Mount the named `db-data` volume at PostgreSQL's data directory (/var/lib/postgresql/data) on the db service and declare it in the top-level volumes map, so the database survives `docker compose restart` and `docker compose down` + `up -d` (recreate). Reset with `docker compose down -v` per the issue rollback note. Header comments in compose.yaml and the server Dockerfile updated: T04 is no longer out of scope; T05/T06 remain.
72 lines
3.0 KiB
YAML
72 lines
3.0 KiB
YAML
# EPPP Docker Compose baseline — [E00-S02-T01/T02/T03/T04]
|
|
#
|
|
# `docker compose up -d` starts both the database (PostgreSQL) and the
|
|
# application (@personal-blog/server). Rollback: `docker compose down`.
|
|
#
|
|
# PostgreSQL health gate (T02): the `db` service carries a `pg_isready`
|
|
# healthcheck and the `app` service depends on it with
|
|
# `condition: service_healthy`, so the application does not start until the
|
|
# database is accepting connections.
|
|
#
|
|
# Application health endpoint (T03): the app serves `GET /health` (HTTP 200 +
|
|
# `{"status":"ok"}`) on port 3000, so the app container stays up and the
|
|
# health endpoint succeeds once the stack is running.
|
|
#
|
|
# Database volume persistence (T04): the `db` service mounts the named volume
|
|
# `db-data` at PostgreSQL's data directory (`/var/lib/postgresql/data`), so
|
|
# the database survives `docker compose restart` (restart) and
|
|
# `docker compose down` + `docker compose up -d` (recreate, which discards the
|
|
# container filesystem). Reset the data with `docker compose down -v`.
|
|
#
|
|
# Explicitly out of scope for T01..T04 (land in later E00-S02 tasks):
|
|
# - non-root execution (T05), read-only root filesystem (T06)
|
|
#
|
|
# All values have defaults so `docker compose up -d` works from a clean clone
|
|
# without a .env file (a committed .env.example template lands in E00-S04).
|
|
|
|
services:
|
|
db:
|
|
# PostgreSQL 18 on Debian bookworm — the documented runtime target
|
|
# (Technology-Stack §5.2/§5.4/§6.2, golden tuple §7; no Alpine drift).
|
|
image: postgres:18-bookworm
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB:-eppp}
|
|
POSTGRES_USER: ${POSTGRES_USER:-eppp}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-eppp}
|
|
ports:
|
|
- "${POSTGRES_PORT:-5432}:5432"
|
|
# T04: persist the database in the named `db-data` volume (PostgreSQL data
|
|
# directory), so data survives `docker compose restart` and `docker
|
|
# compose down` + `up -d` (recreate). `docker compose down -v` resets it.
|
|
volumes:
|
|
- db-data:/var/lib/postgresql/data
|
|
# Health gate for the app service (T02): probe the same credentials the db
|
|
# service was created with. `$$` defers interpolation to the container, so
|
|
# POSTGRES_USER/POSTGRES_DB overrides apply to the probe too.
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 5s
|
|
|
|
app:
|
|
build:
|
|
context: .
|
|
dockerfile: apps/server/Dockerfile
|
|
environment:
|
|
DATABASE_URL: postgres://eppp:eppp@db:5432/eppp
|
|
ports:
|
|
- "${APP_PORT:-3000}:3000"
|
|
# T02: start only once the database reports healthy (service_healthy), so
|
|
# the application waits for PostgreSQL before starting.
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
|
|
# Named volumes shared across `docker compose` lifecycles. `db-data` (T04)
|
|
# holds the PostgreSQL data directory and is preserved across restart and
|
|
# recreate; `docker compose down -v` removes it to reset the database.
|
|
volumes:
|
|
db-data:
|