feat(deploy): add Docker Compose and Traefik edge stack
Provide shared, development, and production compose overlays with Traefik routing.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# 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
|
||||
- --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:
|
||||
Reference in New Issue
Block a user