← Về thư mục
📄 / / proc / 45 / cwd / root / .hermes / skills-backup-20260914-152439 / devops / kanban-browser-proxy / SKILL.md

name: kanban-browser-proxy description: Pattern for deploying local services via Nginx proxy + Tailscale Funnel.


kanban-browser-proxy

A pattern for deploying local services (Kanban server, file browser) to be accessible via Tailscale Funnel while bypassing Host header restrictions in protected services (like the Hermes Dashboard).

Workflow: Nginx as Central Proxy

To expose internal services (port 9119, 9120) over a single Tailscale tunnel without "Invalid Host header" errors, use Nginx as a central gateway.

1. Nginx Proxy Configuration (/etc/nginx/sites-available/hermes-dashboard)

Inject a central proxy that routes different paths to different internal ports.

server {
    listen 127.0.0.1:9121;
    server_name localhost;

    # Routes to custom tools
    location /kanban-os/ {
        proxy_pass http://127.0.0.1:9120/;
        proxy_set_header Host $host;
        ...
    }

    # Dashboard with Host header rewrite to bypass security
    location / {
        proxy_pass http://127.0.0.1:9119;
        proxy_set_header Host "127.0.0.1:9119";
        ...
    }
}

2. Tailscale Tunnel Setup

Only expose the Nginx port (9121) to the public tunnel, never the raw service ports (9119/9120).

tailscale serve reset
tailscale funnel --bg 9121

Pitfalls

Root URL Diagnostic Procedure

When the Tailscale Funnel root URL (https://<tailnode>.ts.net/) returns an error:

  1. Test each layer independently: bash curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:9121/ # via Nginx curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:9119/ # direct Hermes Dashboard curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:9120/ # Kanban server

  2. Check what Nginx proxies root / to in /etc/nginx/sites-available/hermes-dashboard: nginx location / { proxy_pass http://127.0.0.1:9119; # MUST be 9119 }

  3. 502 Bad Gateway → Nginx proxy target has no listener. Common causes: Hermes Dashboard not started, or raw kanban server port (9120) vs Hermes Dashboard port (9119) are confused.
  4. 401 / login page → Nginx is pointing to an auth-gated service (custom Dashboard on port 20129) instead of the Hermes Dashboard on 9119. The Hermes Dashboard bound to 127.0.0.1 does not require auth when accessed through Nginx on the same machine.

  5. Ensure Hermes Dashboard is running on port 9119: bash hermes dashboard --status # check if running hermes dashboard --port 9119 --host 127.0.0.1 --no-open --skip-build # start The --skip-build flag avoids the npm build step (useful for non-interactive contexts). Never start the dashboard with nohup — use terminal(background=true) so Hermes can track lifecycle.

  6. Verify Tailscale Funnel routes to Nginx: bash tailscale funnel status # should show / → http://127.0.0.1:9121 The Funnel MUST point to the Nginx port (9121), never directly to individual service ports.

  7. What NOT to do (lessons from production):

  8. Do NOT point root / to the kanban server (port 9120) — user expects Hermes Dashboard functionality.
  9. Do NOT point root / to the custom auth dashboard (port 20129) — user expects no-login access.
  10. Do NOT apply a second sed fix without reading the current config first — after one fix the old port string is already changed and subsequent sed targeting the old port silently does nothing.
  11. Always read the Nginx config file and verify with curl after every change. Don't assume a sed took effect.