chore(nginx): 🔧 Update routing and performance configs for companion.lilith.apricot.local and ai.quinn.apricot.local services

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-04-09 20:10:04 -07:00
parent b66eba7add
commit dc2641844d
3 changed files with 186 additions and 189 deletions

View file

@ -3,36 +3,40 @@
## Installation
```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)/companion.lilith.apricot.local.conf" /etc/nginx/sites-enabled/companion.lilith.apricot.local.conf
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
```
## Domains
## Domain
| Domain | Upstream | Port |
|--------|----------|------|
| `companion.lilith.apricot.local` | companion-api (NestJS) | 3850 |
| `companion-web.lilith.apricot.local` | companion-web (Vite) | 5850 |
| `ai.quinn.apricot.local` | companion-api (NestJS) + companion-web (Vite) | 3850 / 5850 |
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 existing wildcard cert for `*.lilith.apricot.local`:
Uses wildcard cert for `*.quinn.apricot.local`:
```
/etc/nginx/certs/local/_wildcard.lilith.apricot.local+1.pem
/etc/nginx/certs/local/_wildcard.lilith.apricot.local+1-key.pem
```
If the cert doesn't exist yet, generate with mkcert:
```bash
mkcert -install
mkcert -cert-file /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1.pem \
-key-file /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1-key.pem \
"*.lilith.apricot.local" lilith.apricot.local
/etc/nginx/certs/local/_wildcard.quinn.apricot.local+1.pem
/etc/nginx/certs/local/_wildcard.quinn.apricot.local+1-key.pem
```
## Voice WebSocket Notes

View file

@ -0,0 +1,166 @@
# =============================================================================
# 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;
}

View file

@ -1,173 +0,0 @@
# companion.lilith.apricot.local — companion-api (NestJS)
# companion-web.lilith.apricot.local — companion-web (Vite dev server)
#
# companion-api port: 3850 (from @deployments/ports.yaml)
# companion-web port: 5850 (Vite dev, assigned adjacent to api)
#
# Upstream declarations must be in the http context.
# Include this file from /etc/nginx/sites-enabled/ via:
# include /etc/nginx/sites-enabled/companion.lilith.apricot.local.conf;
upstream companion_api {
server 127.0.0.1:3850;
keepalive 64;
}
upstream companion_web {
server 127.0.0.1:5850;
keepalive 16;
}
# companion-api: REST + WebSocket (voice pipeline)
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name companion.lilith.apricot.local;
ssl_certificate /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1.pem;
ssl_certificate_key /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1-key.pem;
# Health check (no buffering, no auth)
location /health {
proxy_pass http://companion_api/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
access_log off;
}
# Voice WebSocket endpoint — binary PCM; buffering MUST be off
location /voice/ {
proxy_pass http://companion_api;
proxy_http_version 1.1;
# WebSocket upgrade headers
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;
# Critical: disable buffering for binary PCM stream
proxy_buffering off;
proxy_request_buffering off;
# Long timeouts for persistent voice sessions
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 10s;
}
# REST API
location / {
proxy_pass http://companion_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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# WebSocket support (for future WS endpoints)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Buffering for REST responses
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
# SSE: disable buffering for /chat streaming
location /chat {
proxy_pass http://companion_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_read_timeout 300s;
proxy_send_timeout 300s;
}
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
access_log /var/log/nginx/companion.lilith.apricot.local.access.log;
error_log /var/log/nginx/companion.lilith.apricot.local.error.log;
}
# companion-web: Vite dev server (SPA + HMR)
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name companion-web.lilith.apricot.local;
ssl_certificate /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1.pem;
ssl_certificate_key /etc/nginx/certs/local/_wildcard.lilith.apricot.local+1-key.pem;
# Vite HMR WebSocket
location /ws {
proxy_pass http://companion_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 paths
location /@vite/ {
proxy_pass http://companion_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://companion_web;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /node_modules/ {
proxy_pass http://companion_web;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /src/ {
proxy_pass http://companion_web;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# SPA catch-all
location / {
proxy_pass http://companion_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/companion-web.lilith.apricot.local.access.log;
error_log /var/log/nginx/companion-web.lilith.apricot.local.error.log;
}