From b36a696d0ebcb5c4715248f7eff4d2ec5ebadd95 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Thu, 10 Sep 2026 08:43:25 +0000 Subject: [PATCH] feat: Added nginx container to docker compose file --- CLAUDE.md | 2 +- deploy/docker/.env.example | 3 ++ deploy/docker/docker-compose.yml | 18 ++++++-- deploy/docker/nginx/vantage.conf | 72 ++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 deploy/docker/nginx/vantage.conf diff --git a/CLAUDE.md b/CLAUDE.md index 0ad8591..4d00ff7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1151,7 +1151,7 @@ TLS is `ingress.tls.secretName` / `grpcSecretName` (pre-existing certificates) * --- -**Neither compose file ships a reverse proxy, and both now need one.** `web:3000` serves the UI only; a request to `/api` there is a Next 404. Route `/api`, `/auth`, `/public`, `/install`, `/install.ps1`, `/update`, `/update.ps1` to `server:8080` and everything else to `web:3000` — on vantage.hostxtra.co.uk that is the Nginx Proxy Manager already in front, and it is what a self-hosted install has to configure before the UI works at all. +**The compose file ships an `nginx` service, and the UI does not work without it or an equivalent.** `web:3000` serves the UI only; a request to `/api` there is a Next 404. `deploy/docker/nginx/vantage.conf` routes `/api`, `/auth`, `/public`, `/install`, `/install.ps1`, `/update`, `/update.ps1` to `server:8080` and everything else to `web:3000`, on plain HTTP at `${NGINX_HTTP_PORT:-80}`. The self-hosted install docs reproduce that file, so a routing change there must change in `vantage-docs` too. On vantage.hostxtra.co.uk the Nginx Proxy Manager already in front does the same routing, so the host port must not collide with it. `deploy/docker/docker-compose.yml` runs four services: `redis`, `guacd`, `server` (8080 + 9090), `web` (3000). MongoDB is external. **That is the whole of a self-hosted install**, and it is now the only compose file here. vantage.hostxtra.co.uk adds three fragments from three other repositories — `vantage-site` (`site` 3003, `sitesvc` 8082), `vantage-docs` (`docsite` 3005) and `vantage-admin` (`admin` 8083, `adminsite` 3004) — composed together as shown under "The public host". diff --git a/deploy/docker/.env.example b/deploy/docker/.env.example index afae5cc..6bd3265 100644 --- a/deploy/docker/.env.example +++ b/deploy/docker/.env.example @@ -17,4 +17,7 @@ KEY_ENCRYPTION_KEY= # MongoDB is bundled in this compose file. Override only to use an external DB. MONGO_URI=mongodb://mongo:27017/vantage +# Host port the bundled nginx reverse proxy listens on (plain HTTP). +NGINX_HTTP_PORT=80 + # Where workflow run logs are written inside the server container. diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml index cbc57d1..0c6d13e 100644 --- a/deploy/docker/docker-compose.yml +++ b/deploy/docker/docker-compose.yml @@ -60,12 +60,22 @@ services: restart: unless-stopped ports: - 3000:3000 - # No API_URL: web proxies nothing. The reverse proxy in front of this - # deployment must route /api, /auth, /public, /install*, /update* to - # server:8080 and everything else to web:3000. Reaching web:3000 - # directly serves the UI and every API call 404s. + # No API_URL: web proxies nothing. The nginx service below routes + # /api, /auth, /public, /install*, /update* to server:8080 and + # everything else to web:3000. Reaching web:3000 directly serves the + # UI and every API call 404s. depends_on: - server + nginx: + image: nginx:1.29-alpine + restart: unless-stopped + ports: + - ${NGINX_HTTP_PORT:-80}:80 + volumes: + - ./nginx/vantage.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - server + - web volumes: mongo_data: null redis_data: null diff --git a/deploy/docker/nginx/vantage.conf b/deploy/docker/nginx/vantage.conf new file mode 100644 index 0000000..65b2cb3 --- /dev/null +++ b/deploy/docker/nginx/vantage.conf @@ -0,0 +1,72 @@ +# Reverse proxy for a self-hosted Vantage install. +# +# One hostname, two backends: the control plane's HTTP routes go to +# server:8080, everything else to web:3000. web proxies nothing itself, so +# without the server locations the UI loads and every request it makes 404s. +# +# Plain HTTP only. Terminate TLS in front of this container, or see the +# self-hosted install docs for a variant that terminates TLS here. + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +upstream vantage_server { + server server:8080; + keepalive 16; +} + +upstream vantage_web { + server web:3000; + keepalive 16; +} + +server { + listen 80; + listen [::]:80; + server_name _; + + # Step imports and licence pastes are the largest request bodies. + client_max_body_size 10m; + + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-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; + + # Control plane: REST API, auth, public status pages. + location ^~ /api/ { + proxy_pass http://vantage_server; + + # The browser console is a WebSocket at /api/console/tunnel and + # workflow logs stream as server-sent events; neither may be buffered + # or cut off by a short read timeout. + proxy_buffering off; + proxy_read_timeout 1h; + proxy_send_timeout 1h; + } + + location ^~ /auth/ { + proxy_pass http://vantage_server; + } + + location ^~ /public/ { + proxy_pass http://vantage_server; + } + + # Agent install and update scripts: /install, /install.ps1, /update, + # /update.ps1. + location ~ ^/(install|update)(\.ps1)?$ { + proxy_pass http://vantage_server; + } + + # Everything else is the web UI. + location / { + proxy_pass http://vantage_web; + } +}