diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..11a7a18 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,40 @@ +{ + # Admin API for programmatic route management (future use for ISO downloads) + admin localhost:2019 + + # For local development, use internal CA + # In production, Caddy auto-obtains Let's Encrypt certs +} + +# Development configuration (localhost) +:443 { + tls internal # Self-signed for local dev + + # Reverse proxy to FastAPI + reverse_proxy localhost:8000 { + health_uri /health + health_interval 10s + health_timeout 5s + } + + # Security headers (supplement FastAPI's headers) + header { + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + } + + # Access logging + log { + output file /var/log/caddy/access.log { + roll_size 100mb + roll_keep 10 + } + format json + } +} + +# HTTP to HTTPS redirect +:80 { + redir https://{host}{uri} permanent +} diff --git a/docker-compose.yml b/docker-compose.yml index d9c37e2..1442cb5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,5 +18,25 @@ services: start_period: 10s restart: unless-stopped + caddy: + image: caddy:2-alpine + container_name: debate-caddy + restart: unless-stopped + ports: + - "80:80" + - "443:443" + - "127.0.0.1:2019:2019" # Admin API (localhost only) + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile:ro + - caddy_data:/data + - caddy_config:/config + - caddy_logs:/var/log/caddy + network_mode: host # To reach localhost:8000 + depends_on: + - postgres + volumes: postgres_data: + caddy_data: + caddy_config: + caddy_logs: