Files
zopu-code/deploy/vds/Caddyfile
2026-08-04 01:38:48 +05:30

61 lines
2.6 KiB
Caddyfile

# Caddy reverse proxy for the Zopu VDS staging agent stack.
#
# This is the ONLY public ingress to the single agents Node process (see
# docs/DEPLOYMENT_PLAN.md §"Public surface"). It terminates TLS for
# agents.zopu.puter.wtf — the Flue callback hostname Convex reaches — then
# forwards ONLY the documented worker paths to the internal `agents` service at
# 127.0.0.1:3000.
#
# Hard rules this file enforces:
# - No generic /api/* proxy and no browser-to-Flue traffic (DEPLOYMENT_PLAN.md
# line 86). Browsers talk only to Convex.
# - Only the paths the Convex backend actually calls are routed:
# /health liveness probe
# /internal/project-setup single-call project setup coordinator
# /internal/agents/<agentId>/events agent event dispatch callback
# - The RivetKit serverless registry at /internal/rivet/* is NOT proxied. It
# is a private loopback callback the Engine reaches directly at
# http://127.0.0.1:3000/internal/rivet; exposing it publicly would widen the
# private worker protocol.
# - Former routes (/agents/zopu/*, /internal/work-attempts/*, /workflows/*,
# /api/rivet/*) are intentionally absent: they are stale and not part of the
# current Convex→agents contract.
# - Everything else returns 404. The private worker protocol stays narrow.
#
# TLS certs persist in Caddy's data directory. Caddy serves its own ACME
# HTTP-01 challenge responses on :80 automatically, so the :80 block only
# redirects everything else to HTTPS — worker traffic is never served over
# plain HTTP.
#
# Install/update: see the "Caddy" section of deploy/vds/README.md. In short,
# copy this file to /etc/caddy/Caddyfile, then:
# sudo caddy validate --config /etc/caddy/Caddyfile
# sudo systemctl reload caddy
agents.zopu.puter.wtf {
encode zstd gzip
# Explicit route block pins directive order: path-matched proxies run
# first, then the terminal 404 fallback. No directive is left to the
# default sort.
route {
# Liveness probe (CI healthcheck). Routed to the real worker so a failed
# process is not masked by a synthetic success.
reverse_proxy /health 127.0.0.1:3000
# Single-call project setup coordinator. Requires the internalRoute bearer.
reverse_proxy /internal/project-setup 127.0.0.1:3000
# Agent event dispatch callback. Requires the internalRoute bearer.
reverse_proxy /internal/agents/* 127.0.0.1:3000
# Everything else is not part of the private worker protocol.
respond 404
}
}
# HTTP → HTTPS redirect (Caddy still answers ACME challenges on :80).
:80 {
redir https://{host}{uri} permanent
}