Tailscale on Docker Alpine

Status: πŸ”΄ Blocked β€” ISP blocking Tailscale control plane
Started: 2026-05-11
Goal: Persistent Tailscale node running in Docker on dev machine


Progress log

2026-05-11 – 2026-05-12

  • Built Alpine + Tailscale Docker Compose setup βœ…
  • State volume configured (survives reboots) βœ…
  • tailscaled starts, attempts login, fails every ~5s
  • Diagnosed: controlplane.tailscale.com (192.200.0.0/24) TLS timeout
  • Internet works from container (curl google.com β†’ 301) βœ…
  • DNS resolves Tailscale IPs βœ…
  • IPv6 unreachable (Network unreachable) β€” but IPv4 also blocked

Conclusion: ISP-level blocking of Tailscale’s IP range. Not a config problem.


Working Docker setup (pending network fix)

docker-compose.yml:

services:
  tailscale:
    build: .
    container_name: tailscale
    network_mode: host
    env_file: .env
    volumes:
      - tailscale-state:/var/lib/tailscale
      - tailscale-run:/var/run/tailscale
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun:/dev/net/tun
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "tailscale", "status"]
      interval: 30s
      retries: 3
 
volumes:
  tailscale-state:
  tailscale-run:

Dockerfile:

FROM alpine:latest
RUN apk add --no-cache tailscale iproute2 curl
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh:

#!/bin/sh
set -e
mkdir -p /var/run/tailscale
tailscaled --state=/var/lib/tailscale/tailscaled.state \
           --socket=/var/run/tailscale/tailscaled.sock &
TAILSCALED_PID=$!
for i in $(seq 1 30); do
  tailscale status > /dev/null 2>&1 && break
  sleep 1
done
tailscale up --authkey=${TS_AUTHKEY} --hostname=${TS_HOSTNAME:-alpine-docker}
tailscale status
wait $TAILSCALED_PID

.env:

TS_AUTHKEY=tskey-auth-xxxxx   # from tailscale.com/admin/settings/keys
TS_HOSTNAME=my-dev-node

Open tasks

  • Test on mobile hotspot β€” confirm ISP is the blocker
  • If confirmed ISP: try routing through a VPN first, then Tailscale
  • Alternative: use Headscale (self-hosted control plane) to bypass ISP blocking
  • Check if --login-server flag allows alternate control plane

Useful commands

docker compose up -d --build
docker compose exec tailscale tailscale status
docker compose exec tailscale tailscale ip
docker compose logs -f tailscale