Updated the documentation for the Website service target to name/reference PostgreSQL instead.
This commit is contained in:
+17
-17
@@ -10,7 +10,7 @@ The service:
|
||||
- Returns a custom not-found (404) HTML page, localized like the landing 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.
|
||||
- Persists data through [Fluent](https://github.com/hummingbird-project/hummingbird-fluent), against either an ephemeral in-memory SQLite database (the default — no external infrastructure) or a MySQL/MariaDB server, selected by a single configuration key.
|
||||
- Persists data through [Fluent](https://github.com/hummingbird-project/hummingbird-fluent), against either an ephemeral in-memory SQLite database (the default — no external infrastructure) or a PostgreSQL server, selected by a single configuration key.
|
||||
|
||||
## Requirements
|
||||
- Swift 6.3 toolchain (`swift-tools-version:6.3`).
|
||||
@@ -55,7 +55,7 @@ the following sources, **highest precedence first**:
|
||||
5. Built-in defaults
|
||||
|
||||
The two files play different roles:
|
||||
- **`.env`** (git-ignored) holds your deployment values — it is the file the Makefile and Compose read for the `${VAR}` placeholders, and typically selects the MySQL/MariaDB backend.
|
||||
- **`.env`** (git-ignored) holds your deployment values — it is the file the Makefile and Compose read for the `${VAR}` placeholders, and typically selects the PostgreSQL backend.
|
||||
- **`.env.local`** (tracked) holds the local development values — the in-memory database and `debug` logging, plus the image/deployment placeholders the Makefile falls back to when no `.env` exists. Because it sits *above* `.env`, a direct launch (`swift run` or a debugger) runs against the local values even when `.env` points at a deployment, the same way `docker-compose.override.yml` overrides the base Compose file. Compose itself never reads it, and the production image does not ship it — only the executable, its resources, and the static files are staged into the final stage.
|
||||
|
||||
### Environment variable naming
|
||||
@@ -92,10 +92,10 @@ A dotted config key maps to an environment variable by upper-casing, splitting c
|
||||
### Persistence
|
||||
| Config key | Environment variable | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `database.driver` | `DATABASE_DRIVER` | `inMemory` | Backend: `inMemory` (ephemeral SQLite, no infrastructure) or `mysql` (MySQL/MariaDB). |
|
||||
| `database.driver` | `DATABASE_DRIVER` | `inMemory` | Backend: `inMemory` (ephemeral SQLite, no infrastructure) or `postgres` (PostgreSQL). |
|
||||
| `database.migrate` | `DATABASE_MIGRATE` (flag `--database-migrate`) | `false` | When set, run the migrations and exit instead of serving. |
|
||||
| `database.host` | `DATABASE_HOST` | `localhost` | MySQL/MariaDB host. Ignored for `inMemory`. |
|
||||
| `database.port` | `DATABASE_PORT` | `3306` | MySQL/MariaDB port. Ignored for `inMemory`. |
|
||||
| `database.host` | `DATABASE_HOST` | `localhost` | PostgreSQL host. Ignored for `inMemory`. |
|
||||
| `database.port` | `DATABASE_PORT` | `5432` | PostgreSQL port. Ignored for `inMemory`. |
|
||||
| `database.name` | `DATABASE_NAME` | `loud` | Database name. Ignored for `inMemory`. |
|
||||
| `database.username` | `DATABASE_USERNAME` | `loud` | Database username. Ignored for `inMemory`. |
|
||||
| `database.password` | `DATABASE_PASSWORD` | _(empty)_ | Database password. Provide via the environment/a secret — never commit it. |
|
||||
@@ -136,7 +136,7 @@ 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
|
||||
```
|
||||
|
||||
A direct run picks up the local development overrides from `.env.local` (in-memory database, `debug` logging) over whatever `.env` configures. To run against another backend, override per launch — e.g. `DATABASE_DRIVER=mysql swift run Website` — since process environment variables outrank both files.
|
||||
A direct run picks up the local development overrides from `.env.local` (in-memory database, `debug` logging) over whatever `.env` configures. To run against another backend, override per launch — e.g. `DATABASE_DRIVER=postgres swift run Website` — since process environment variables outrank both files.
|
||||
|
||||
Or via the Makefile / Docker (uses `docker-compose.override.yml`, which builds from source and sets `LOG_LEVEL=debug`):
|
||||
```sh
|
||||
@@ -154,8 +154,8 @@ The service persists data through Fluent and selects its backend at runtime with
|
||||
### In-memory (default)
|
||||
With no configuration, the service uses an ephemeral in-memory SQLite database. It is created and **migrated on startup** every launch, so `swift run Website` and `docker compose up` work with no external database — ideal for local development and tests.
|
||||
|
||||
### MySQL / MariaDB
|
||||
Set `DATABASE_DRIVER=mysql` and the connection values (`DATABASE_HOST`, `DATABASE_NAME`, `DATABASE_USERNAME`, `DATABASE_PASSWORD`, …). Unlike the in-memory backend, a MySQL/MariaDB database is **not** migrated on boot — a shared database is migrated out of band so multiple instances never race:
|
||||
### PostgreSQL
|
||||
Set `DATABASE_DRIVER=postgres` and the connection values (`DATABASE_HOST`, `DATABASE_NAME`, `DATABASE_USERNAME`, `DATABASE_PASSWORD`, …). Unlike the in-memory backend, a PostgreSQL database is **not** migrated on boot — a shared database is migrated out of band so multiple instances never race:
|
||||
```sh
|
||||
# Run the registered migrations against the configured database, then exit.
|
||||
swift run Website --database-migrate
|
||||
@@ -163,14 +163,14 @@ swift run Website --database-migrate
|
||||
docker compose -f docker-compose.yml run --rm website --database-migrate
|
||||
```
|
||||
|
||||
A local MariaDB for development lives behind the `database` Compose profile (so a plain `docker compose up` still runs in-memory). Its data directory is bind-mounted to `Tests/DB` (git-ignored), so the database survives `db-unmount` and container restarts:
|
||||
A local PostgreSQL for development lives behind the `database` Compose profile (so a plain `docker compose up` still runs in-memory). Its data directory is bind-mounted to `Tests/DB` (git-ignored), so the database survives `db-unmount` and container restarts:
|
||||
```sh
|
||||
make db-mount # start MariaDB (docker compose --profile database up --wait mariadb)
|
||||
make db-mount # start PostgreSQL (docker compose --profile database up --wait postgres)
|
||||
make db-migrate # run migrations against it
|
||||
make db-shell # open a SQL shell on it
|
||||
make db-shell # open a SQL shell on it (psql)
|
||||
make db-unmount # stop and remove the container (data kept in Tests/DB)
|
||||
make db-reset # stop and remove the container
|
||||
DATABASE_DRIVER=mysql make site-mount # run the site against MariaDB
|
||||
DATABASE_DRIVER=postgres make site-mount # run the site against PostgreSQL
|
||||
```
|
||||
> **Note:** because the data lives in the bind-mounted `Tests/DB` folder rather than a named volume, `db-reset`'s `--volumes` flag does **not** clear it. To start from an empty database, delete `Tests/DB` by hand.
|
||||
|
||||
@@ -187,11 +187,11 @@ make pkg-test
|
||||
|
||||
Tests use the [Swift Testing](https://developer.apple.com/documentation/testing/) framework. The `Tests/Website.xctestplan` covers the service's two targets — `WebsiteTests` (the executable/integration tests) and `WebsiteLibraryTests` (the library unit tests) — plus the local packages' suites: `InfrastructureTests`, `PersistenceTests`, `LocalizationTests`, and `UtilityTests`.
|
||||
|
||||
The `Persistence` package has its own suite (run it from `Packages/Persistence`). Its tests run against the in-memory backend by default; the MySQL integration test is skipped unless a database is pointed at via `MYSQL_TEST_HOST` (with optional `MYSQL_TEST_PORT`/`NAME`/`USERNAME`/`PASSWORD`), so `swift test` stays runnable with no database:
|
||||
The `Persistence` package has its own suite (run it from `Packages/Persistence`). Its tests run against the in-memory backend by default; the PostgreSQL integration test is skipped unless a database is pointed at via `POSTGRES_TEST_HOST` (with optional `POSTGRES_TEST_PORT`/`NAME`/`USERNAME`/`PASSWORD`), so `swift test` stays runnable with no database:
|
||||
```sh
|
||||
cd ../../Packages/Persistence && swift test # in-memory only
|
||||
# With the local MariaDB up (make db-mount):
|
||||
cd ../../Packages/Persistence && MYSQL_TEST_HOST=127.0.0.1 swift test
|
||||
# With the local PostgreSQL up (make db-mount):
|
||||
cd ../../Packages/Persistence && POSTGRES_TEST_HOST=127.0.0.1 swift test
|
||||
```
|
||||
|
||||
## Deployment
|
||||
@@ -262,8 +262,8 @@ The Makefile and Compose files read these from a `.env` file (or the environment
|
||||
| `LOG_LEVEL` | Runtime log level (default `info`). |
|
||||
| `HTTP_SERVER_NAME` | Runtime server name (default `LoudWebsite`). |
|
||||
| `SECURITY_STRICT_TRANSPORT_SECURITY` | HSTS header value (default `max-age=31536000; includeSubDomains`). |
|
||||
| `DATABASE_DRIVER` | `inMemory` or `mysql`. The production Compose file defaults it to `mysql`; the local override defaults back to the in-memory backend. |
|
||||
| `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_NAME`, `DATABASE_USERNAME`, `DATABASE_PASSWORD` | MySQL/MariaDB connection (when `DATABASE_DRIVER=mysql`). Provide the password via a secret. |
|
||||
| `DATABASE_DRIVER` | `inMemory` or `postgres`. The production Compose file defaults it to `postgres`; the local override defaults back to the in-memory backend. |
|
||||
| `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_NAME`, `DATABASE_USERNAME`, `DATABASE_PASSWORD` | PostgreSQL connection (when `DATABASE_DRIVER=postgres`). Provide the password via a secret. |
|
||||
| `DATABASE_TLS` | TLS posture when connecting: `off`, `prefer`, or `require` (default `prefer` in production — set `require` when the database enforces TLS, so a stripped connection fails instead of silently downgrading to plaintext). |
|
||||
|
||||
Run the migrations against the production database once before (or during) rollout: `docker compose -f docker-compose.yml run --rm website --database-migrate`.
|
||||
|
||||
Reference in New Issue
Block a user