Files
studio/services/admin/docs/TAILSCALE-PRODUCTION.md
ozan a81a450e7e feat: monorepo consolidation — merge CLI, bot, admin, team-tool, website, docs, runner, proxy
Merged into tinqs/studio:
- cmd/tinqs-cli/    — tinqs-cli (Go binary, from bot/cli)
- cmd/tea/          — Gitea CLI tool (from tinqs/cli-tea)
- services/bot/     — Bot service (from tinqs-ltd/bot on git.arikigame.com)
- services/admin/   — Admin panel (from tinqs/admin)
- services/team-tool/ — Team Tool (from tinqs/team-tool)
- services/proxy/   — tinqs-proxy (from bot/proxy)
- web/landing/      — tinqs.com website (from tinqs/website)
- web/docs/         — Platform docs (from tinqs/docs)
- web/blog/         — Blog (placeholder)
- runner/           — Ephemeral CI runner (from tinqs/runner)

All source repos will be deleted after verification.
2026-05-22 04:55:50 +00:00

3.8 KiB

Production on Tailscale (no Caddy)

Tailscale already encrypts traffic (WireGuard). You do not need a second reverse proxy like Caddy for TLS on the tailnet unless you want public internet on port 443 or fancy hostname routing.

What we use instead

Need How
Encryption Tailscale mesh (always on for tailnet paths)
HTTPS + identity headers tailscale serve https / http://127.0.0.1:8088 on the app host (MagicDNS URL), or
Custom hostname (admin.arikigame.com) + no Serve Split DNS → 100.x → app on :8088; set TAILSCALE_WHOIS_PROXY_URL so Next.js resolves the client with tailscale whois --json (see below)
Git + Git Studio web Gitea built-in HTTPS + ACME on :443 (https://git.arikigame.com). No Caddy.
Admin UI tailscale servehttp://127.0.0.1:8088 gives HTTPS on the machine MagicDNS name (identity headers). Or http://<tailnet-ip>:8088 / http://admin.arikigame.com:8088 (split DNS) + TAILSCALE_WHOIS_PROXY_URL (whois). Do not use https://admin.arikigame.com/ on :443 — that socket is Gitea only (cert is for git.arikigame.com).

Why Caddy was optional

Caddy was only there to: terminate public TLS, route admin.* vs git.* on :443, and serve a static page for non-tailnet clients. None of that is required if everyone uses the tailnet and you are fine with Tailscale Serve or direct 100.x + whois proxy.

  1. On the host (not inside Docker), install Node or use node from apt.

  2. Run scripts/tailscale-whois-proxy.mjs under systemd (example below).

  3. In /mnt/gitea-data/admin-app/.env (or compose env):

    TAILSCALE_WHOIS_PROXY_URL=http://host.docker.internal:39139
    
  4. Rebuild/restart the app container.

The proxy listens on 0.0.0.0:39139 — restrict with firewall to localhost + Docker bridge only.

Example systemd unit

/etc/systemd/system/tailscale-whois-proxy.service:

[Unit]
Description=Tailscale whois proxy for admin.arikigame
After=network.target tailscaled.service

[Service]
Type=simple
ExecStart=/usr/bin/node /mnt/gitea-data/admin-app/scripts/tailscale-whois-proxy.mjs
Environment=TAILSCALE_WHOIS_PROXY_PORT=39139
Environment=TAILSCALE_WHOIS_PROXY_HOST=0.0.0.0
Restart=always
User=ubuntu
WorkingDirectory=/mnt/gitea-data/admin-app

[Install]
WantedBy=multi-user.target

Then: sudo systemctl enable --now tailscale-whois-proxy

Removing Caddy on Lightsail (operator) — done on v2

  1. Gitea: [server] PROTOCOL=https, HTTP_PORT=443, ENABLE_ACME=true, setcap cap_net_bind_service=+ep on gitea binary, cert paths under /var/lib/gitea/data/acme/.
  2. sudo systemctl stop caddy && sudo systemctl disable caddy
  3. Admin: sudo tailscale serve --bg http://127.0.0.1:8088 (MagicDNS HTTPS to Next.js).
  4. Admin app .env: TAILSCALE_WHOIS_PROXY_URL=http://host.docker.internal:39139, GITEA_URL=https://git.arikigame.com
  5. Docker publishes 8088:8088 so tailnet clients can hit :8088 on the host IP when not using Serve.

“Connect Tailscale” help page (no Caddy)

The repo docs/setup/tailscale-required.html explains installation for users not yet on the tailnet. You do not need Caddy to serve it:

  • Best: Do not expose admin.arikigame.com on the public internet — split DNS / tailnet-only so only enrolled devices resolve the name.
  • If you need a public URL with instructions only: host that HTML on the gateway, static hosting, or a minimal web server — see devops/tailscale/company-tailnet.md in the tinqs-ltd/docs repository.

Stable devices: laptops join via Google SSO; servers can use pre-auth keys and a fixed --hostname so nodes add themselves predictably — same doc.