# nginx — feedthepyre.com virtual host This directory holds the nginx virtual host config for **feedthepyre.com**, the public domain for the PYRE / Prometheus Protocol MVP. - [`feedthepyre.com.conf`](feedthepyre.com.conf) — the vhost. ## What it does now Right now the vhost serves a **static status dashboard** (a holding/status page) for both `feedthepyre.com` and `www.feedthepyre.com`. - Site root (`location /`) serves files from the webroot `/var/www/feedthepyre/status` (with `index.html`), using `try_files $uri $uri/ /index.html`. - The Next.js web app and Fastify API are **not** proxied yet — those blocks are present but commented out. - An explicit `/.well-known/acme-challenge/` location is served from the same webroot so Let's Encrypt HTTP-01 validation works even before certbot applies its `--nginx` changes. - gzip is enabled for common text content types. Ports (per `.env.example`; design §11 names the processes but not their ports): | service | bind | env var | | -------------- | --------------- | ---------- | | web (Next.js) | 127.0.0.1:3000 | `WEB_PORT` | | api (Fastify) | 127.0.0.1:4000 | `API_PORT` | ## How the provision script installs it The provisioning script (run with sudo on the PYRE VPS) is expected to: 1. Copy `feedthepyre.com.conf` to `/etc/nginx/sites-available/feedthepyre.com`. 2. Symlink it into the enabled set: `ln -s /etc/nginx/sites-available/feedthepyre.com /etc/nginx/sites-enabled/feedthepyre.com` 3. Ensure the webroot exists and has an index page: `mkdir -p /var/www/feedthepyre/status` (drop an `index.html` in it). 4. Validate and reload: `nginx -t && systemctl reload nginx`. These exact paths are a contract the script relies on — do not rename the install path or the webroot without updating the script too. > This config is file-only. Do not run nginx/sudo from this repo; the provision > script owns that. ## How certbot adds TLS After the HTTP vhost is installed and nginx is reloaded, obtain certificates: ```bash sudo certbot --nginx -d feedthepyre.com -d www.feedthepyre.com ``` certbot will **edit `feedthepyre.com.conf` in place**, adding: - a `listen 443 ssl;` server block, - `ssl_certificate` / `ssl_certificate_key` directives (and Let's Encrypt includes), - an HTTP->HTTPS redirect on the `listen 80;` server. That is why the `:80` server is written as a plain `listen 80;` block with both domains in `server_name` — it is the shape certbot expects to augment. Renewals are handled automatically by certbot's systemd timer/cron. ## Flipping from the static status page to the live app + API proxy Once `apps/web` (Next.js, port 3000) and `apps/api` (Fastify, port 4000) are deployed and running on the VPS: 1. Edit `/etc/nginx/sites-available/feedthepyre.com`. 2. **Enable the API proxy:** uncomment the `location /api/ { ... }` block. The trailing slash on `proxy_pass http://127.0.0.1:4000/;` strips the `/api/` prefix so the backend sees `/scan`, `/receipt`, etc. 3. **Switch the root to the web app:** in `location / { ... }`, replace the `try_files ...` line with the `proxy_pass http://127.0.0.1:3000;` block shown in the inline comment (Host / X-Real-IP / X-Forwarded-For / X-Forwarded-Proto plus the websocket Upgrade/Connection headers). 4. **Add the websocket map** (one time) to the `http{}` block of `/etc/nginx/nginx.conf`: ```nginx map $http_upgrade $connection_upgrade { default upgrade; '' close; } ``` 5. **Optional global hardening:** add `server_tokens off;` to the same `http{}` block (kept out of the vhost on purpose so it is not duplicated). 6. Validate and reload: ```bash sudo nginx -t && sudo systemctl reload nginx ``` Keep the `/.well-known/acme-challenge/` location in place so certificate renewals continue to work after the cutover.