# Running Tailscale with Docker Tailscale provides a simple and secure way to connect servers and services using a **mesh VPN**, without exposing ports or managing complex firewall rules. In this post, I’ll walk through running **Tailscale as a Docker container** using the **host network**, allowing the server itself to join the Tailscale network with minimal configuration. The focus is on a setup that is: - Simple and reproducible - Restart-safe - Suitable for production environments The full script is provided at the end. --- ## What are we trying to achieve? The goal of this setup is to: - Join a server to a Tailscale network - Avoid manual Tailscale installation on the host - Keep the setup containerized and easy to manage - Allow Tailscale to operate at the **host network level** This is especially useful for servers, VMs, or bare-metal machines. --- ## General approach In this setup: - The official `tailscale/tailscale` Docker image is used - The container runs on the **host network** - Required Linux capabilities are explicitly granted - Authentication is handled via a **Tailscale auth key** - No configuration files are required This keeps the container **stateless** and easy to recreate. --- ## Prerequisites Before starting, make sure that: - Docker is installed on the server - You have a Tailscale account - You have generated a valid **Auth Key** from the Tailscale admin panel > Auth keys can be created under **Tailscale Admin → Keys**. --- ## Step 1: Running Bash in safe mode The script starts by enabling strict Bash settings: - Exit immediately on errors - Fail on undefined variables - Catch errors in pipelines This prevents silent failures and is considered a best practice for production scripts. --- ## Step 2: Defining base variables The script defines the following core variables: | Variable | Description | |-----------------|-----------------------------------------------------------| | `CONTAINER` | Container name, used for easier management and debugging | | `IMAGE` | Docker image pinned to a specific version for reproducibility | | `AUTH_KEY` | Authentication key used to join the Tailscale network | > In real environments, the auth key should be stored as a secret > (e.g. `.env`, Docker secrets, CI/CD secrets). --- ## Step 3: Using the host network The container is started with `--network host`. This allows: - Tailscale to use the host’s network stack directly - VPN interfaces to be created at the host level - No additional port mapping or routing configuration This mode is ideal for VPN-style workloads like Tailscale. --- ## Step 4: Granting required Linux capabilities Tailscale requires specific capabilities to function correctly: - `NET_ADMIN` – to manage network interfaces and routing - `SYS_MODULE` – to interact with kernel modules when needed Without these, the Tailscale daemon will not be able to establish connectivity. --- ## Full Bash script (copy & paste) Below is the complete script containing all the steps described above: ```bash #!/usr/bin/env bash set -euo pipefail # ============================================================ # Tailscale setup script (bash) # # This script: # - starts a Tailscale container using the host network # - joins the server to a Tailscale network # ============================================================ # ------------------------------------------------------------ # 0) Base variables # ------------------------------------------------------------ CONTAINER="tailscale" IMAGE="tailscale/tailscale:v1.90.9" TS_AUTHKEY="tskey-XXXX" # replace with your real auth key # ------------------------------------------------------------ # 1) Start Tailscale container # ------------------------------------------------------------ docker run -d \ --name "$CONTAINER" \ --network host \ --cap-add NET_ADMIN \ --cap-add SYS_MODULE \ -e TS_AUTHKEY="$TS_AUTHKEY" \ "$IMAGE"