deploy(deployments): 🚀 Refactor and enhance deployment workflows in the deployments directory

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-04-01 23:54:15 -07:00
parent 0bc056d211
commit e455bc3990
4 changed files with 296 additions and 0 deletions

View file

@ -0,0 +1,40 @@
services:
companion-postgres:
image: postgres:16-alpine
container_name: lilith-companion-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-lilith}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-lilith}
POSTGRES_DB: ${POSTGRES_DB:-companion}
ports:
- "${POSTGRES_PORT:-26407}:5432"
volumes:
- companion-postgres-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-lilith} -d ${POSTGRES_DB:-companion}']
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
companion-redis:
image: redis:7-alpine
container_name: lilith-companion-redis
restart: unless-stopped
ports:
- "${REDIS_PORT:-26406}:6379"
volumes:
- companion-redis-data:/data
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
volumes:
companion-postgres-data:
name: lilith-${LILITH_ENV:-dev}-companion-postgres-data
companion-redis-data:
name: lilith-${LILITH_ENV:-dev}-companion-redis-data

View file

@ -0,0 +1,43 @@
# @companion nginx configuration
## Installation
```bash
# Symlink into nginx sites-enabled:
sudo ln -sf "$(pwd)/companion.lilith.apricot.local.conf" /etc/nginx/sites-enabled/companion.lilith.apricot.local.conf
# Verify config and reload:
sudo nginx -t && sudo systemctl reload nginx
```
## Domains
| Domain | Upstream | Port |
|--------|----------|------|
| `companion.lilith.apricot.local` | companion-api (NestJS) | 3850 |
| `companion-web.lilith.apricot.local` | companion-web (Vite) | 5850 |
## SSL Certificates
Uses existing wildcard cert for `*.lilith.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
```
## 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)

View file

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

40
@deployments/ports.yaml Normal file
View file

@ -0,0 +1,40 @@
# @companion Service Ports - Development
#
# Assigned port ranges:
# companion-api: 3850 (NestJS HTTP + WS)
# companion-postgres: 26397 (PostgreSQL)
# companion-redis: 26396 (Redis)
#
# Port conflict audit (2026-04-01):
# 3790 → @ai ai-core (taken)
# 8001-8012 → @imajin (taken)
# 8080, 8090 → @imajin api/app (taken)
# 8210 → @model-boss coordinator (taken)
# 10010 → llama-http (taken)
# 26404 → @ai ai-redis (taken)
# 26405 → @ai ai-postgres (taken)
# 41222 → @audio speech-synthesis (taken)
companion:
# NestJS orchestration API (HTTP REST + WebSocket)
api: 3850
# Vite dev server (React PWA)
web: 5850
# Local infrastructure
postgres:
companion: 26407
redis:
companion: 26406
# Remote services (network — addresses configured via service-registry)
external:
ai_core: 3790 # @ai ai-core (localhost or network)
model_boss: 8210 # @model-boss (apricot.local)
speech_synthesis: 41222 # @audio speech-synthesis (apricot.local)
# Runtime configuration (dev)
runtime:
reload: true
log_level: debug