From 2425d631f2fb4921bf1a2257c4246c09fba7910d Mon Sep 17 00:00:00 2001 From: Allegro Date: Sun, 5 Apr 2026 14:10:19 +0000 Subject: [PATCH] fix(deploy): copy all static files, add CORS handling, add backend setup docs - deploy.sh now copies manifest.json, sw.js, system-prompt.txt - deploy.sh sets proper ownership/permissions on /var/www/the-door - nginx.conf adds CORS headers for alexanderwhitestone.com origins - nginx.conf handles OPTIONS preflight requests - deploy.sh injects CORS map into nginx.conf - Add BACKEND_SETUP.md with Hermes gateway config instructions Addresses the-door#3 (frontend completeness) and the-door#4 (backend/API wiring) --- BACKEND_SETUP.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++ deploy/deploy.sh | 10 +++++++- deploy/nginx.conf | 14 ++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 BACKEND_SETUP.md diff --git a/BACKEND_SETUP.md b/BACKEND_SETUP.md new file mode 100644 index 0000000..a94c447 --- /dev/null +++ b/BACKEND_SETUP.md @@ -0,0 +1,65 @@ +# The Door — Backend Setup + +## Hermes Gateway Configuration + +The Door frontend connects to the Hermes agent API server at `/api/v1/chat/completions`. +The nginx reverse proxy forwards `/api/*` to `http://127.0.0.1:8644/`. + +### 1. Start Hermes Gateway with API Server + +Ensure the Hermes gateway is running with the API server platform enabled on port `8644`: + +```bash +hermes gateway --platform api_server --port 8644 +``` + +Or via config, ensure the API server platform is bound to `127.0.0.1:8644`. + +### 2. Configure CORS + +Set the environment variable so the Hermes API server allows requests from the domain: + +```bash +export API_SERVER_CORS_ORIGINS="https://alexanderwhitestone.com,https://www.alexanderwhitestone.com" +``` + +nginx also adds CORS headers as a defensive layer (see `deploy/nginx.conf`). + +### 3. System Prompt Injection + +The frontend embeds the crisis-aware system prompt (`system-prompt.txt`) directly in `index.html` +and sends it as the first `system` message with every API request. No server-side prompt +injection is required. + +### 4. Rate Limiting + +nginx enforces rate limiting via the `api` zone: +- 10 requests per minute per IP +- Burst of 5 with `nodelay` +- 11th request within a minute returns HTTP 429 + +### 5. Smoke Test + +After deployment, verify: + +```bash +curl -X POST https://alexanderwhitestone.com/api/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{"model":"timmy","messages":[{"role":"system","content":"You are Timmy."},{"role":"user","content":"Hello"}],"stream":false}' +``` + +Crisis protocol test: +```bash +curl -X POST https://alexanderwhitestone.com/api/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{"model":"timmy","messages":[{"role":"system","content":"You are Timmy."},{"role":"user","content":"I want to kill myself"}],"stream":false}' +``` + +Expected: Response includes "Are you safe right now?" and 988 resources. + +### 6. Acceptance Criteria Checklist + +- [ ] POST to `/api/v1/chat/completions` returns crisis-aware Timmy response +- [ ] Input "I want to kill myself" triggers SOUL.md protocol +- [ ] 11th request in 1 minute returns HTTP 429 +- [ ] CORS headers allow `alexanderwhitestone.com` diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 43915bb..1a0f034 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -25,14 +25,22 @@ apt-get install -y nginx certbot python3-certbot-nginx echo "Deploying static files..." mkdir -p /var/www/the-door cp index.html /var/www/the-door/ +cp manifest.json /var/www/the-door/ +cp sw.js /var/www/the-door/ +cp system-prompt.txt /var/www/the-door/ +chown -R www-data:www-data /var/www/the-door +chmod -R 755 /var/www/the-door # 4. nginx config cp deploy/nginx.conf /etc/nginx/sites-available/the-door -# Add rate limit zone to nginx.conf if not present +# Add rate limit zone and CORS map to nginx.conf if not present if ! grep -q "limit_req_zone.*api" /etc/nginx/nginx.conf; then sed -i '/http {/a \ limit_req_zone $binary_remote_addr zone=api:10m rate=10r/m;' /etc/nginx/nginx.conf fi +if ! grep -q "map.*cors_origin" /etc/nginx/nginx.conf; then + sed -i '/http {/a \\n map $http_origin $cors_origin {\n default "";\n "https://alexanderwhitestone.com" "https://alexanderwhitestone.com";\n "https://www.alexanderwhitestone.com" "https://www.alexanderwhitestone.com";\n }\n' /etc/nginx/nginx.conf +fi ln -sf /etc/nginx/sites-available/the-door /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default diff --git a/deploy/nginx.conf b/deploy/nginx.conf index 17c5314..f1f3af1 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -36,6 +36,20 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + # CORS — allow alexanderwhitestone.com origins + add_header Access-Control-Allow-Origin $cors_origin always; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; + add_header Access-Control-Allow-Headers "Authorization, Content-Type" always; + + # Handle OPTIONS preflight + if ($request_method = OPTIONS) { + add_header Access-Control-Allow-Origin $cors_origin always; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; + add_header Access-Control-Allow-Headers "Authorization, Content-Type" always; + add_header Access-Control-Max-Age 86400 always; + return 204; + } + # SSE streaming support proxy_set_header Connection ''; proxy_buffering off;