Skip to Content

Tailscale Private Networking

Tailscale  provides a private mesh VPN that lets you access your Companion Hub apps from anywhere — without exposing them to the public internet.

When to Use Tailscale

Tailscale is ideal when:

  • You want private access to your apps from your devices only
  • You don’t want apps publicly accessible on the internet
  • You need to connect multiple machines in a private network
  • You want to access your Hub from anywhere securely

Benefits

Access from Anywhere — Securely reach your Hub from any location
Connect All Devices — Link Windows, Mac, Linux, iOS, and Android devices
Zero Configuration — Automatic NAT traversal, no port forwarding needed
Enterprise Security — End-to-end encryption for all traffic
Free for Personal Use — Tailscale offers a free Personal plan

Setup Options

Companion Hub offers two ways to use Tailscale:

The easiest way — Companion Hub includes a built-in Tailscale container that connects your Hub to your Tailscale network.

Enable During Onboarding

When you first set up your Hub, the onboarding wizard includes a Private VPN step:

  1. Click Log In with Tailscale
  2. Authenticate in the popup window (create a free account if needed)
  3. Your Hub automatically joins your Tailscale network
  4. Continue with the wizard

The onboarding wizard polls connection status in real-time, so you’ll see when your Hub connects successfully.

Enable in Settings

If you skipped Tailscale during onboarding, you can set it up later:

  1. Go to Settings → Network
  2. Find the Private VPN section
  3. Click Log In with Tailscale
  4. Authenticate in the popup window
Network Settings with Private VPN sectionNetwork Settings with Private VPN section

Access Your Hub

Once connected, your Hub gets a Tailscale IP address (e.g., 100.x.y.z). You can see it in Settings → Network.

Install Tailscale on your other devices:

  • Download from tailscale.com/download 
  • Join the same tailnet (use the same sign-in identity or an invited account)
  • Access your Hub via its Tailscale IP or hostname

Option 2: Host Installation

For advanced users with a custom Compose override, Hub can use a Tailscale daemon installed directly on the host. The built-in sidecar is simpler and is the supported default.

Install Tailscale on Host

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

Mount the Socket

Bind-mount the host’s /var/run/tailscale/tailscaled.sock into the ci-os-hub container at the same path and ensure the Hub container user can read and write the socket. This mount is not included in the stock Compose configuration. Hub detects the host client only after the socket is available inside the container.

Access Your Hub

Open the Hub dashboard at http://<tailscale-ip>:5002. Apps still need their own Hub exposure setting; use Private VPN for the managed HTTPS links described below.

Accessing Apps over Private VPN

When you enable Private VPN for an individual app (App → Settings → set exposure to Private VPNSave), the Hub automatically publishes that app on your Tailscale node using Tailscale Serve . Each app gets its own HTTPS port on your Hub’s Tailscale hostname:

https://<your-hub>.<tailnet>.ts.net:<app-port>

For example, a code-server app on port 8138 becomes:

https://hub-tailscale.tail-scale.ts.net:8138

The Hub creates and removes these mappings for you whenever you toggle Private VPN, start/stop the app, or change its configuration — no manual tailscale serve commands required.

One-time setup: approve Tailscale Serve prerequisites for your Hub node. Private VPN publishing uses Tailscale Serve , which requires HTTPS certificates for the tailnet. If they are not enabled when you pick Private VPN, the Hub shows an inline warning in the app’s exposure settings and a toast with the direct Enable Tailscale Serve link for your node.

Approve Tailscale Serve prerequisites

Tailscale Serve’s prerequisites must be approved before Private VPN app links work. When HTTPS is not enabled yet, the Hub toast includes a node-specific consent link. You can also confirm from the CLI on your Hub:

docker exec hub-tailscale tailscale serve status

If Serve is not enabled, Tailscale prints a link like https://login.tailscale.com/f/serve?node=.... Open that URL (tailnet admin required) and approve the requested tailnet settings:

Enable Tailscale Serve

The button opens Tailscale’s Serve consent flow. If you already have a node-specific link from the Hub toast or CLI output, use that instead — it skips straight to the right node.

Enable HTTPS & MagicDNS (if still needed)

Tailscale Serve also needs HTTPS Certificates and MagicDNS on your tailnet. The Serve approval flow usually enables these for you; if Private VPN still fails afterward, turn them on manually on the DNS page:

Enable HTTPS in Tailscale

Enabling HTTPS allows Tailscale to provision certificates for your tailnet’s *.ts.net names. Tailscale’s consent screen explains that machine and tailnet names are recorded in public certificate-transparency logs. This only needs to be enabled once by a tailnet owner or admin.

Re-trigger the Hub sync

After enabling Serve (and HTTPS if needed), toggle the app’s Private VPN setting off and back on (or restart the app) so the Hub re-creates the serve mapping. The app link will then resolve.

You’ll find the generated https://<your-hub>.<tailnet>.ts.net:<port> URL on the app’s page. Make sure the device you’re browsing from is connected to the same tailnet.

Next: Follow the agent mobile apps guide to install OpenClaw on iOS or Android, pair it with CI-OpenClaw, or open CI-Hermes securely from an iPhone.

How It Works

  1. Mesh Network — Tailscale creates a peer-to-peer mesh between all your devices
  2. NAT Traversal — Works behind firewalls and routers without configuration
  3. Private IPs — Each device gets a private IP (100.x.y.z range)
  4. Encrypted — All traffic is encrypted end-to-end using WireGuard

Troubleshooting

Sidecar Not Available

If you see “Tailscale sidecar container is not running”:

  1. Ensure the private-vpn profile is enabled:

    docker compose --profile private-vpn up -d
  2. Or use the Hub CLI (Tailscale sidecar is enabled by default):

    cihub up --detached cihub status # shows Tailscale IP when connected
  3. Check that the hub-tailscale container is running:

    docker ps | grep hub-tailscale

Connection Not Working

If the login button doesn’t connect:

  1. Complete the authentication in the popup window
  2. Wait 5-10 seconds for the connection to establish
  3. Refresh the Settings page to see updated status

Can’t Access Hub from Other Devices

  1. Verify Tailscale is running on both devices:

    tailscale status
  2. Ensure both devices show “Running” in Tailscale

  3. Try accessing by IP first: http://100.x.y.z:5002 (find IP in Settings → Network)

  4. Try accessing by hostname: http://your-hub-name:5002

If an app has Private VPN enabled but its https://<hub>.<tailnet>.ts.net:<port> link doesn’t load, Tailscale Serve’s HTTPS prerequisites may not be enabled for your tailnet yet. The Hub detects this and tells you, so you don’t have to guess:

  • A toast appears — “Couldn’t publish <app> over Private VPN: HTTPS is not enabled on your tailnet” — with an Enable Tailscale Serve link for your node.
  • The app’s exposure settings show an inline warning the moment you choose Private VPN.

You can also confirm from the CLI on your Hub:

docker exec hub-tailscale tailscale serve status

When Serve isn’t enabled, Tailscale prints:

Serve is not enabled on your tailnet. To enable, visit: https://login.tailscale.com/f/serve?node=...

Open that node-specific link (or use the one from the Hub toast) and approve Serve for your Hub:

Enable Tailscale Serve

If the consent flow is already complete but links still fail, enable HTTPS Certificates and MagicDNS on your tailnet:

Enable HTTPS in Tailscale

Then toggle the app’s Private VPN setting off and on (or restart the app) so the Hub re-creates the serve mapping. See Accessing Apps over Private VPN for details.

Advanced Configuration

Custom Routes

By default, the sidecar advertises the Docker bridge network (172.18.0.0/16). This is separate from Hub-managed Tailscale Serve links and is only needed when you want tailnet clients to route directly to container addresses. Tailscale may require a tailnet admin to approve the advertised subnet route.

To customize this, set HUB_TAILSCALE_EXTRA_ARGS in your .env file:

HUB_TAILSCALE_EXTRA_ARGS=--accept-routes --advertise-routes=172.18.0.0/16,192.168.1.0/24

Pre-Auth Keys (Automated Setup)

For headless or automated deployments, you can use a pre-authentication key instead of browser login:

  1. Generate a key at login.tailscale.com/admin/settings/keys 
  2. Add it to your .env file:
    TAILSCALE_AUTHKEY=tskey-auth-...
  3. The sidecar will automatically connect on startup

Pre-auth keys should be kept secret and rotated regularly. Prefer browser login for interactive setups so you do not need to store a reusable key.

Comparison with Cloudflare

FeatureTailscaleCloudflare
PrivacyPrivate mesh, no public exposurePublic URLs (can be secured with Access)
SetupOne-click browser loginRequires CI Account registration
Device RequirementTailscale client on each deviceAny browser works
Use CasePersonal, private accessSharing with others, public apps
CostFree Personal plan availableFree tier available

For public access to your apps, use the Cloudflare Gateway instead. You can use both Tailscale and Cloudflare simultaneously.

New to this? Reach your Hub from your phone walks the whole path end to end, including how to prove it works away from your home Wi-Fi.

Next Steps

Last updated on