Files
Classeo/compose.prod.yaml
Mathias STRASSER 9c26628561
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat(deploy): add vps deployment assets
2026-03-10 18:58:02 +01:00

160 lines
5.1 KiB
YAML

services:
caddy:
image: caddy:2.10-alpine
container_name: classeo_caddy
environment:
APP_DOMAIN: ${APP_DOMAIN}
ports:
- "80:80"
- "443:443"
volumes:
- ./deploy/vps/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- php
- frontend
restart: unless-stopped
php:
build:
context: ./backend
dockerfile: Dockerfile
target: prod
container_name: classeo_php
environment:
APP_ENV: prod
APP_SECRET: ${APP_SECRET}
TRUSTED_PROXIES: ${TRUSTED_PROXIES}
TRUSTED_HOSTS: ${TRUSTED_HOSTS}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${MASTER_DATABASE_NAME}?serverVersion=18&charset=utf8
REDIS_URL: redis://redis:6379
MESSENGER_TRANSPORT_DSN: doctrine://default?queue_name=async
MAILER_DSN: ${MAILER_DSN}
ADMIN_ALERT_EMAIL: ${ADMIN_ALERT_EMAIL}
DEFAULT_URI: https://${APP_DOMAIN}
TENANT_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
APP_URL: https://${APP_DOMAIN}
CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN}
TURNSTILE_SECRET_KEY: ${TURNSTILE_SECRET_KEY}
TURNSTILE_FAIL_OPEN: ${TURNSTILE_FAIL_OPEN}
JWT_SECRET_KEY: /app/config/jwt/private.pem
JWT_PUBLIC_KEY: /app/config/jwt/public.pem
JWT_PASSPHRASE: ${JWT_PASSPHRASE}
LOCK_DSN: redis://redis:6379
SENTRY_DSN: ${SENTRY_DSN}
SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
TENANT_CONFIGS: >-
[{"tenantId":"${TENANT_ID}","subdomain":"${TENANT_SUBDOMAIN}","databaseUrl":"postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${TENANT_DATABASE_NAME}?serverVersion=18&charset=utf8"}]
volumes:
- backend_uploads:/app/public/uploads
- ./backend/config/jwt:/app/config/jwt
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: prod
container_name: classeo_frontend
environment:
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
ORIGIN: https://${APP_DOMAIN}
PUBLIC_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
PUBLIC_TURNSTILE_SITE_KEY: ${PUBLIC_TURNSTILE_SITE_KEY}
depends_on:
- php
restart: unless-stopped
worker:
build:
context: ./backend
dockerfile: Dockerfile
target: prod
container_name: classeo_worker
command:
- sh
- -lc
- until [ -f /app/config/jwt/private.pem ]; do sleep 1; done; php bin/console messenger:consume async --time-limit=3600 --memory-limit=128M -vv
environment:
APP_ENV: prod
APP_SECRET: ${APP_SECRET}
TRUSTED_PROXIES: ${TRUSTED_PROXIES}
TRUSTED_HOSTS: ${TRUSTED_HOSTS}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${MASTER_DATABASE_NAME}?serverVersion=18&charset=utf8
REDIS_URL: redis://redis:6379
MESSENGER_TRANSPORT_DSN: doctrine://default?queue_name=async
MAILER_DSN: ${MAILER_DSN}
ADMIN_ALERT_EMAIL: ${ADMIN_ALERT_EMAIL}
DEFAULT_URI: https://${APP_DOMAIN}
TENANT_BASE_DOMAIN: ${PUBLIC_BASE_DOMAIN}
APP_URL: https://${APP_DOMAIN}
CORS_ALLOW_ORIGIN: ${CORS_ALLOW_ORIGIN}
TURNSTILE_SECRET_KEY: ${TURNSTILE_SECRET_KEY}
TURNSTILE_FAIL_OPEN: ${TURNSTILE_FAIL_OPEN}
JWT_SECRET_KEY: /app/config/jwt/private.pem
JWT_PUBLIC_KEY: /app/config/jwt/public.pem
JWT_PASSPHRASE: ${JWT_PASSPHRASE}
LOCK_DSN: redis://redis:6379
SENTRY_DSN: ${SENTRY_DSN}
SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
TENANT_CONFIGS: >-
[{"tenantId":"${TENANT_ID}","subdomain":"${TENANT_SUBDOMAIN}","databaseUrl":"postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${TENANT_DATABASE_NAME}?serverVersion=18&charset=utf8"}]
volumes:
- ./backend/config/jwt:/app/config/jwt
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
php:
condition: service_started
restart: unless-stopped
db:
image: postgres:18.1-alpine
container_name: classeo_db
environment:
POSTGRES_DB: ${MASTER_DATABASE_NAME}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
TENANT_DATABASE_NAME: ${TENANT_DATABASE_NAME}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./deploy/vps/postgres/01-create-tenant-db.sh:/docker-entrypoint-initdb.d/01-create-tenant-db.sh:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${MASTER_DATABASE_NAME}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
restart: unless-stopped
redis:
image: redis:7.4-alpine
container_name: classeo_redis
command: redis-server --save "" --appendonly no --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 10
start_period: 5s
restart: unless-stopped
volumes:
backend_uploads:
caddy_config:
caddy_data:
postgres_data:
redis_data: