services: db: image: postgres:16-alpine container_name: codetutor-db environment: POSTGRES_USER: codetutor POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} POSTGRES_DB: codetutor volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U codetutor"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped networks: - internal backend: build: context: ../backend dockerfile: Dockerfile container_name: codetutor-backend environment: DATABASE_URL: postgresql+asyncpg://codetutor:${POSTGRES_PASSWORD}@db:5432/codetutor CORS_ORIGINS: '["https://codetutor-demo.kschappell.com", "https://kschappell.com"]' depends_on: db: condition: service_healthy restart: unless-stopped networks: - internal frontend: build: context: ../frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: https://codetutor-demo.kschappell.com container_name: codetutor-frontend depends_on: - backend restart: unless-stopped networks: - internal nginx: image: nginx:alpine container_name: codetutor-nginx volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - frontend - backend restart: unless-stopped networks: - internal - public-network cloudflared: image: cloudflare/cloudflared:latest container_name: codetutor-cloudflared command: tunnel run environment: TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN:?CLOUDFLARE_TUNNEL_TOKEN is required} depends_on: - nginx restart: unless-stopped networks: - public-network networks: internal: driver: bridge public-network: external: true