ScaleTail: Docker Compose Stacks That Put Self-Hosted Apps on a Tailnet
Tailscale Sidecar Configurations for Docker
At a glance
- What is it?
- ScaleTail is a collection of ready-to-run Docker Compose sidecar configurations that connect self-hosted services to a Tailscale tailnet with automatic HTTPS. It is a convenience layer over Tailscale, not a replacement for it, and its value depends on whether your stack already speaks Docker Compose.
- Who is it for?
- ScaleTail suits self-hosters who already run Docker Compose and want their services reachable over a tailnet without hand-writing Tailscale sidecar blocks. Skip it if you need a Kubernetes operator, a non-Compose orchestrator, or a supported SLA.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem ScaleTail Addresses: Sidecar Wiring for Tailscale
Tailscale itself is a mesh VPN client. Running it inside Docker is a separate exercise: you need a container with the tailscaled daemon, an auth key injected at startup, and a way for the application container to route traffic through that daemon. Doing this correctly means picking a network mode, sharing the network namespace, and deciding how the app's HTTP port becomes a tailnet URL. ScaleTail packages that decision once per application and ships it as a directory of Compose files. The README describes the output as an application URL with automatic HTTPS, for example https://application.tail-net.ts.net. That URL is the point: no reverse proxy certificate management, no port forwarding, no public DNS record. The intended audience is a self-hoster running Docker Compose on a Linux host who already has a tailnet and wants a service reachable from other tailnet devices. The repository is organized as services/<name> directories, each containing an .env file and a Compose stack. The README's Quick Start assumes Git and Docker Compose are installed, and states a Linux host is preferable.
How the Sidecar Pattern Works in These Stacks
Each service directory contains a Docker Compose stack with at least two containers: the application and a Tailscale container. The Tailscale container authenticates with an auth key read from TS_AUTHKEY in the .env file, joins the tailnet, and exposes the application over the tailnet. The README distinguishes two modes for this exposure. Tailscale Serve keeps the service reachable only to devices on the tailnet. Tailscale Funnel publishes it to the public internet through Tailscale's infrastructure. The repository documents both and links to Tailscale's own documentation for the underlying commands. The README does not spell out the exact Compose keys used per service; you have to open the individual service directory to see whether it uses network_mode: service:tailscale, a shared volume for the tailscaled socket, or another arrangement. That variability across services is a real cost: the pattern is consistent in spirit, but the file contents differ, so copying one service's compose.yaml to another service is not safe. The Python label on the repository is not explained by the README, which shows only shell commands and Compose YAML; the Python code is presumably tooling or scripts in the repository, not part of the runtime path for a deployed stack.
Getting a Service Running: The Auth Key and Compose Commands
The documented workflow has three steps. First, generate an auth key in the Tailscale admin console under Settings, then Keys. Second, clone the repository and change into the service directory you want:
git clone https://github.com/tailscale-dev/ScaleTail.git cd ScaleTail/services/YourDesiredService
Third, open the .env file in that directory, add the key after the line TS_AUTHKEY=, and start the stack:
docker compose up -d
That is the whole documented path. There is no install script, no CLI, no configuration generator. The auth key is the only required secret, and it lives in a plain .env file, so file permissions on that directory matter. The README does not mention key expiry, key rotation, or what happens to the container when the auth key expires; Tailscale auth keys can be set to expire, and the repository does not document a renewal procedure. If you deploy this, treat the .env file as you would any credential file and check the key's expiry setting in the Tailscale admin console before you rely on the service staying up.
Serve Versus Funnel: The Choice That Changes Your Exposure
The README devotes a section to Tailscale Funnel versus Tailscale Serve, which is the most consequential decision in any of these stacks. Serve keeps the application inside the tailnet. Funnel exposes it on the public internet under a ts.net hostname. These are not interchangeable defaults; they describe different threat models. A Funnel-exposed service is reachable by anyone who can resolve the hostname, so the application's own authentication becomes the only barrier. A Serve-exposed service is reachable only from devices that have joined the tailnet, which adds Tailscale's identity layer in front of the app. The README lists both as options without stating a recommended default per service. That is a gap worth flagging: a reader skimming the Available Configurations table sees service names and descriptions but not which exposure mode each stack uses. Before running docker compose up -d on any directory, read its compose.yaml and determine whether Funnel is enabled. If you do not need public reachability, do not enable it.
Limitations: What the Repository Does Not Do
ScaleTail is a set of examples, not a managed product. There are no retrieved releases, so there is no versioned artifact to pin against; you consume the repository at whatever commit you clone. Updates arrive as commits to main, and there is no documented upgrade path beyond pulling the repository and re-running docker compose up -d, which may or may not pick up changes depending on how images are tagged in each stack. The README does not describe a testing or validation process for the service directories, so the correctness of any individual stack is not established by the material available here. The catalog is broad, spanning categories from networking to media to smart home, and breadth in a repository like this usually means uneven depth: some directories will be more complete than others. There is also no documented support channel beyond the Contributing section and the repository's issue tracker. If your environment is not Docker Compose on Linux, the Quick Start does not cover you, and the README explicitly frames Linux as preferable rather than required, leaving non-Linux behavior undocumented.
Alternatives: Plain Tailscale Plus Your Own Compose File
The obvious alternative is to run the Tailscale container yourself and attach your existing services to it, using Tailscale's own Docker documentation and the tailscale/tailscale image. The difference is control: you decide the network mode, the hostname, the tags, and whether Serve or Funnel is active, and you keep that configuration in your own repository rather than tracking an upstream one. The cost is that you write and maintain the sidecar block for every service, including the auth key handling and the Serve or Funnel command. ScaleTail's contribution is that someone has already made those choices for a long list of applications, and the README shows a Tailscale team member walking through a deployment in a video. A second alternative is a general reverse proxy with a VPN overlay, such as Caddy or Traefik placed behind WireGuard. That gives you a familiar proxy configuration, but you lose Tailscale's identity-based access control and its MagicDNS naming, and you take on certificate and DNS management that the tailnet URL avoids. For a single service, the manual sidecar is a small amount of work. For a dozen services, the per-service boilerplate is exactly what ScaleTail removes.
Licence, Maintenance, and What to Verify Before Adopting
The repository is MIT licensed, which permits commercial and private use, modification, and redistribution provided the licence notice is retained. That applies to the configuration files in the repository. It does not extend to Tailscale itself, which is a separate product with its own terms, or to the third-party applications each stack deploys, each of which carries its own licence. Do not read the MIT label as covering the whole assembled stack. On maintenance: the last push recorded for the repository is 2026-09-10, and no releases were retrieved, so there is no release cadence to reason about. Upgrading means pulling the repository and reviewing the diff for the service directories you use, then re-running docker compose up -d. Budget time for reading those diffs, because a change to a compose.yaml can alter exposure mode or volume mounts. Before adopting, verify three things in the specific service directory you care about: the TS_AUTHKEY line in .env and the key's expiry setting in the Tailscale admin console, whether the stack uses Serve or Funnel, and whether the application image tag is pinned or floating. Those three checks are the difference between a service that stays private and one that does not.
Editorial conclusion
ScaleTail suits self-hosters who already run Docker Compose and want their services reachable over a tailnet without hand-writing Tailscale sidecar blocks. Skip it if you need a Kubernetes operator, a non-Compose orchestrator, or a supported SLA. Before adopting, read the .env file and compose.yaml for your chosen service directory and confirm the TS_AUTHKEY line, the network mode, and whether the stack uses Tailscale Serve or Funnel, because that choice determines whether the app is reachable only inside the tailnet or on the public internet.
Community notes