The Problem

Running services inside Docker often requires manual port exposure, DNS configuration, and separate TLS handling. Teams that already use Tailscale for zero‑trust networking must still create service entries in the Tailscale admin console for each container, and keep those entries in sync when containers start or stop.

What This Does

DockTail watches the Docker daemon (via the mounted socket) and translates container labels into Tailscale Service definitions. The core logic lives in docker/client.go (Docker API wrapper) and tailscale/service.go (service creation/cleanup). When a container is started with the expected labels—e.g., docktail.service.enable=true, docktail.service.name=myapp, docktail.service.port=80—DockTail calls the Tailscale API (OAuth or API‑key) to register a service automatically.

The project is packaged as a stateless container (Dockerfile at the repository root) that can be run alongside any Docker host. The entry point is main.go, which starts the reconciler (reconciler/reconciler.go) that continuously syncs Docker state with Tailscale.

How To Use It

Setup

Build the image (optional; the public image is published as ghcr.io/marvinvr/docktail:latest):

docker build -t docktail . Create a compose file (the repo provides several examples, e.g. docker-compose.yaml). A minimal service definition is:

services: docktail: image: ghcr.io/marvinvr/docktail:latest restart: unless-stopped volumes: /var/run/docker.sock:/var/run/docker.sock:ro /var/run/tailscale:/var/run/tailscale environment: TAILSCALEOAUTHCLIENTID=${TAILSCALEOAUTHCLIENTID} TAILSCALEOAUTHCLIENTSECRET=${TAILSCALEOAUTHCLIENTSECRET} Add your application containers with the required labels, for example test/nginx-web1/Dockerfile shows a typical Nginx image; the README’s quick‑start snippet demonstrates the label set.

Configuration

Credentials – either OAuth (TAILSCALEOAUTHCLIENTID / TAILSCALEOAUTHCLIENTSECRET) or a long‑lived API key (TAILSCALEAPIKEY). These are read by tailscale/client.go. Service definition – container‑level labels are parsed in tailscale/service.go. No additional config file is required. An example .env.example is provided; copy it to .env and fill in the appropriate values.

Running

Start the stack with Docker Compose:

docker compose up -d

DockTail will launch, attach to the Docker socket, and begin reconciling. Verify a service appears in the Tailscale admin console or resolve it via DNS, e.g.:

curl http://myapp.your-tailnet.ts.net

Testing (optional)

Run the Go test suite:

go test ./...

The CI workflow (.github/workflows/ci.yaml) executes the same command on each push.

Real‑World Use

A small SaaS team runs all micro‑services on a single VM with Docker. By adding the DockTail label set to each service container, the team instantly gets a Tailscale‑routable address (service-name.<tailnet>.ts.net) without exposing ports on the host firewall. When a container is redeployed, DockTail removes the stale service and creates the new one, keeping the mesh consistent automatically.

Code Health & Issues

Low – Limited test coverage for edge cases – tailscale/service_test.go covers basic paths but does not exercise failure modes of the Tailscale API. Med – Docker socket exposure – Mounting /var/run/docker.sock gives the container root‑level control over the host Docker daemon; this is a deliberate design decision but a security risk in multi‑tenant environments. Low – Minimal input validation – Label parsing in tailscale/service.go trusts string values; malformed labels could cause runtime errors. Low – Dependency hygiene – go.mod pins versions but no go.sum audit step is visible in CI; adding go mod verify would improve supply‑chain security. Low – Documentation gaps – The README explains the OAuth flow, but the repo lacks a concrete example of the sidecar mode described in docker-compose.sidecar.yaml.

Overall the repository includes a license, CI pipeline (.github/workflows/.yaml), lint config (.golangci.yml), and a full test suite for core functionality, indicating a mature baseline.

The Bottom Line

DockTail delivers a pragmatic bridge between Docker and Tailscale, automating service registration with minimal configuration. It is well‑structured, actively tested, and easy to deploy via the provided Docker images. Teams that already use Tailscale and need automatic service discovery should consider it; however, they must accept the security implications of granting Docker‑socket access to the DockTail container.