services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-popularity} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-popularity_dev_pw} POSTGRES_DB: ${POSTGRES_DB:-popularity} ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-popularity}"] interval: 5s timeout: 5s retries: 10 backend: build: context: ./backend dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy environment: DATABASE_URL: ${DATABASE_URL} AUTH_JWKS_URL: ${AUTH_JWKS_URL} AUTH_ISSUER: ${AUTH_ISSUER} AUTH_SERVICE_NAME: ${AUTH_SERVICE_NAME:-popularity} BACKEND_PORT: ${BACKEND_PORT:-8080} FETCH_CRON: ${FETCH_CRON:-0 3 * * *} FETCH_WORKERS: ${FETCH_WORKERS:-4} YOUTUBE_API_KEY: ${YOUTUBE_API_KEY} X_BEARER_TOKEN: ${X_BEARER_TOKEN} TELEGRAM_API_ID: ${TELEGRAM_API_ID} TELEGRAM_API_HASH: ${TELEGRAM_API_HASH} FACEBOOK_ACCESS_TOKEN: ${FACEBOOK_ACCESS_TOKEN} INSTAGRAM_ACCESS_TOKEN: ${INSTAGRAM_ACCESS_TOKEN} STACKEXCHANGE_KEY: ${STACKEXCHANGE_KEY} GITHUB_TOKEN: ${GITHUB_TOKEN} DISCORD_BOT_TOKEN: ${DISCORD_BOT_TOKEN} REDDIT_BEARER_TOKEN: ${REDDIT_BEARER_TOKEN} LINKEDIN_LI_AT: ${LINKEDIN_LI_AT} LINKEDIN_JSESSIONID: ${LINKEDIN_JSESSIONID} CAMOUFOX_URL: ${CAMOUFOX_URL:-} INSECURE_SKIP_AUTH: ${INSECURE_SKIP_AUTH:-false} DEV_USER_ID: ${DEV_USER_ID:-dev-local} ports: - "${BACKEND_PORT:-8080}:8080" frontend: build: context: ./frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8080} NEXT_PUBLIC_AUTH_URL: ${NEXT_PUBLIC_AUTH_URL:-https://auth.marketmaker.cc/api/v1} NEXT_PUBLIC_INSECURE_SKIP_AUTH: ${INSECURE_SKIP_AUTH:-false} restart: unless-stopped depends_on: - backend environment: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8080} NEXT_PUBLIC_AUTH_URL: ${NEXT_PUBLIC_AUTH_URL:-https://auth.marketmaker.cc/api/v1} ports: - "3000:3000" camoufox: build: context: ./camoufox dockerfile: Dockerfile args: GITHUB_TOKEN: ${GITHUB_TOKEN:-} restart: unless-stopped ports: # 3000 is the frontend's, so we expose camoufox on 3001 host-side. # Inside the docker network backend reaches it via http://camoufox:3000. - "3001:3000" # VNC for the one-time interactive login flow. Only useful when the # operator runs `docker compose --profile scraping run --rm -p 5900:5900 camoufox …`. - "5900:5900" volumes: - ./data/camoufox-profiles:/data/profiles profiles: - scraping volumes: postgres-data: