133 lines
3.5 KiB
YAML
133 lines
3.5 KiB
YAML
# =============================================================================
|
|
# ©AngelaMos | 2026
|
|
# compose.yml
|
|
# =============================================================================
|
|
# Production compose: nginx → canary backend → postgres + redis
|
|
# Cloudflare tunnel overlay:
|
|
# docker compose -f compose.yml -f cloudflared.compose.yml up -d
|
|
# =============================================================================
|
|
|
|
name: ${APP_NAME:-canary-token-generator}
|
|
|
|
services:
|
|
nginx:
|
|
build:
|
|
context: .
|
|
dockerfile: infra/docker/vite.prod
|
|
args:
|
|
- VITE_API_URL=${VITE_API_URL:-/api}
|
|
- VITE_APP_TITLE=${VITE_APP_TITLE:-Canary Token Generator}
|
|
- VITE_TURNSTILE_SITE_KEY=${VITE_TURNSTILE_SITE_KEY:-}
|
|
container_name: ${APP_NAME:-canary-token-generator}-nginx
|
|
ports:
|
|
- "${NGINX_HOST_PORT:-22784}:80"
|
|
networks:
|
|
- app
|
|
depends_on:
|
|
canary:
|
|
condition: service_healthy
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1.0'
|
|
memory: 256M
|
|
reservations:
|
|
cpus: '0.25'
|
|
memory: 64M
|
|
restart: unless-stopped
|
|
|
|
canary:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: ../infra/docker/canary.prod
|
|
container_name: ${APP_NAME:-canary-token-generator}-canary
|
|
environment:
|
|
- APP_ENVIRONMENT=production
|
|
- DATABASE_URL=postgres://canary:${POSTGRES_PASSWORD}@postgres:5432/canary?sslmode=disable
|
|
- REDIS_URL=redis://redis:6379/0
|
|
- PUBLIC_BASE_URL=${PUBLIC_BASE_URL}
|
|
- TURNSTILE_SECRET=${TURNSTILE_SECRET}
|
|
- OPERATOR_TOKEN=${OPERATOR_TOKEN}
|
|
- GEOLITE_PATH=/data/GeoLite2-City.mmdb
|
|
- WEBHOOK_HMAC_SECRET=${WEBHOOK_HMAC_SECRET:-}
|
|
- MYSQL_FAKE_ENABLED=${MYSQL_FAKE_ENABLED:-false}
|
|
- TRUSTED_PROXY_CIDRS=${TRUSTED_PROXY_CIDRS:-}
|
|
- LOG_LEVEL=${LOG_LEVEL:-info}
|
|
- LOG_FORMAT=${LOG_FORMAT:-json}
|
|
- OTEL_ENABLED=${OTEL_ENABLED:-false}
|
|
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-}
|
|
volumes:
|
|
- geolite:/data:ro
|
|
networks:
|
|
- app
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "/healthcheck"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 15s
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1.0'
|
|
memory: 256M
|
|
reservations:
|
|
cpus: '0.25'
|
|
memory: 64M
|
|
restart: unless-stopped
|
|
|
|
postgres:
|
|
image: postgres:18-alpine
|
|
container_name: ${APP_NAME:-canary-token-generator}-postgres
|
|
environment:
|
|
POSTGRES_USER: canary
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: canary
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
networks:
|
|
- app
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U canary -d canary"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: ${APP_NAME:-canary-token-generator}-redis
|
|
command: redis-server --appendonly yes
|
|
volumes:
|
|
- redisdata:/data
|
|
networks:
|
|
- app
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 128M
|
|
restart: unless-stopped
|
|
|
|
networks:
|
|
app:
|
|
driver: bridge
|
|
|
|
volumes:
|
|
pgdata:
|
|
redisdata:
|
|
geolite:
|