version: '3.8' networks: proxy: external: true turftracker: driver: bridge services: frontend: build: context: ./frontend dockerfile: Dockerfile environment: - REACT_APP_API_URL=https://turftracker.kaspers.us/api - CHOKIDAR_USEPOLLING=true - WATCHPACK_POLLING=true - WDS_SOCKET_PORT=443 - DANGEROUSLY_DISABLE_HOST_CHECK=true volumes: - ./frontend:/app - /app/node_modules depends_on: - backend networks: - proxy - turftracker labels: - "traefik.enable=true" - "traefik.http.routers.turftracker-frontend.rule=Host(`turftracker.kaspers.us`)" - "traefik.http.routers.turftracker-frontend.entrypoints=websecure" - "traefik.http.routers.turftracker-frontend.tls.certresolver=letsencrypt" - "traefik.http.services.turftracker-frontend.loadbalancer.server.port=3000" - "traefik.docker.network=proxy" - "traefik.constraint=proxy-public" restart: unless-stopped backend: build: context: ./backend dockerfile: Dockerfile environment: - NODE_ENV=development - DB_HOST=db - DB_PORT=5432 - DB_NAME=${DB_NAME:-turftracker} - DB_USER=${DB_USER:-turftracker} - DB_PASSWORD=${DB_PASSWORD:-password123} - JWT_SECRET=${JWT_SECRET:-dev-secret-key-change-in-production-12345} - AUTHENTIK_CLIENT_ID=${AUTHENTIK_CLIENT_ID:-} - AUTHENTIK_CLIENT_SECRET=${AUTHENTIK_CLIENT_SECRET:-} - AUTHENTIK_BASE_URL=${AUTHENTIK_BASE_URL:-} - AUTHENTIK_CALLBACK_URL=${AUTHENTIK_CALLBACK_URL:-https://turftracker.kaspers.us/api/auth/authentik/callback} - WEATHER_API_KEY=${WEATHER_API_KEY:-} - FRONTEND_URL=https://turftracker.kaspers.us volumes: - ./backend:/app - /app/node_modules depends_on: db: condition: service_healthy networks: - proxy - turftracker labels: - "traefik.enable=true" - "traefik.http.routers.turftracker-backend.rule=Host(`turftracker.kaspers.us`) && PathPrefix(`/api`)" - "traefik.http.routers.turftracker-backend.entrypoints=websecure" - "traefik.http.routers.turftracker-backend.tls.certresolver=letsencrypt" - "traefik.http.services.turftracker-backend.loadbalancer.server.port=5000" - "traefik.docker.network=proxy" restart: unless-stopped db: image: postgres:15-alpine environment: - POSTGRES_USER=${DB_USER:-turftracker} - POSTGRES_PASSWORD=${DB_PASSWORD:-password123} - POSTGRES_DB=${DB_NAME:-turftracker} volumes: - postgres_data:/var/lib/postgresql/data - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-turftracker} -d ${DB_NAME:-turftracker} -h 127.0.0.1 -p 5432"] interval: 5s timeout: 5s retries: 20 networks: - turftracker restart: unless-stopped # Database should not be exposed to proxy network for security flyway: image: flyway/flyway:9 depends_on: - db environment: - FLYWAY_URL=jdbc:postgresql://db:5432/${DB_NAME:-turftracker} - FLYWAY_USER=${DB_USER:-turftracker} - FLYWAY_PASSWORD=${DB_PASSWORD:-password123} # Uncomment if you need to baseline an existing DB without schema history - FLYWAY_BASELINE_ON_MIGRATE=true - FLYWAY_LOCATIONS=filesystem:/migrations command: migrate volumes: - ./database/migrations:/migrations:ro networks: - turftracker # Not started automatically; run with: docker compose run --rm flyway migrate volumes: postgres_data: