Files
pargar/deploy/compose/compose.prod.yaml
T

116 lines
3.4 KiB
YAML
Raw Normal View History

# Internet-facing production overlay (Traefik + Let's Encrypt, no host DB ports).
# Usage:
# docker compose -f deploy/compose/compose.yaml -f deploy/compose/compose.prod.yaml \
# --env-file .env.prod up -d --build
#
# Requires: DOMAIN (public DNS), ACME_EMAIL, PUBLIC_URL=https://$DOMAIN, strong secrets.
services:
postgres:
# No host ports — only reachable on the compose network.
deploy:
resources:
limits:
memory: 1G
redis:
deploy:
resources:
limits:
memory: 512M
rustfs:
environment:
RUSTFS_CONSOLE_ENABLE: "false"
deploy:
resources:
limits:
memory: 1G
backend:
environment:
DEV_MODE: "false"
SEED_CURRICULUM: "false"
labels:
- traefik.http.routers.pargar-api.tls.certresolver=le
- traefik.http.routers.pargar-cert-api.tls.certresolver=le
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 256M
frontend:
labels:
- traefik.http.routers.pargar-web.tls.certresolver=le
- traefik.http.routers.pargar-cert-web.tls.certresolver=le
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 256M
traefik:
# v3.6.1+ required for Docker Engine 29+ API negotiation
image: traefik@sha256:24841fe2de7304c149343d877d2923b4c8800a38ba015dea9174c23b20e344a0
restart: unless-stopped
security_opt:
- no-new-privileges:true
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=pargar_pargar
- --providers.file.directory=/etc/traefik/dynamic
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.web.http.aliasHeadersStrategy=delete
- --entrypoints.websecure.http.aliasHeadersStrategy=delete
# Allow slow, large uploads (admin video ≤ 200MB); default is 60s.
- --entrypoints.web.transport.respondingTimeouts.readTimeout=3600
- --entrypoints.websecure.transport.respondingTimeouts.readTimeout=3600
- --certificatesresolvers.le.acme.email=${ACME_EMAIL:?ACME_EMAIL must be set}
- --certificatesresolvers.le.acme.storage=/data/acme.json
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
- --api.dashboard=false
- --log.level=WARN
- --accesslog=true
- --ping=true
- --global.checkNewVersion=false
- --serversTransport.forwardingTimeouts.dialTimeout=10s
- --serversTransport.forwardingTimeouts.responseHeaderTimeout=60s
ports:
- "80:80"
- "[::]:80:80"
- "443:443"
- "[::]:443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ../traefik/dynamic:/etc/traefik/dynamic:ro
- traefik_data:/data
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_healthy
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
interval: 10s
timeout: 3s
retries: 10
deploy:
resources:
limits:
memory: 256M
networks:
- pargar
volumes:
traefik_data: