The **Loud** public website service — a [Hummingbird](https://github.com/hummingbird-project/hummingbird) server that renders a static landing page and serves the site's static assets.
## Overview
The service:
- Serves the landing page at `GET /` (rendered once with [Elementary](https://github.com/elementary-swift/elementary) and cached).
- Serves static files (CSS, JS, icons, manifest, `robots.txt`) from `Resources/Static` via Hummingbird's `FileMiddleware`, tagged with media-type-specific `Cache-Control`.
- Returns a custom HTML 404 page for any request that matches neither a route nor a static file.
- Compresses responses (gzip/deflate) above a configurable size when the client advertises support.
- Stamps a hardened set of security headers on every response.
## Requirements
- Swift 6.3 toolchain (`swift-tools-version:6.3`).
- Docker (optional) for the containerized run/deploy workflow.
## Architecture
Two SwiftPM targets:
| Target | Kind | Path | Role |
| --- | --- | --- | --- |
| `Website` | executable | `Sources/App` | Entry point: reads configuration, builds and runs the application. |
3. A `.env` file in the working directory (optional)
4. Built-in defaults
### Environment variable naming
A dotted config key maps to an environment variable by upper-casing, splitting camelCase, and replacing separators with `_`. For example `http.serverName` → `HTTP_SERVER_NAME`,
| `compression.minimumResponseSize` | `COMPRESSION_MINIMUM_RESPONSE_SIZE` | `1024` | Minimum response body size, in bytes, before compression is applied. |
`Strict-Transport-Security` has **no default** and is omitted unless explicitly configured: it only takes effect over HTTPS (browsers ignore it on plain HTTP) and is "sticky" in browsers, so it must stay off in local HTTP development. It is enabled for production in `docker-compose.yml`, where it only has an effect once traffic is served over HTTPS behind a TLS-terminating proxy.
## Running locally
Directly with Swift:
```sh
swift run Website # binds to Hummingbird's default 127.0.0.1:8080
swift run Website --http-host 0.0.0.0 --http-port 9000 --log-level debug
```
Or via the Makefile / Docker (uses `docker-compose.override.yml`, which builds from source and sets`LOG_LEVEL=debug`:
```sh
make pkg-build # swift build
make img-mount # docker compose up --build --detach
make img-unmount # docker compose down + remove the local image
```
`make help` lists every available target.
## Testing
```sh
make pkg-test
# = swift test --disable-xctest --enable-code-coverage --enable-swift-testing --parallel
```
Tests use the [Swift Testing](https://developer.apple.com/documentation/testing/) framework. The`Website.xctestplan` covers two targets: `WebsiteTests` (the executable/integration tests) and` WebsiteCoreTests` (the library unit tests).
## Deployment
The production image is built for `linux/amd64` in release mode with a statically linked Swift runtime and jemalloc, runs as a non-root `hummingbird` user, and exposes port `8080`(`ENTRYPOINT ./Website --http-host 0.0.0.0 --http-port 8080`).
Build, tag, and push a release to the registry (an explicit version is required):
```sh
make img-release version=1.2.3
```
Pull and run the prebuilt image in production — the `-f docker-compose.yml` flag is important, as it skips the local-development override:
```sh
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up -d
```
### Required variables
The Makefile and Compose files read these from a `.env` file (or the environment). Provide your own values — do **not** commit secrets.