x-default-logging: &default-logging driver: json-file options: max-size: "${LOG_MAX_SIZE:-20m}" max-file: "${LOG_MAX_FILES:-10}" services: postgres: profiles: ["local"] image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: ${LOCAL_POSTGRES_DB:-ltjt_platform} POSTGRES_USER: ${LOCAL_POSTGRES_USER:-ltjt_app} POSTGRES_PASSWORD: ${LOCAL_POSTGRES_PASSWORD:-local-dev-only-change-me} volumes: - ltjt-postgres:/var/lib/postgresql/data logging: *default-logging 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} command: ["sh", "-c", "node .build/control-plane/src/migrate.js && node .build/control-plane/src/server.js"] logging: *default-logging 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 logging: *default-logging volumes: ltjt-postgres: caddy-data: caddy-config: