# Production / Docker Swarm compose file # Usage: # docker stack deploy -c docker-compose.yml casera # # All env vars must be set in the environment or a .env file. # No dev-safe defaults — missing vars will fail the deploy. services: # PostgreSQL Database db: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data # DB port NOT exposed externally — only reachable within overlay network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 deploy: replicas: 1 restart_policy: condition: any delay: 5s update_config: parallelism: 1 delay: 10s networks: - casera-network # Redis Cache redis: image: redis:7-alpine command: redis-server --appendonly yes volumes: - redis_data:/data # Redis port NOT exposed externally — only reachable within overlay network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 deploy: replicas: 1 restart_policy: condition: any delay: 5s networks: - casera-network # Casera API api: image: ${REGISTRY:-ghcr.io/treytartt}/casera-api:${TAG:-latest} ports: - "${PORT:-8000}:8000" environment: # Server PORT: "8000" DEBUG: "${DEBUG:-false}" ALLOWED_HOSTS: "${ALLOWED_HOSTS}" TIMEZONE: "${TIMEZONE:-UTC}" # Database DB_HOST: db DB_PORT: "5432" POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} DB_SSLMODE: "${DB_SSLMODE:-disable}" # Redis REDIS_URL: "redis://redis:6379/0" # Security SECRET_KEY: ${SECRET_KEY} # Email EMAIL_HOST: ${EMAIL_HOST} EMAIL_PORT: ${EMAIL_PORT:-587} EMAIL_HOST_USER: ${EMAIL_HOST_USER} EMAIL_HOST_PASSWORD: ${EMAIL_HOST_PASSWORD} DEFAULT_FROM_EMAIL: ${DEFAULT_FROM_EMAIL} EMAIL_USE_TLS: "${EMAIL_USE_TLS:-true}" # Push Notifications APNS_AUTH_KEY_PATH: "/certs/apns_key.p8" APNS_AUTH_KEY_ID: ${APNS_AUTH_KEY_ID} APNS_TEAM_ID: ${APNS_TEAM_ID} APNS_TOPIC: ${APNS_TOPIC} APNS_USE_SANDBOX: "${APNS_USE_SANDBOX:-false}" FCM_SERVER_KEY: ${FCM_SERVER_KEY} volumes: - push_certs:/certs:ro - uploads:/app/uploads # TODO: migrate secrets to Docker secrets (docker secret create) healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/api/health/"] interval: 30s timeout: 10s start_period: 15s retries: 3 deploy: replicas: 1 restart_policy: condition: any delay: 5s update_config: parallelism: 1 delay: 10s order: start-first networks: - casera-network # Casera Admin Panel (Next.js) admin: image: ${REGISTRY:-ghcr.io/treytartt}/casera-admin:${TAG:-latest} ports: - "${ADMIN_PORT:-3000}:3000" environment: PORT: "3000" HOSTNAME: "0.0.0.0" NEXT_PUBLIC_API_URL: "${NEXT_PUBLIC_API_URL}" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/admin/"] interval: 30s timeout: 10s retries: 3 deploy: replicas: 1 restart_policy: condition: any delay: 5s update_config: parallelism: 1 delay: 10s order: start-first networks: - casera-network # Casera Worker (Background Jobs) worker: image: ${REGISTRY:-ghcr.io/treytartt}/casera-worker:${TAG:-latest} environment: # Database DB_HOST: db DB_PORT: "5432" POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} DB_SSLMODE: "${DB_SSLMODE:-disable}" # Redis REDIS_URL: "redis://redis:6379/0" # Security SECRET_KEY: ${SECRET_KEY} # Push Notifications APNS_AUTH_KEY_PATH: "/certs/apns_key.p8" APNS_AUTH_KEY_ID: ${APNS_AUTH_KEY_ID} APNS_TEAM_ID: ${APNS_TEAM_ID} APNS_TOPIC: ${APNS_TOPIC} APNS_USE_SANDBOX: "${APNS_USE_SANDBOX:-false}" FCM_SERVER_KEY: ${FCM_SERVER_KEY} # Email EMAIL_HOST: ${EMAIL_HOST} EMAIL_PORT: ${EMAIL_PORT:-587} EMAIL_HOST_USER: ${EMAIL_HOST_USER} EMAIL_HOST_PASSWORD: ${EMAIL_HOST_PASSWORD} DEFAULT_FROM_EMAIL: ${DEFAULT_FROM_EMAIL} EMAIL_USE_TLS: "${EMAIL_USE_TLS:-true}" # Worker settings (UTC hours for scheduled jobs) TASK_REMINDER_HOUR: ${TASK_REMINDER_HOUR:-14} OVERDUE_REMINDER_HOUR: ${OVERDUE_REMINDER_HOUR:-15} DAILY_DIGEST_HOUR: ${DAILY_DIGEST_HOUR:-3} volumes: - push_certs:/certs:ro deploy: replicas: 1 restart_policy: condition: any delay: 5s networks: - casera-network volumes: postgres_data: redis_data: push_certs: uploads: networks: casera-network: driver: overlay