docker-compose.prod.yml
version: '3.8'
# --- Base config -------------------------------------------------------------
x-default-opts:
&default-opts
logging:
options:
max-size: '1m'
max-file: '3'
# --- Base Django config ------------------------------------------------------
x-django-config:
&django-config
image: ghcr.io/uccser/cs-field-guide:${CS_FIELD_GUIDE_IMAGE_TAG}
environment:
POSTGRES_HOST: postgres
POSTGRES_PORT: "5432"
DEPLOYMENT_ENVIRONMENT_FILE: /cs-field-guide_deployment_environment
DJANGO_SECRET_KEY_FILE: /run/secrets/cs-field-guide_django_secret_key
POSTGRES_DB_FILE: /run/secrets/cs-field-guide_postgres_db
POSTGRES_USER_FILE: /run/secrets/cs-field-guide_postgres_user
POSTGRES_PASSWORD_FILE: /run/secrets/cs-field-guide_postgres_password
configs:
- cs-field-guide_deployment_environment
secrets:
- cs-field-guide_django_secret_key
- cs-field-guide_postgres_db
- cs-field-guide_postgres_user
- cs-field-guide_postgres_password
# -----------------------------------------------------------------------------
services:
django:
<<: *default-opts
<<: *django-config
deploy:
replicas: 2
placement:
constraints:
- node.role==worker
- node.labels.role==apps
restart_policy:
condition: on-failure
labels:
- "traefik.enable=true"
- "traefik.docker.network=uccser-public"
- "traefik.http.services.cs-field-guide-django.loadbalancer.server.port=8000"
- "traefik.http.routers.cs-field-guide-django.service=cs-field-guide-django"
- "traefik.http.routers.cs-field-guide-django.rule=${CS_FIELD_GUIDE_ROUTER_RULE}"
- "traefik.http.routers.cs-field-guide-django.entryPoints=web"
# Redirect non-www to www, only triggers in production swarm.
- "traefik.http.middlewares.cs-field-guide-redirect-non-www.redirectregex.regex=^https://csfieldguide\\.org(.*)"
- "traefik.http.middlewares.cs-field-guide-redirect-non-www.redirectregex.replacement=https://www.csfieldguide.org$${1}"
- "traefik.http.middlewares.cs-field-guide-redirect-non-www.redirectregex.permanent=true"
networks:
- uccser-public
- backend
task-update-data:
<<: *default-opts
<<: *django-config
command: python ./manage.py update_data
deploy:
replicas: 0
placement:
constraints:
- node.role==worker
- node.labels.role==apps
restart_policy:
condition: none
healthcheck:
disable: true
networks:
- backend
postgres:
<<: *default-opts
image: postgres:13.8
# TODO: Write test script that reads secret files
# to get correct username
# healthcheck:
# test: ["CMD-SHELL", "pg_isready -U postgres"]
# start_period: 10s
# interval: 10s
# timeout: 5s
# retries: 3
deploy:
replicas: 1
placement:
constraints:
- node.role==worker
- node.labels.role==data
restart_policy:
condition: on-failure
environment:
POSTGRES_DB_FILE: /run/secrets/cs-field-guide_postgres_db
POSTGRES_USER_FILE: /run/secrets/cs-field-guide_postgres_user
POSTGRES_PASSWORD_FILE: /run/secrets/cs-field-guide_postgres_password
secrets:
- cs-field-guide_postgres_db
- cs-field-guide_postgres_user
- cs-field-guide_postgres_password
networks:
- backend
volumes:
- postgres-data:/var/lib/postgresql/data:Z
- postgres-data-backups:/backups:z
configs:
cs-field-guide_deployment_environment:
external: true
secrets:
cs-field-guide_django_secret_key:
external: true
cs-field-guide_postgres_db:
external: true
cs-field-guide_postgres_user:
external: true
cs-field-guide_postgres_password:
external: true
networks:
uccser-public:
external: true
backend:
driver: overlay
attachable: true
volumes:
postgres-data: {}
postgres-data-backups: {}