services: frontend-builder: image: node:20-alpine profiles: - build working_dir: /workspace volumes: - ../../frontend:/workspace - frontend_node_modules:/workspace/node_modules command: sh -c "npm ci && npm run build" frontend: build: context: ../.. dockerfile: docker/app/Dockerfile.frontend image: yg-ft-frontend-runtime:latest container_name: yg-ft-frontend depends_on: backend-api: condition: service_started ports: - "6801:80" environment: API_PROXY_PASS: ${API_PROXY_PASS:-http://backend-api:8000} volumes: - ../../frontend/dist:/usr/share/nginx/html:ro - ../nginx.conf.template:/etc/nginx/templates/default.conf.template:ro networks: - yg-ft-app restart: unless-stopped backend-api: build: context: ../.. dockerfile: docker/app/Dockerfile.backend image: yg-ft-backend-api:latest container_name: yg-ft-backend-api depends_on: postgres: condition: service_healthy redis: condition: service_healthy expose: - "8000" environment: APP_ENV: ${APP_ENV:-prod} APP_NAME: ${APP_NAME:-YG Fine-Tune Platform API} API_PREFIX: ${API_PREFIX:-/api} DATABASE_URL: ${DATABASE_URL:-postgresql+asyncpg://yg_ft:change_me@postgres:5432/yg_ft} REDIS_URL: ${REDIS_URL:-redis://redis:6379/0} USE_BUILTIN_POSTGRES: ${USE_BUILTIN_POSTGRES:-true} USE_BUILTIN_REDIS: ${USE_BUILTIN_REDIS:-true} LOG_LEVEL: ${LOG_LEVEL:-INFO} LOG_DIR: ${LOG_DIR:-/opt/yg-ft/logs/backend} LOG_FILE_PREFIX: ${LOG_FILE_PREFIX:-backend} LOG_ERROR_FILE_PREFIX: ${LOG_ERROR_FILE_PREFIX:-error} LOG_MAX_BYTES: ${LOG_MAX_BYTES:-20971520} LOG_RETENTION_DAYS: ${LOG_RETENTION_DAYS:-10} COMPUTE_API_BASE_URL: ${COMPUTE_API_BASE_URL:-http://compute-api:9100} COMPUTE_SERVICE_TOKEN: ${COMPUTE_SERVICE_TOKEN:-change_me} FILE_GATEWAY_BASE_URL: ${FILE_GATEWAY_BASE_URL:-http://compute-api:9101} COMPUTE_STATUS_SYNC_MODE: ${COMPUTE_STATUS_SYNC_MODE:-polling} COMPUTE_POLL_INTERVAL_SECONDS: ${COMPUTE_POLL_INTERVAL_SECONDS:-10} COMPUTE_POLL_BATCH_SIZE: ${COMPUTE_POLL_BATCH_SIZE:-100} PYTHONPATH: /app volumes: - ../../backend:/app:ro - ../../runtime/app/logs/backend:/opt/yg-ft/logs/backend - ../../runtime/app/data:/data/yg-ft networks: - yg-ft-app healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/v1/health', timeout=3).read()\""] interval: 30s timeout: 5s retries: 3 start_period: 20s restart: unless-stopped postgres: image: postgres:16-alpine container_name: yg-ft-postgres environment: POSTGRES_DB: ${POSTGRES_DB:-yg_ft} POSTGRES_USER: ${POSTGRES_USER:-yg_ft} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me} PGDATA: /var/lib/postgresql/data/pgdata volumes: - postgres_data:/var/lib/postgresql/data - ../../docs/postgres-schema.sql:/docker-entrypoint-initdb.d/001-schema.sql:ro networks: - yg-ft-app healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped redis: image: redis:7-alpine container_name: yg-ft-redis command: ["redis-server", "--appendonly", "yes"] volumes: - redis_data:/data networks: - yg-ft-app healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 restart: unless-stopped networks: yg-ft-app: name: yg-ft-app volumes: frontend_node_modules: postgres_data: redis_data: