deploy: record the relay as actually deployed
Quadlets captured from the live units on bob, with the real immutable tags (0.1.44-ge06652a) rather than a placeholder, plus the hanzalova vhost that mounts the relay on /relay-api/ of the existing name. Verified end to end: /relay-api/health returns ok through the prefix, the relay's nested /v1 routes answer 401 rather than 404 (so the strip reaches them and they are genuinely protected), the remote's own /v1 is unaffected, and the served SPA bundle now carries the origin-relative /relay-api base. The vhost is committed because it is half the design: the relay only works on a path because nginx strips the prefix, and a future kanban.l4ir.net needs exactly this location block and nothing else.
This commit is contained in:
75
deploy/nginx/kanban.internal.conf
Normal file
75
deploy/nginx/kanban.internal.conf
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Mesh-only vhost for vibe-kanban, fronted by the hanzalova edge proxy (office site).
|
||||||
|
# Cert: internal `lair` CA, minted from the operator box and renewed by
|
||||||
|
# step@kanban.timer (architecture internal-tls.md — dot-free instance label).
|
||||||
|
# Whole-app reverse proxy to the vibe-kanban remote-server on bob, which serves
|
||||||
|
# both its API and the built SPA. Mirrors the hermes.internal vhost pattern.
|
||||||
|
# ln -sf ../sites-available/kanban.internal.conf /etc/nginx/sites-enabled/
|
||||||
|
#
|
||||||
|
# TLS terminates here, not in the app: upstream's compose puts Caddy in front for
|
||||||
|
# Let's Encrypt, which we drop entirely — this is a mesh-only name on the internal
|
||||||
|
# CA. remote-server is told SERVER_PUBLIC_BASE_URL=https://kanban.internal so the
|
||||||
|
# links it generates match what the client actually reached.
|
||||||
|
#
|
||||||
|
# Electric streams shape updates over long-lived HTTP; the long read timeout and
|
||||||
|
# disabled buffering below are what keep those from being cut or batched.
|
||||||
|
|
||||||
|
# The relay is a separate service on the same host. It is mounted on a PATH of
|
||||||
|
# this vhost rather than given its own name: every relay URL on both sides is
|
||||||
|
# composed as {base}/v1/..., and the relay has no notion of its own public
|
||||||
|
# address, so a prefix is invisible to it. Same-origin also means no CORS and no
|
||||||
|
# second certificate -- and a future kanban.l4ir.net inherits the relay by
|
||||||
|
# copying the location block below.
|
||||||
|
upstream kanban_relay_up {
|
||||||
|
server bob.hanzalova.internal:27181;
|
||||||
|
keepalive 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream kanban_up {
|
||||||
|
server bob.hanzalova.internal:27180;
|
||||||
|
keepalive 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name kanban.internal;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/tls/cert/kanban.internal.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/tls/key/kanban.internal.pem;
|
||||||
|
ssl_protocols TLSv1.3;
|
||||||
|
ssl_trusted_certificate /etc/pki/ca-trust/source/anchors/root-internal.pem;
|
||||||
|
|
||||||
|
client_max_body_size 100m;
|
||||||
|
# Electric shape subscriptions are long-poll/streaming; don't cut them short.
|
||||||
|
proxy_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
|
||||||
|
# Trailing slash on proxy_pass strips /relay-api/, so the relay sees the
|
||||||
|
# /v1/... routes it nests. Must precede location / .
|
||||||
|
location /relay-api/ {
|
||||||
|
proxy_pass http://kanban_relay_up/;
|
||||||
|
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;
|
||||||
|
# The relay control channel is a long-lived websocket.
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://kanban_up;
|
||||||
|
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;
|
||||||
|
# Sync streams must reach the browser as they arrive, not in buffers.
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ Wants=network-online.target
|
|||||||
Requires=vibe-kanban-db.service
|
Requires=vibe-kanban-db.service
|
||||||
|
|
||||||
[Container]
|
[Container]
|
||||||
Image=git.lair.cafe/lair/vibe-kanban-relay:REPLACE_WITH_IMMUTABLE_TAG
|
Image=git.lair.cafe/lair/vibe-kanban-relay:0.1.44-ge06652a
|
||||||
ContainerName=vibe-kanban-relay
|
ContainerName=vibe-kanban-relay
|
||||||
Network=vibe-kanban.network
|
Network=vibe-kanban.network
|
||||||
# Published to the LAN so the hanzalova edge proxy can reach it; the browser and
|
# Published to the LAN so the hanzalova edge proxy can reach it; the browser and
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Wants=network-online.target
|
|||||||
Requires=vibe-kanban-db.service
|
Requires=vibe-kanban-db.service
|
||||||
|
|
||||||
[Container]
|
[Container]
|
||||||
Image=git.lair.cafe/lair/vibe-kanban-remote:0.1.44-gccff6fc
|
Image=git.lair.cafe/lair/vibe-kanban-remote:0.1.44-ge06652a
|
||||||
ContainerName=vibe-kanban
|
ContainerName=vibe-kanban
|
||||||
Network=vibe-kanban.network
|
Network=vibe-kanban.network
|
||||||
PublishPort=27180:8081
|
PublishPort=27180:8081
|
||||||
|
|||||||
Reference in New Issue
Block a user