Zerobyte + Tailscale sidecar (Docker Compose)
This example runs Zerobyte behind a Tailscale sidecar container so the Zerobyte web UI/API can be reached over your tailnet and Zerobyte can access other devices on your tailnet (based on the ACLs/tags you configure in Tailscale).
It uses a common “sidecar networking” pattern:
- The
tailscalecontainer brings up a Tailscale node - The
zerobytecontainer shares thetailscalenetwork namespace (network_mode: service:tailscale)
About Tailscale
Tailscale is a mesh VPN built on WireGuard. It connects devices and containers into a private network (“tailnet”) without opening inbound ports on your router or exposing services directly to the public internet.
In this example, Tailscale acts as a secure access layer in front of Zerobyte:
- You reach Zerobyte using the node’s tailnet IP/DNS name.
- Access can be restricted using Tailscale ACLs/tags.
Prerequisites
- Docker + Docker Compose
- A Tailscale account and an auth key
This example supports two Tailscale modes:
-
Kernel mode (
TS_USERSPACE=false, default):- requires
/dev/net/tunon the host - requires
NET_ADMIN - may require
SYS_MODULEon some hosts (kept commented out in the compose file)
- requires
-
Userspace mode (
TS_USERSPACE=true):- does not require
/dev/net/tun - works better on Docker Desktop / restricted hosts
- requires a small edit in the compose file (see Troubleshooting)
- does not require
Setup
-
Copy the env file and fill in your auth key:
cp .env.example .env -
Start the stack:
docker compose up -d -
In the Tailscale admin console, confirm the node is present (and approved if your policy requires it).
Access
- Over Tailscale:
http://<tailscale-ip>:4096orhttp://<tailscale-name>:4096(if MagicDNS is enabled) - Locally (optional): the example publishes
4096:4096on the host
If you want Zerobyte to be reachable only via Tailscale, remove the ports: section from the tailscale service in docker-compose.yml. Zerobyte will still be able to access the internet and other resources outside the tailnet, but UI will only be accessible over Tailscale with possibility to further restrict access to it with ACLs/tags.
Notes
network_mode: service:tailscalemakes Zerobyte share the Tailscale container’s entire network namespace (interfaces + routing table).- Traffic to tailnet IPs (typically
100.x.y.z) goes overtailscale0and is governed by Tailscale ACLs; traffic to your LAN/Internet may still go over the normal network interface depending on routes and host firewall. - If
--accept-routesis used, the Tailscale container may add routes to your routing table that Zerobyte will also use and be able to access remote networks. - If
--accept-dnsis used, Zerobyte will also use Tailscale’s DNS servers. - Zerobyte still needs
SYS_ADMINand/dev/fuseif you intend to mount NFS/SMB/WebDAV volumes from inside the container.
The example uses these environment variables (see .env.example):
TS_AUTHKEY(required)TS_HOSTNAME(optional)TS_EXTRA_ARGS(optional; passed totailscale up)TS_USERSPACE(optional; set totrueto use userspace mode)TZ(optional)
Troubleshooting
- If the
tailscalecontainer can’t start due to missing TUN support, ensure your host has/dev/net/tunavailable and that Docker is allowed to use it. - If your tailnet uses ACLs/tags, set
TS_EXTRA_ARGSaccordingly (for example--advertise-tags=tag:backup). - If the
tailscalecontainer fails due to Docker Desktop / missing TUN support: setTS_USERSPACE=truein your.env, remove the/dev/net/tun:/dev/net/tundevice mapping in docker-compose.yml, and keepSYS_MODULEdisabled (commented out).
To confirm the tailnet address of the container:
docker exec zerobyte-tailscale tailscale status
docker exec zerobyte-tailscale tailscale ip -4
To confirm received routes when --accept-routes is used in kernel mode:
(Missing routes could be due to ACLs or because --accept-routes is not set or not supported in userspace mode)
docker exec zerobyte-tailscale ip route
docker exec zerobyte-tailscale ip route show table 52