TSLinkTSLink Docs

Several apps on one machine, one ts.net name each

Native tailscale serve gives one machine one MagicDNS name. See how Tailscale Services, a TSLink node per app, Docker sidecars and TSDproxy each give apps their own names.

Last updated on

View as Markdown

Ordinary tailscale serve (without --service) gives one machine one MagicDNS name, so a second app can only be reached on another port or under a path. TSLink runs each app as its own tsnet node, so each one gets https://<name>.<tailnet>.ts.net on the root path and port 443. To try it with two apps already listening on ports 3000 and 8080:

bash
tslink add web --proxy localhost:3000 --allow you@example.com
tslink add api --proxy localhost:8080 --allow you@example.com
tslink url web --wait
tslink url api --wait

Replace the login with your own Tailscale account. Each url command prints the exact address to use, because the runtime hostname can differ from the requested name. Using add with a name that already exists replaces that service. The first time a node starts, tslink may return an auth_url (needs_login) for a one-time browser enrollment: open it, then rerun url. To clean up, run tslink remove web and tslink remove api; there is no unshare command. TSLink is an independent project, not made by Tailscale.

Why native Serve stops at one name

Tailscale's MagicDNS documentation says it "automatically uses a device's machine name as part of the DNS entry", so a device has one name. The tailscale serve reference then offers two ways to tell apps apart on that name: --https=<port> (or --http=<port>) picks the port to listen on, and --set-path mounts a service under a URL path. Both change the address you give people.

Tailscale's own tsnet documentation describes the underlying limit: "every IP address in your tailnet has to be strongly associated with a single device. This makes it difficult to run multiple services on a single device", and tsnet "lets you run multiple services on the same device with different IP addresses, access control rules, and even user identities". TSLink uses tsnet this way: one embedded node per registered app, all inside one daemon. See share one app for what each node exposes.

Paths cause their own trouble. Many frontends assume they live at /, which is why a path mount can break assets and redirects.

Four approaches give each app its own name. They differ in what you have to set up first.

Tailscale ServicesTSLink node per appDocker sidecarDocker auto-proxy (TSDproxy)
What each app getsIts own MagicDNS name and TailVIP, defined as a Service (configuration file reference)Its own tsnet node and name: https://<name>.<tailnet>.ts.netA Tailscale container next to the app's container, so each service gets a unique name (Tailscale's Docker guide)One proxy process creates a tsnet node with its own name and HTTPS for each labelled container, with no Tailscale container per service (README)
What the host must beA device with a tag-based identity; "You cannot use a device authenticated with a user account as a Service host"An ordinary node. Fresh credential-free nodes are user-owned; with stored credentials a node is tagged (the configured default tag, initially tag:tsmain)A machine that runs DockerA machine that runs the proxy and can reach the Docker servers it is configured to use
Permissions and approvalOwner, Admin or Network admin permissions; define the Service in the admin console (or API); approve the advertisement unless an auto-approval policy covers itEnroll each new node once (browser login or stored credentials), plus any device approval your tailnet requiresVaries by setupVaries by setup
Client versionsTailscale v1.86.0 or later, or an unstable v1.87.xNo separate Tailscale install on the host; phones and laptops that connect need Tailscale as usualVaries by setupVaries by setup
Across hostsA Service can be advertised by several approved hostsOne host per registration; no automatic cross-host aggregationContainers on the host that runs themOne proxy can connect to multiple configured Docker servers, including remote servers (server configuration)

Services requirements are quoted from the Tailscale Services documentation (last validated October 7, 2026 on the page we read). Services is the right tool when you want a stable service name that survives moving hosts or spans several of them. It needs a tagged host and an administrator, while a TSLink app can run from an ordinary machine today. Docker sidecars suit apps that already run in containers and need a Tailscale container each. TSDproxy suits label-driven publishing of containers from one proxy process, and the comparison page covers it and tsnsrv.

What each option counts as in Tailscale billing

A TSLink node is a Tailscale node, so it counts under your plan. The facts below come from Tailscale's pricing page and FAQ and tags documentation, read on 2026-10-22. Whether a node is tagged depends on credentials, not on whether the registration is durable: tslink add registers a non-ephemeral node unless you pass --ephemeral, and tslink share registers an ephemeral one by default.

  • Credential-free enrollment is the default. A fresh node is user-owned and untagged. The FAQ says user devices are "free and unlimited", and that also covers an ephemeral node of this kind. Each node needs its own browser authorization, do not assume tag-based access rules apply to it, and it cannot be a Services host. Keys expire on the default 180-day schedule.
  • With stored credentials, which are optional, each app node is tagged with the configured default tag, initially tag:tsmain, unless --tags overrides it. That makes it a tagged resource, which the FAQ defines as "a device that is owned by a tag rather than a user identity". The Personal plan lists "Up to 50 tagged resources to start", with more at $1 each per month, and the FAQ says Tailscale is currently not enforcing those limits.
  • Tagged ephemeral nodes (stored credentials plus --ephemeral, which tslink share passes by default) first draw on the ephemeral-minutes pool. In the FAQ's words, a device present "for more than four hours" is "counted as a standard tagged resource".
  • A Services host is also a tagged device. One tagged host can advertise several Services, so Services can use fewer tagged resources than one tagged TSLink node per app.
  • One app is enough. If a single port or path under the device name is fine, plain tailscale serve 3000 needs no extra layer. See when you need TSLink.
  • You need one name across hosts, or host failover. Choose Services. TSLink manages the apps on one host and does not aggregate hosts.
  • You want your own domain. TSLink only produces *.ts.net names.
  • Your apps already run in Docker and you like label-driven publishing. TSDproxy fits that workflow better.
  • You want to keep tagged resources low. One tagged Services host can front several Services; with stored credentials, a TSLink node per app uses one tagged resource each.
  • You need host process isolation. TSLink nodes have separate network identities, but they run in one shared daemon and do not isolate the apps.

Official Tailscale sources linked above: accessed 2026-10-22. TSLink behavior: v0.2.0. TSLink is an independent project by anydoor7, not made or endorsed by Tailscale.

Table of Contents