Skip to main content
This guide covers connecting devices to your Headscale server using Tailscale clients on various platforms.

Prerequisites

Before connecting any device, you need:
  1. A running Headscale server
  2. A user created in Headscale
  3. A pre-auth key for authentication

Generate a Pre-Auth Key

1

Create a user (if you haven't already)

docker exec headscale headscale users create myuser
Or use the helper script:
./scripts/headscale.sh users create myuser
2

Generate a pre-auth key

docker exec headscale headscale preauthkeys create --user myuser --reusable --expiration 24h
Save this key securely - you’ll need it to connect each device. Use --reusable for connecting multiple devices with the same key.

Linux

1

Navigate to configuration directory

cd tailscale-configs/linux-systemd
2

Run the setup script

sudo bash setup.sh
The script will prompt you for:
  • Headscale server URL (e.g., http://localhost:8000)
  • Pre-auth key
  • Whether to accept routes from other nodes
  • Whether to advertise as an exit node
  • Routes to advertise (if any)
3

Verify connection

tailscale status
tailscale ip

Manual Setup

1

Install Tailscale

curl -fsSL https://tailscale.com/install.sh | sh
2

Connect to Headscale

sudo tailscale up --login-server http://localhost:8000 --authkey YOUR_KEY --accept-routes
3

Check status

tailscale status

macOS

Using GUI Application

1

Download and install Tailscale

Download from tailscale.com/download/mac and install the DMG package.
2

Configure custom server

  1. Open Tailscale from menu bar
  2. Click Preferences
  3. Go to Advanced tab
  4. Under “Login Server”, enter: http://localhost:8000
  5. Click Save
3

Connect with pre-auth key

  1. Click Connect in the main menu
  2. Browser opens - paste your pre-auth key
  3. Click Authenticate

Using Terminal

sudo /Applications/Tailscale.app/Contents/MacOS/Tailscale up \
  --login-server=http://localhost:8000 \
  --authkey=YOUR_PREAUTH_KEY \
  --accept-routes

Windows

Using GUI Application

1

Download and install Tailscale

Download the MSI installer from tailscale.com/download/windows and install it.
2

Configure custom server

  1. Open Tailscale app from Start menu
  2. Click Settings (gear icon)
  3. Go to Admin Console
  4. Click Use a Custom Login Server
  5. Enter: http://YOUR_SERVER_IP:8000
  6. Click Connect
3

Authenticate

  1. Browser window opens
  2. Paste your pre-auth key
  3. Click Authenticate

Using PowerShell (as Administrator)

tailscale up --login-server http://localhost:8000 --authkey YOUR_KEY --accept-routes

Mobile Devices

iOS

1

Install Tailscale

Download Tailscale from the App Store.
2

Configure alternative server

  1. Open the app
  2. Tap Settings (gear icon)
  3. Scroll to Use Alternative Coordination Server
  4. Toggle ON
  5. Enter your server URL: http://YOUR_SERVER_IP:8000
  6. Tap Save
Use your computer’s IP address or public domain, not localhost (which won’t work from your phone).
3

Connect

  1. Go back and tap Connect
  2. Browser opens
  3. Paste your pre-auth key
  4. Tap Authenticate

Android

1

Install Tailscale

Download Tailscale from Google Play Store.
2

Configure server URL

  1. Open the app
  2. Tap (three dots menu)
  3. Select Settings
  4. Tap Server URL
  5. Enter: http://YOUR_SERVER_IP:8000
  6. Tap OK
3

Connect

  1. Go back and tap Connect
  2. Browser opens
  3. Paste pre-auth key
  4. Tap Authenticate

Docker Containers

Sidecar Pattern

Connect a Docker container to your Tailscale network using the sidecar pattern:
docker-compose.yml
services:
  myapp:
    image: myapp:latest
    network_mode: "service:tailscale"
    depends_on:
      - tailscale

  tailscale:
    image: tailscale/tailscale:latest
    hostname: myapp-container
    environment:
      - TS_AUTHKEY=YOUR_PREAUTH_KEY
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_LOGIN_SERVER=http://host.docker.internal:8000
      - TS_ACCEPT_ROUTES=true
    volumes:
      - tailscale-data:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    restart: unless-stopped

volumes:
  tailscale-data:
1

Create .env file with your key

echo "TS_AUTHKEY=your-preauth-key-here" > .env
2

Start the stack

docker compose up -d
3

Verify connection

docker exec myapp-tailscale tailscale status

Verification

After connecting any device, verify the connection:
tailscale status

Verify in Headplane GUI

  1. Open http://localhost:3001/admin/
  2. Go to Nodes page
  3. Your device should appear in the list with:
    • Hostname
    • IP addresses
    • Online status
    • Last seen timestamp

Connection Options

Common Parameters

ParameterDescriptionExample
--login-serverYour Headscale server URLhttp://localhost:8000
--authkeyPre-auth key from HeadscaleYOUR_PREAUTH_KEY
--accept-routesAccept subnet routes from other nodes(flag, no value)
--advertise-routesShare local networks192.168.1.0/24,10.0.0.0/24
--advertise-exit-nodeBecome an exit node(flag, no value)
--hostnameCustom hostnamemy-device
--advertise-tagsApply ACL tagstag:personal,tag:servers
--sshEnable Tailscale SSH(flag, no value)

Example Configurations

sudo tailscale up \
  --login-server=http://localhost:8000 \
  --authkey=YOUR_KEY \
  --accept-routes \
  --hostname=my-laptop
Accept routes from other nodes to access shared networks.

Troubleshooting

Unable to Connect

1

Verify Headscale is running

curl http://localhost:8000/health
# Should return: {"status":"pass"}
2

Check pre-auth key validity

docker exec headscale headscale preauthkeys list --user myuser
Ensure the key hasn’t expired.
3

Check Tailscale logs

journalctl -u tailscaled -f

Reset Connection

If you need to reset and reconnect:
# Disconnect
sudo tailscale down

# Clear state (optional)
sudo rm -rf /var/lib/tailscale/*

# Reconnect with new key
sudo tailscale up --login-server=http://localhost:8000 --authkey=NEW_KEY

Mobile Connection Issues

When connecting from mobile devices, you must use your server’s actual IP address or domain name, not localhost.
Find your server’s IP:
# Linux/macOS
ip addr show | grep inet

# Or get external IP
curl ifconfig.me

Security Best Practices

  • Use short-lived keys: Set expiration to 24h for testing, 1h for production
  • Use single-use keys: Remove --reusable when possible
  • Apply ACL tags: Organize devices with --advertise-tags=tag:personal
  • Never commit auth keys: Add .env files to .gitignore
  • Use ephemeral nodes: Add --ephemeral for temporary devices
  • Rotate keys regularly: Generate new keys and reconnect devices periodically

Next Steps

Build docs developers (and LLMs) love