services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-ltjt_platform} POSTGRES_USER: ${POSTGRES_USER:-ltjt_app} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in the deployment secret file} volumes: - ltjt-postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 12 control-plane: build: . restart: unless-stopped env_file: - .env.production environment: DATABASE_URL: ${DATABASE_URL:?set DATABASE_URL in .env.production} depends_on: postgres: condition: service_healthy command: ["sh", "-c", "node dist/control-plane/src/migrate.js && node dist/control-plane/src/server.js"] healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8786/health/ready').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] interval: 15s timeout: 5s retries: 6 caddy: image: caddy:2-alpine restart: unless-stopped depends_on: control-plane: condition: service_healthy environment: APP_DOMAIN: ${APP_DOMAIN:-localhost} ports: - "80:80" - "443:443" volumes: - ./infra/Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data - caddy-config:/config volumes: ltjt-postgres: caddy-data: caddy-config: