# Setup recipe: Tailscale

> A ready-made first-boot script that installs Tailscale from its own repository and can join the server to your tailnet with a one-off auth key.

Source: https://vpsnine.com/help/tailscale-setup-script · Updated: 2026-10-21

This is a [setup script](https://vpsnine.com/help/setup-scripts) that installs [Tailscale](https://tailscale.com) on a new server's first boot, using Tailscale's own install script and package repository, and starts it at boot. It works on Ubuntu, Debian, AlmaLinux, Rocky Linux and Fedora.

With Tailscale on the server, you can reach it, and services you keep off the public internet, from your other devices over your private tailnet.

## The auth key

Leave `TS_AUTHKEY` empty and the server installs Tailscale but doesn't join anything. Log in afterwards, run `sudo tailscale up`, and open the link it prints.

To have it join by itself, make an auth key in Tailscale's admin console under **Settings > Keys** and put it in `TS_AUTHKEY` before ordering. The script is copied onto the server's disk to run (see [keep secrets out of it](https://vpsnine.com/help/setup-scripts#keep-secrets-out-of-it)), so use a key that is **not reusable**, ideally **ephemeral** or with a short expiry. Once the server has joined, the key has done its job.

## Deploy it

[Deploy with VPSNine](https://my.vpsnine.com/servers/new?recipe=tailscale): this opens the order form with the script in the setup script field (you log in first). Add your key to `TS_AUTHKEY` there if you want one, then order.

With the CLI:

```bash
vps9 servers create --plan budget --image debian-13 --hostname vpn-1 --key key_… --setup-script ./tailscale.sh
```

## The script

```bash
#!/bin/bash
# VPSNine setup recipe: Tailscale
# https://vpsnine.com/help/tailscale-setup-script
# Tailscale from its own repository, started at boot, and joined to your tailnet if you give it
# an auth key.
set -euo pipefail
umask 022

# ---- settings: change these before you run it ----
# An auth key from https://login.tailscale.com/admin/settings/keys joins the server by itself. Leave it
# empty to join by hand afterwards (run: tailscale up). The script is stored on the server, so use a
# one-off or ephemeral key, never a reusable one.
TS_AUTHKEY=""

# Which family of distributions this is: Debian and Ubuntu, or AlmaLinux, Rocky Linux and Fedora.
. /etc/os-release
case " ${ID:-} ${ID_LIKE:-} " in
  *" debian "*|*" ubuntu "*) family=debian ;;
  *" rhel "*|*" fedora "*|*" centos "*) family=rhel ;;
  *) echo "This recipe supports Ubuntu, Debian, AlmaLinux, Rocky Linux and Fedora, not ${PRETTY_NAME:-this system}" >&2; exit 1 ;;
esac

echo "== Installing Tailscale"
if [ "$family" = debian ]; then
export DEBIAN_FRONTEND=noninteractive
apt-get -o DPkg::Lock::Timeout=300 update
apt-get -o DPkg::Lock::Timeout=300 install -y ca-certificates curl
command -v tailscale >/dev/null 2>&1 || curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
else
command -v tailscale >/dev/null 2>&1 || curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
fi

if [ -n "$TS_AUTHKEY" ]; then
  echo "== Joining the tailnet"
  tailscale up --auth-key="$TS_AUTHKEY"
  tailscale ip -4 || true
else
  echo "== Installed. To join your tailnet, log in and run: tailscale up"
fi
echo "== Done"
```

## Check the result

```bash
tail -n 20 /var/log/vps9-setup.log
tailscale status
tailscale ip -4
```

The address `tailscale ip -4` prints starts with `100.` and only your tailnet can reach it. To keep SSH off the public internet once Tailscale works, allow port 22 only from the tailnet in the [server firewall](https://vpsnine.com/help/server-firewall), and keep the [serial console](https://vpsnine.com/help/serial-console) in mind as the way back in if you lock yourself out.
