Reverse proxy
Kaio streams in two ways that a default proxy configuration breaks:
- Server-sent events for the dashboard feed and for logs, on
/api/events,/api/containers/{id}/logsand/api/stacks/{name}/logs; - WebSocket for the in-container shell, on
/api/containers/{id}/shell.
The failure is silent. The page loads, the tables fill, and then logs never arrive and the terminal never opens.
location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
proxy_buffering off; proxy_cache off; proxy_read_timeout 1h;}With this map at the http level, so that Connection is only set to upgrade
for requests that ask for it:
map $http_upgrade $connection_upgrade { default upgrade; '' close;}proxy_buffering off is the one that matters for logs: with buffering on, nginx
holds the event stream until a buffer fills, so lines arrive in bursts or not at
all. proxy_read_timeout has to outlive an idle stream, otherwise a quiet
container drops its log view after 60 seconds.
kaio.example.com { reverse_proxy 127.0.0.1:8080 { flush_interval -1 }}Caddy upgrades WebSocket connections on its own. flush_interval -1 disables
response buffering, which is what the event streams need.
Traefik
Section titled “Traefik”labels: - "traefik.http.routers.kaio.rule=Host(`kaio.example.com`)" - "traefik.http.services.kaio.loadbalancer.server.port=8080" - "traefik.http.services.kaio.loadbalancer.responseforwarding.flushinterval=-1"Traefik handles the WebSocket upgrade itself. flushinterval=-1 flushes
immediately, again for the event streams.
Add authentication while you are there
Section titled “Add authentication while you are there”The application has none. A proxy is the natural place to put it, and the reason the port should not be reachable without one. See Security.
auth_basic "Kaio";auth_basic_user_file /etc/nginx/.htpasswd;Basic auth is the floor, not the goal. Anything that terminates a session works, as long as the port itself is never exposed directly.
Checking it works
Section titled “Checking it works”curl -N -H "Accept: text/event-stream" https://kaio.example.com/api/eventsEvents should appear as they happen. If the command hangs with nothing, or if lines arrive in blocks after a delay, response buffering is still on somewhere.
Kaio, built by Régis Gaidot