diff --git a/deploy/ecosystem/docker-compose.yml b/deploy/ecosystem/docker-compose.yml index a49082e..0cca3ec 100644 --- a/deploy/ecosystem/docker-compose.yml +++ b/deploy/ecosystem/docker-compose.yml @@ -8,6 +8,18 @@ # # Maven's own compose joins this same network (add `ecosystem` as an external # network there) to reach nexus:9740 / praxis:8989 / hexis:9741 directly. +# +# NO RELEASE PINNING (Vikunja #354): each `build:` below points at a sibling +# WORKING TREE, so `up --build` ships whatever is checked out there, including +# uncommitted edits. Before bringing this up, check what you are about to +# deploy: +# +# for r in nexus praxis hexis; do git -C ../../../$r status --short; \ +# git -C ../../../$r log -1 --oneline; done +# +# The host nginx that fronts these is deploy/ecosystem/nginx.conf — it binds +# the wg and LAN addresses only, with allow/deny. Keep it that way: none of +# these containers has auth of its own. name: ecosystem services: diff --git a/deploy/ecosystem/nginx.conf b/deploy/ecosystem/nginx.conf index a511b03..7e84902 100644 --- a/deploy/ecosystem/nginx.conf +++ b/deploy/ecosystem/nginx.conf @@ -1,6 +1,7 @@ -# Reverse-proxy the three sibling admin UIs. Drop into your nginx sites (or the -# nginx-panel app) and reload. Assumes the compose publishes each service on -# 127.0.0.1:. Add TLS (certbot / your existing cert block) per server. +# Reverse-proxy Maven's own web UI plus the three sibling admin UIs. Drop into +# your nginx sites (or the nginx-panel app) and reload. Assumes the compose +# publishes each service on 127.0.0.1:. Add TLS (certbot / your existing +# cert block) per server. # # NOTE: hexis. previously pointed at the MCP tool — repoint that # elsewhere first (the app now owns hexis.*). @@ -12,6 +13,50 @@ # Do NOT "fix" a failed bind by reverting to `listen 80` (all interfaces) — # that removes the only access control these containers have. +# maven. → mavweb (docker-compose.yml publishes it on 127.0.0.1:9201). +# Same bind + ACL as the siblings, and for a stronger reason: mavweb serves +# POST /tools, which defines argv that internal/tool EXECUTES, plus POST +# /routines, /api/revert and /api/chat (Vikunja #317). Without +# -webauthn-origin/-webauthn-rpid mavweb has no auth of its own, so this block +# is the auth. If you add TLS and a basic-auth/oauth2-proxy layer, keep the +# allow/deny anyway — belt and braces on an RCE surface. +# +# WebSocket upgrade matters here: /ws carries push-to-talk audio, so the +# Upgrade/Connection headers below are required, not decoration. The map keeps +# `Connection: upgrade` off plain requests; it sits in the http context, which +# is where sites-available files are included — if your nginx already defines +# $connection_upgrade, drop this block. +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 10.42.0.1:80; + listen 192.168.1.104:80; + server_name maven.kvmx.ru; + + allow 10.42.0.0/24; + allow 192.168.1.0/24; + deny all; + + # push-to-talk uploads raw PCM; the default 1m is enough for a short + # utterance but not for a long one. + client_max_body_size 32m; + + location / { + proxy_pass http://127.0.0.1:9201; + 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_read_timeout 300s; # an LLM turn can take minutes on the iGPU + } +} + server { listen 10.42.0.1:80; listen 192.168.1.104:80;