Join a tailnet from the router#
You will end up with the router as a node on your tailnet, advertising the LAN as a subnet route, so every device behind it is reachable from your other Tailscale machines without a client on each one. That is what earns Tailscale a place on a router specifically.
Tailscale here is a catalogue app — a container declared in the configuration tree — not a native feature. It installs, diffs, commits and rolls back like any other app.
Before you start#
- The operator role and a licence.
- A Tailscale account and an auth key from its admin console.
- Container support on the router, and a route to Docker Hub to pull the image.
- The LAN prefix you will advertise.
Step 1 — Install it#
Services → Apps → Tailscale. The install is three steps, and only the third is configuration:
- Directories — the volume source
/config/apps/tailscaleis created withmkdir -p. This only works when the agent runs on the router; off-router it hands you the command instead of pretending to have run it. - Pull the image —
add container image docker.io/tailscale/tailscale:latest. - Stage the install — the
set container name …lines, into the Commit Bar.
set container name tailscale image docker.io/tailscale/tailscale:latest
set container name tailscale allow-host-networks
set container name tailscale capability net-admin
set container name tailscale capability net-raw
set container name tailscale capability sys-module
set container name tailscale volume state source /config/apps/tailscale
set container name tailscale volume state destination /var/lib/tailscale
set container name tailscale environment TS_AUTHKEY value <the auth key>
set container name tailscale environment TS_ROUTES value 192.0.2.0/24
set container name tailscale environment TS_STATE_DIR value /var/lib/tailscaleStep 2 — Set the environment variables#
The catalogue entry declares five, and the install panel shows each with its description:
| Variable | What it does |
|---|---|
TS_AUTHKEY | The auth key from the admin console. Marked required and secret, with no default. |
TS_HOSTNAME | The node name in the tailnet. Defaults to the container's host name. |
TS_ROUTES | Subnets to advertise, comma separated — for example 192.0.2.0/24. Routes still need approval in the admin console. |
TS_STATE_DIR | /var/lib/tailscale, matching the volume. With the state volume in place the auth key is only needed once. |
TS_EXTRA_ARGS | Extra tailscale up flags — for example --advertise-exit-node. |
The state volume is what makes the auth key a one-time thing: the node's identity persists
across restarts and across an image upgrade, because /config is the persistent partition.
Step 3 — Approve the routes#
Approve them in the Tailscale admin console, on the machine's route settings.
Step 4 — Commit#
Read the diff. This is a privileged host-network container, which is worth a second look before it runs.
Check it worked#
The container is running and healthy. Apps → Installed shows declared beside running, with the health probe's verdict. The app's own detail page has its logs.
show containerThe node is on the tailnet. In the Tailscale admin console, or from the container:
sudo podman exec tailscale tailscale statusThe LAN is reachable from another tailnet machine.
ping -c 3 192.0.2.10If the node is online and the LAN is not reachable, it is step 3.
Restarting and updating it#
Check for update re-pulls the image and compares the local image ID before and after. The answer is either already current or a newer image is on the router but the running container still holds the old one — restart to pick it up. A pull is not an upgrade and the page does not pretend it is.
Restart is a two-commit bounce — commit disable, then commit its deletion — because
that is the only restart the VyOS API can express. Both commits are audited.
Undoing it#
Uninstall deletes the whole container name tailscale subtree.
delete container name tailscaleThe volume under /config/apps/tailscale is deliberately not removed, so a reinstall
picks up the same node identity. Remove the machine from the tailnet in the admin console
as well — an uninstalled container is not a revoked node.
See also#
- Install an app — the general procedure
- Stop, uninstall, and what stays behind
- A WireGuard tunnel for a laptop — the same job without a third-party coordination server
- Apps — catalogue
Checked against agent/catalog.json ·
agent/catalog.go ·
agent/apps.go ·
docs/apps.md