version: "3.9" # Production waitlist deployment for VPS (Traefik proxy) # Serves: # GET /training/django-cohort/waitlist → cohort waitlist HTML page # POST /v1/waitlist/django-cohort → waitlist signup API services: waitlist-db: image: postgres:16-alpine restart: unless-stopped env_file: - .env environment: POSTGRES_DB: waitlist POSTGRES_USER: waitlist POSTGRES_PASSWORD: ${WAITLIST_DB_PASSWORD:-waitlistpw} volumes: - waitlist_postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U waitlist"] interval: 5s timeout: 5s retries: 10 networks: - waitlist-internal waitlist-web: image: training-software:local build: context: . args: REQUIREMENTS_FILE: waitlist.txt restart: unless-stopped env_file: - .env command: gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 2 --timeout 60 environment: DJANGO_SETTINGS_MODULE: config.settings.waitlist DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY} DJANGO_ALLOWED_HOSTS: "usepaperclip.app,api.usepaperclip.app,${TRAEFIK_HOST:-srv1603731.hstgr.cloud},localhost" DATABASE_URL: "postgres://waitlist:${WAITLIST_DB_PASSWORD:-waitlistpw}@waitlist-db:5432/waitlist" REDIS_URL: "redis://waitlist-redis:6379/0" depends_on: waitlist-db: condition: service_healthy waitlist-redis: condition: service_healthy networks: - waitlist-internal - traefik-public labels: - "traefik.enable=true" - "traefik.docker.network=traefik-public" # Route for api.usepaperclip.app - "traefik.http.routers.waitlist-api.rule=Host(`api.usepaperclip.app`)" - "traefik.http.routers.waitlist-api.entrypoints=websecure" - "traefik.http.routers.waitlist-api.tls=true" - "traefik.http.routers.waitlist-api.tls.certresolver=letsencrypt" - "traefik.http.routers.waitlist-api.service=waitlist-svc" # Route for usepaperclip.app (waitlist page + API on same host) - "traefik.http.routers.waitlist-frontend.rule=Host(`usepaperclip.app`)" - "traefik.http.routers.waitlist-frontend.entrypoints=websecure" - "traefik.http.routers.waitlist-frontend.tls=true" - "traefik.http.routers.waitlist-frontend.tls.certresolver=letsencrypt" - "traefik.http.routers.waitlist-frontend.service=waitlist-svc" # Service definition - "traefik.http.services.waitlist-svc.loadbalancer.server.port=8000" waitlist-redis: image: redis:7-alpine restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 10 networks: - waitlist-internal volumes: waitlist_postgres_data: networks: waitlist-internal: driver: bridge traefik-public: external: true