refactor: switch nginx to Caddy with automatic Let's Encrypt
Build Admin / Build image (push) Successful in 13s

Nginx required manually managed certs on port 8443; TLS was effectively
unused. Caddy issues and renews certificates for DOMAIN on its own.

- Caddyfile replaces nginx.conf + locations.conf; upstreams are one
  `import api <prefix> <host> <path-prefix>` line each
- routes wrapped in `route {}` so guards run before handle_path
- access control (IP allowlist, X-Proxy-Token) generated from env into
  matchers.caddy / guard.caddy by the entrypoint, as before
- listeners: 443 (+udp, HTTP/3) and 80 for ACME on DOMAIN, plus the
  unchanged plain-HTTP 8082 -> 8080 path for existing clients
- caddy_data volume added: losing it re-issues certs and burns LE limits
- scripts/migrate-host-nginx.sh backs up and retires the host nginx
- deploy.sh points at the real prod layout (/srv/elevenlabs, compose v1)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
vasyanskandClaude Opus 5 committed 2026-09-20 13:35:49 +07:00
1 parent c31f6d8d90
commit d71001a2bf
15 files changed
+289 -466

No files matched your search

+15 -5
View File
@@ -1,16 +1,22 @@
services:
proxy:
image: git.realmanual.ru/pub/elevenlabs.io/elevenlabs:latest
build: .
container_name: api-proxy
restart: unless-stopped
ports:
- "8080:8080"
- "8443:8443"
# Public HTTPS endpoint + ACME HTTP-01 challenge
- "80:80"
- "443:443"
- "443:443/udp"
# Legacy plain-HTTP endpoint (unchanged for existing clients)
- "8082:8080"
env_file: .env
volumes:
# Mount TLS certs (optional — HTTPS disabled if files are absent)
# Place tls.crt and tls.key in ./ssl/ directory
- ./ssl:/etc/nginx/ssl:ro
# Let's Encrypt certificates and ACME account keys — MUST persist,
# otherwise every recreate re-issues certs and burns LE rate limits
- caddy_data:/data
- caddy_config:/config
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
interval: 30s
@@ -21,3 +27,7 @@ services:
options:
max-size: "50m"
max-file: "5"
volumes:
caddy_data:
caddy_config: