version: "3.9" services: # ── Streamlit app ──────────────────────────────────────────────────────────── pna-assistant: build: context: . dockerfile: Dockerfile container_name: pna-assistant restart: unless-stopped ports: - "8501:8501" environment: - STRIPE_PRO_LINK=${STRIPE_PRO_LINK} - STRIPE_INSTITUTION=${STRIPE_INSTITUTION} volumes: - ./assets:/app/assets:ro healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8501/_stcore/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # ── Stripe webhook handler ─────────────────────────────────────────────────── pna-webhook: build: context: . dockerfile: Dockerfile.webhook container_name: pna-webhook restart: unless-stopped ports: - "8080:8080" environment: - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} - AWS_REGION=${AWS_REGION:-eu-west-2} - SES_FROM_EMAIL=${SES_FROM_EMAIL:-lincoln@clinyqai.com} # SES needs IAM role on EC2 (preferred) OR explicit credentials: # - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} # - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} volumes: - codes_data:/app # persist codes.jsonl across restarts healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"] interval: 30s timeout: 10s retries: 3 start_period: 20s # ── Nginx reverse proxy ────────────────────────────────────────────────────── nginx: image: nginx:alpine container_name: pna-nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro - /etc/letsencrypt:/etc/letsencrypt:ro depends_on: - pna-assistant - pna-webhook volumes: codes_data: