Files
automations/deployments/headscale

headscale

Headscale — a self-hosted Tailscale control server — behind Caddy, with OIDC login delegated to pocket-id.

Prerequisite

Register an OIDC client in pocket-id's admin UI with redirect URI:

https://${HEADSCALE_DOMAIN}/oidc/callback

Then paste its OIDC_CLIENT_ID / OIDC_CLIENT_SECRET below.

Required .env values

Variable Notes
HEADSCALE_DOMAIN Public hostname (e.g. hs.example.com). Clients connect here over HTTPS.
ACME_EMAIL Let's Encrypt registration email.
TAILNET_DOMAIN MagicDNS suffix (e.g. tail.example.com). Must differ from HEADSCALE_DOMAIN.
POCKETID_DOMAIN OIDC issuer hostname (your pocket-id).
OIDC_CLIENT_ID / OIDC_CLIENT_SECRET From the pocket-id client above.

The deploy substitutes these into config.yaml from the embedded template. See .env.example.

Deploy

./automations.sh        # Deploy on this host → deploy: headscale

Or build + run the self-contained artifact:

./build.sh
scp deploy.sh root@host:
ssh root@host 'bash deploy.sh'
# non-interactive: pass HEADSCALE_DOMAIN, ACME_EMAIL, TAILNET_DOMAIN,
#   POCKETID_DOMAIN, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, SKIP_PROMPTS=1

Unattended provisioning: cloud-init.yml.

DNS for HEADSCALE_DOMAIN must resolve to the host and 80/443 be reachable before deploy.