forked from ungleich-public/ungleich-user
PostgreSQL with a persistent volume, a one-off migrate service running migrate_locked, and the web app, which starts only after migrations succeeded. The app runs with a read-only filesystem, no capabilities and a health check. Configuration comes from .env (or ENV_FILE). Checked end to end: database healthy, migrations applied, both probes OK, login works.
61 lines
1.6 KiB
YAML
61 lines
1.6 KiB
YAML
# Production-style deployment with Docker Compose: PostgreSQL, a one-off
|
|
# migration step, and the web app. Configuration comes from .env
|
|
# (copy .env.example). See docker.md.
|
|
#
|
|
# cp .env.example .env # then fill in the required values
|
|
# docker compose up -d --build
|
|
#
|
|
# For local development use docker-compose.dev.yml instead.
|
|
|
|
x-app: &app
|
|
build: .
|
|
image: ungleich-user:latest
|
|
env_file: ${ENV_FILE:-.env}
|
|
environment:
|
|
DATABASE_HOST: db
|
|
read_only: true
|
|
tmpfs:
|
|
- /tmp
|
|
cap_drop: [ALL]
|
|
security_opt: ["no-new-privileges:true"]
|
|
|
|
services:
|
|
db:
|
|
image: postgres:18-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: ${DATABASE_NAME:-ungleich_user}
|
|
POSTGRES_USER: ${DATABASE_USER:-ungleich_user}
|
|
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:?set DATABASE_PASSWORD in .env}
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER}"]
|
|
interval: 3s
|
|
retries: 20
|
|
|
|
# Runs once per `up` and exits; web starts only if it succeeded.
|
|
migrate:
|
|
<<: *app
|
|
command: ["python", "manage.py", "migrate_locked"]
|
|
restart: "no"
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
|
|
web:
|
|
<<: *app
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${PORT:-8000}:8000"
|
|
depends_on:
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
healthcheck:
|
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/healthz', timeout=3)"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
volumes:
|
|
pgdata:
|