Files
anwar-pi-website/web/docker-compose.vps.yml
T

91 lines
3.6 KiB
YAML

services:
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: anwarpi
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: anwarpi
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U anwarpi -d anwarpi"]
interval: 5s
timeout: 5s
retries: 10
web:
# Run migrations explicitly as a separate reviewed deployment step.
# Access-control-only release: avoid the dev-schema interactive prompt.
command: ["npm", "run", "start"]
build:
context: .
args:
NEXT_PUBLIC_SITE_URL: https://anwarpy.ai
restart: unless-stopped
expose:
- "3000"
volumes:
- media-uploads:/app/media
- files-uploads:/app/files-private
environment:
DATABASE_URI: postgres://anwarpi:${DB_PASSWORD}@db:5432/anwarpi
PAYLOAD_SECRET: ${PAYLOAD_SECRET}
AGENT_API_KEY: ${AGENT_API_KEY}
NEXT_PUBLIC_SITE_URL: https://anwarpy.ai
LAUNCH_MODE: ${LAUNCH_MODE:-free_early_access}
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
CLOUDFLARE_ACCOUNT_ID: ${CLOUDFLARE_ACCOUNT_ID}
MAIL_FROM: noreply@anwarpy.ai
labels:
- traefik.enable=true
- traefik.http.routers.anwarpi.rule=Host(`anwarpy.ai`)
- traefik.http.routers.anwarpi.entrypoints=websecure
- traefik.http.routers.anwarpi.tls.certresolver=mytlschallenge
- traefik.http.routers.anwarpi.middlewares=pagelimit@docker,connlimit@docker
- traefik.http.services.anwarpi.loadbalancer.server.port=3000
# 39: canonical host is the apex. www hits this router first (priority
# above anwarpi-api's 100) and is 301-redirected before any rate limit.
- traefik.http.routers.anwarpi-www.rule=Host(`www.anwarpy.ai`)
- traefik.http.routers.anwarpi-www.entrypoints=websecure
- traefik.http.routers.anwarpi-www.tls.certresolver=mytlschallenge
- traefik.http.routers.anwarpi-www.priority=110
- traefik.http.routers.anwarpi-www.service=anwarpi
- traefik.http.routers.anwarpi-www.middlewares=www-redirect
- traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www\.anwarpy\.ai/(.*)
- traefik.http.middlewares.www-redirect.redirectregex.replacement=https://anwarpy.ai/$$1
- traefik.http.middlewares.www-redirect.redirectregex.permanent=true
- traefik.http.routers.anwarpi-api.rule=PathPrefix(`/api`) && Host(`anwarpy.ai`)
- traefik.http.routers.anwarpi-api.entrypoints=websecure
- traefik.http.routers.anwarpi-api.tls=true
- traefik.http.routers.anwarpi-api.tls.certresolver=mytlschallenge
- traefik.http.routers.anwarpi-api.service=anwarpi
- traefik.http.routers.anwarpi-api.middlewares=apilimit@docker
- traefik.http.routers.anwarpi-api.priority=100
- traefik.http.middlewares.apilimit.ratelimit.average=90
- traefik.http.middlewares.apilimit.ratelimit.burst=180
- traefik.http.middlewares.apilimit.ratelimit.period=1m
# F1: the pentest flood froze pages while /api held. Cap per-IP page
# rate and in-flight requests; apilimit already guards /api itself.
- traefik.http.middlewares.pagelimit.ratelimit.average=60
- traefik.http.middlewares.pagelimit.ratelimit.period=1m
- traefik.http.middlewares.pagelimit.ratelimit.burst=120
- traefik.http.middlewares.connlimit.inflightreq.amount=50
- traefik.docker.network=proxy
depends_on:
db:
condition: service_healthy
networks:
- default
- proxy
volumes:
db-data:
media-uploads:
files-uploads:
networks:
default:
proxy:
external: true