Open source · AGPL · one binary

Unleash your Containers as Tailscale Services

Add labels to your Docker containers. DockTail handles the rest.

Native Tailscale Services · not per-container devices · same tailnet ACLs

docker-compose.yml
services:
  myapp:
    image: nginx:latest
    # No ports needed!
    labels:
      - "docktail.service.enable=true"
      - "docktail.service.name=myapp"
      - "docktail.service.port=80"
https://myapp.tailnet.ts.net
Service is live
myapp.tailnet.ts.net
Tailscale HTTPS

DockTail vs alternatives

DockTail gives Docker containers the native Tailscale Services model without turning each app into another Tailscale device.

DockTail TSDProxy ScaleTail tsbridge Plain Services DockFlare
Native Tailscale Services ✅⚠️iThe stable v2 release runs one tailnet node per app. The v3 beta adds an opt-in Services mode.❌❌✅—iDockFlare uses Cloudflare Tunnel, not Tailscale.
Configured via Docker labels ✅✅❌✅❌✅
One tailnet device per host, not per app iDockTail advertises each app as a Tailscale Service from the node already on the host (or its sidecar). Apps do not get their own node, node key or machine entry. ✅⚠️iDefault mode runs one tailnet node per app. The v3 beta Services mode serves apps from one node.❌❌✅—iDockFlare uses Cloudflare Tunnel, not Tailscale. Apps are routes on one tunnel per host.
No app port publishing ✅iProxies to the container IP on its Docker network. On rootless Docker, publish the port or put the sidecar on the app’s network.⚠️iThe default config reaches apps through host.docker.internal, which needs published ports. Sharing a Docker network with the app avoids that.✅iApps share the sidecar’s network namespace, so templates publish no host ports by default. A few publish on purpose for LAN protocols such as DNS.⚠️iNo published ports if tsbridge joins each app’s Docker network. It proxies by container name.⚠️iYou point tailscale serve at a published port or a hand-typed container IP. An IP target does not follow the container to a new IP.⚠️iNo published ports, but each app has to join the cloudflare-net network so cloudflared can reach it by container name.
Automatic Docker reconciliation ✅✅❌✅❌✅
Low manual setup after install ✅✅⚠️iScaleTail is template-based, so each app usually starts from its own Compose recipe.✅❌iPer app: a Service definition in the admin console plus a tailscale serve command on the host.✅
Private to your tailnet by default iApps are reachable only from tailnet devices your policy allows. In every Tailscale-based option here, going public through Funnel is an explicit opt-in. ✅✅✅✅✅❌iPublishes public hostnames through Cloudflare’s edge. Cloudflare Access login policies are optional; a service without one is public.

All comparisons →

Features

Auto Discovery

Monitors Docker events in real-time. Start a labeled container and it appears on your Tailnet within seconds.

Direct IP Proxy

No port publishing required. Routes directly to container IPs on the Docker network, adapting automatically on restart.

Funnel Support

Expose any container to the public internet via Tailscale Funnel. Two labels and the funnel node attribute in your policy file take you from private to public.

How it works

1

Add docktail.* labels to your container

2

DockTail detects and advertises to Tailscale

3

Access via http://service

DockTail Cloud

Stop checking if it's still up.

Monitor every DockTail host and service from one dashboard. Cloud reads local checks, Docker events, and Tailscale control-plane state together to name the layer that broke — the container, its exposure on the tailnet, or the host — not just that something's down.

Fleet-wide service catalog and health history
Context-rich incidents, recoveries, and alerts
Outbound-only connection with no shell or deploy access

Connect one host and see every service it detects, free and without a card. Checks and alerts start with a plan; Homelab and Team come with a 30-day trial.

DockTail Cloud in 50 seconds