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:
Option 1: Hub Sidecar (Recommended)
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:
- Click Log In with Tailscale
- Authenticate in the popup window (create a free account if needed)
- Your Hub automatically joins your Tailscale network
- 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:
- Go to Settings → Network
- Find the Private VPN section
- Click Log In with Tailscale
- Authenticate in the popup window


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 upMount 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 VPN → Save), 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:8138The 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 statusIf 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.
Open the app link
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
- Mesh Network — Tailscale creates a peer-to-peer mesh between all your devices
- NAT Traversal — Works behind firewalls and routers without configuration
- Private IPs — Each device gets a private IP (100.x.y.z range)
- Encrypted — All traffic is encrypted end-to-end using WireGuard
Troubleshooting
Sidecar Not Available
If you see “Tailscale sidecar container is not running”:
-
Ensure the
private-vpnprofile is enabled:docker compose --profile private-vpn up -d -
Or use the Hub CLI (Tailscale sidecar is enabled by default):
cihub up --detached cihub status # shows Tailscale IP when connected -
Check that the
hub-tailscalecontainer is running:docker ps | grep hub-tailscale
Connection Not Working
If the login button doesn’t connect:
- Complete the authentication in the popup window
- Wait 5-10 seconds for the connection to establish
- Refresh the Settings page to see updated status
Can’t Access Hub from Other Devices
-
Verify Tailscale is running on both devices:
tailscale status -
Ensure both devices show “Running” in Tailscale
-
Try accessing by IP first:
http://100.x.y.z:5002(find IP in Settings → Network) -
Try accessing by hostname:
http://your-hub-name:5002
Private VPN App Link Doesn’t Work
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 statusWhen 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/24Pre-Auth Keys (Automated Setup)
For headless or automated deployments, you can use a pre-authentication key instead of browser login:
- Generate a key at login.tailscale.com/admin/settings/keys
- Add it to your
.envfile:TAILSCALE_AUTHKEY=tskey-auth-... - 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
| Feature | Tailscale | Cloudflare |
|---|---|---|
| Privacy | Private mesh, no public exposure | Public URLs (can be secured with Access) |
| Setup | One-click browser login | Requires CI Account registration |
| Device Requirement | Tailscale client on each device | Any browser works |
| Use Case | Personal, private access | Sharing with others, public apps |
| Cost | Free Personal plan available | Free 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
- Install Tailscale on your devices: tailscale.com/download
- Learn about exposing apps on your network
- Explore Cloudflare Gateway for public access