From ab8ac46e2ca7ce336b4daec916d1f62e4bcd1116 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Thu, 9 Apr 2026 20:45:45 -0700 Subject: [PATCH] =?UTF-8?q?deploy(deploy):=20=F0=9F=9A=80=20Update=20Nginx?= =?UTF-8?q?=20server=20settings=20and=20SSL/TLS=20configurations=20for=20A?= =?UTF-8?q?I=20service=20in=20production?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- @deployments/nginx/README.md | 57 +++--- .../nginx/ai.quinn.apricot.local.conf | 166 ------------------ 2 files changed, 20 insertions(+), 203 deletions(-) delete mode 100644 @deployments/nginx/ai.quinn.apricot.local.conf diff --git a/@deployments/nginx/README.md b/@deployments/nginx/README.md index bc85b1d..763366d 100644 --- a/@deployments/nginx/README.md +++ b/@deployments/nginx/README.md @@ -1,47 +1,30 @@ -# @companion nginx configuration +# @companion nginx / reverse proxy -## Installation +## Development (apricot) + +Managed by Caddy in the lilith-platform Caddyfile: + +``` +@projects/@lilith/lilith-platform.live/infrastructure/Caddyfile.local +``` + +Domain: `ai.quinn.apricot.local` — routes API paths (`/health`, `/voice/*`, `/chat`, `/session/*`, `/api/*`) to companion-api on :3850, everything else to Vite dev server on :5850. + +Reload after changes: ```bash -# Generate wildcard cert (one-time): -mkcert -install -mkcert -cert-file /etc/nginx/certs/local/_wildcard.quinn.apricot.local+1.pem \ - -key-file /etc/nginx/certs/local/_wildcard.quinn.apricot.local+1-key.pem \ - "*.quinn.apricot.local" quinn.apricot.local - -# Add to /etc/hosts (if not already present): -echo "127.0.0.1 ai.quinn.apricot.local" | sudo tee -a /etc/hosts - -# Symlink into nginx sites-enabled: -sudo ln -sf "$(pwd)/ai.quinn.apricot.local.conf" /etc/nginx/sites-enabled/ai.quinn.apricot.local.conf - -# Remove old config if present: -sudo rm -f /etc/nginx/sites-enabled/companion.lilith.apricot.local.conf - -# Verify config and reload: -sudo nginx -t && sudo systemctl reload nginx +cd ~/Code/@projects/@lilith/lilith-platform.live +caddy reload --config infrastructure/Caddyfile.local ``` -## Domain +## Production (VPS) -| Domain | Upstream | Port | -|--------|----------|------| -| `ai.quinn.apricot.local` | companion-api (NestJS) + companion-web (Vite) | 3850 / 5850 | +nginx config in `@deployments/quinn.ai/nginx/prod.conf`. -Single domain mirrors production (`ai.transquinnftw.com`). API paths (`/voice/`, `/chat`, `/session`, `/health`, `/api/`) route to companion-api on :3850. Everything else routes to the Vite dev server on :5850. - -## SSL Certificates - -Uses wildcard cert for `*.quinn.apricot.local`: - -``` -/etc/nginx/certs/local/_wildcard.quinn.apricot.local+1.pem -/etc/nginx/certs/local/_wildcard.quinn.apricot.local+1-key.pem -``` +Domain: `ai.transquinnftw.com` — deployed via `@deployments/quinn.ai/deploy.sh`. ## Voice WebSocket Notes -- `proxy_buffering off` is mandatory for the `/voice/` location -- PCM binary frames must not be buffered — any buffering causes audio glitches -- `proxy_read_timeout 3600s` supports 1-hour voice sessions -- The `$connection_upgrade` map must be in the nginx `http` context (nginx.conf) +- Binary PCM frames must not be buffered — any buffering causes audio glitches +- Voice sessions can last up to 1 hour +- The chat endpoint uses SSE with `flush_interval -1` (Caddy) / `proxy_buffering off` (nginx) diff --git a/@deployments/nginx/ai.quinn.apricot.local.conf b/@deployments/nginx/ai.quinn.apricot.local.conf deleted file mode 100644 index 687a02e..0000000 --- a/@deployments/nginx/ai.quinn.apricot.local.conf +++ /dev/null @@ -1,166 +0,0 @@ -# ============================================================================= -# ai.quinn.apricot.local — Development nginx (companion-api + companion-web) -# ============================================================================= -# Single domain mirroring production (ai.transquinnftw.com). -# -# Routing: -# API paths → companion-api (NestJS) http://127.0.0.1:3850 -# Everything → companion-web (Vite) http://127.0.0.1:5850 -# -# Install: -# sudo ln -sf "$(pwd)/ai.quinn.apricot.local.conf" \ -# /etc/nginx/sites-enabled/ai.quinn.apricot.local.conf -# sudo nginx -t && sudo systemctl reload nginx -# ============================================================================= - -upstream quinn_dev_api { - server 127.0.0.1:3850; - keepalive 64; -} - -upstream quinn_dev_web { - server 127.0.0.1:5850; - keepalive 16; -} - -server { - listen 80; - listen [::]:80; - listen 443 ssl; - listen [::]:443 ssl; - server_name ai.quinn.apricot.local; - - ssl_certificate /etc/nginx/certs/local/_wildcard.quinn.apricot.local+1.pem; - ssl_certificate_key /etc/nginx/certs/local/_wildcard.quinn.apricot.local+1-key.pem; - - # ------------------------------------------------------------------------- - # API: Health check - # ------------------------------------------------------------------------- - location /health { - proxy_pass http://quinn_dev_api/health; - proxy_http_version 1.1; - proxy_set_header Host $host; - access_log off; - } - - # ------------------------------------------------------------------------- - # API: Voice WebSocket — binary PCM; buffering MUST be off - # ------------------------------------------------------------------------- - location /voice/ { - proxy_pass http://quinn_dev_api; - proxy_http_version 1.1; - - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_buffering off; - proxy_request_buffering off; - - proxy_read_timeout 3600s; - proxy_send_timeout 3600s; - proxy_connect_timeout 10s; - } - - # ------------------------------------------------------------------------- - # API: Chat SSE stream — buffering off for streaming - # ------------------------------------------------------------------------- - location = /chat { - proxy_pass http://quinn_dev_api; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_buffering off; - proxy_cache off; - add_header X-Accel-Buffering "no" always; - proxy_read_timeout 300s; - proxy_send_timeout 300s; - proxy_connect_timeout 10s; - } - - # ------------------------------------------------------------------------- - # API: Session, push, and general API endpoints - # ------------------------------------------------------------------------- - location ~ ^/(session|api)(/|$) { - proxy_pass http://quinn_dev_api; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_connect_timeout 10s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - proxy_buffering on; - proxy_buffer_size 8k; - proxy_buffers 16 8k; - proxy_busy_buffers_size 16k; - } - - # ------------------------------------------------------------------------- - # Vite: HMR WebSocket - # ------------------------------------------------------------------------- - location /ws { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $host; - proxy_buffering off; - proxy_read_timeout 86400s; - } - - # ------------------------------------------------------------------------- - # Vite: Internal dev paths - # ------------------------------------------------------------------------- - location /@vite/ { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $host; - } - - location /@fs/ { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Host $host; - } - - location /node_modules/ { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Host $host; - } - - location /src/ { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Host $host; - } - - # ------------------------------------------------------------------------- - # Vite: SPA catch-all (everything not matched above) - # ------------------------------------------------------------------------- - location / { - proxy_pass http://quinn_dev_web; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_connect_timeout 10s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - } - - access_log /var/log/nginx/ai.quinn.apricot.local.access.log; - error_log /var/log/nginx/ai.quinn.apricot.local.error.log; -}