---
title: "Several apps on one machine, one ts.net name each"
description: "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."
url: "https://tslink.md/docs/several-apps-one-machine"
locale: "en"
product_version: "0.2.0"
source: "https://github.com/anydoor7/tslink/blob/v0.2.0/docs/architecture.md"
---

> Documentation index: https://tslink.md/llms.txt · Installed binary is authoritative: `tslink manifest`.

**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](https://tailscale.com/docs/features/magicdns) 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](https://tailscale.com/docs/reference/tailscale-cli/serve) 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](https://tailscale.com/docs/features/tsnet) 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](https://tslink.md/docs/share-one-app.md) 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](https://tslink.md/docs/serve-set-path-breaks-app.md).

## Services, a TSLink node per app, or Docker

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

|                          | Tailscale Services                                                                                                                                                   | TSLink node per app                                                                                                                                         | Docker sidecar                                                                                                                                                        | Docker auto-proxy (TSDproxy)                                                                                                                                                                                                                           |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| What each app gets       | Its own MagicDNS name and TailVIP, defined as a Service ([configuration file reference](https://tailscale.com/docs/reference/tailscale-services-configuration-file)) | Its own tsnet node and name: `https://<name>.<tailnet>.ts.net`                                                                                              | A Tailscale container next to the app's container, so each service gets a unique name ([Tailscale's Docker guide](https://tailscale.com/blog/docker-tailscale-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](https://github.com/almeidapaulopt/tsdproxy/blob/cc0c124946d2a76b172fb9cd97cea1458f7a93a8/README.md)) |
| What the host must be    | A 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 Docker                                                                                                                                            | A machine that runs the proxy and can reach the Docker servers it is configured to use                                                                                                                                                                 |
| Permissions and approval | Owner, Admin or Network admin permissions; define the Service in the admin console (or API); approve the advertisement unless an auto-approval policy covers it      | Enroll each new node once (browser login or stored credentials), plus any device approval your tailnet requires                                             | Varies by setup                                                                                                                                                       | Varies by setup                                                                                                                                                                                                                                        |
| Client versions          | Tailscale v1.86.0 or later, or an unstable v1.87.x                                                                                                                   | No separate Tailscale install on the host; phones and laptops that connect need Tailscale as usual                                                          | Varies by setup                                                                                                                                                       | Varies by setup                                                                                                                                                                                                                                        |
| Across hosts             | A Service can be advertised by several approved hosts                                                                                                                | One host per registration; no automatic cross-host aggregation                                                                                              | Containers on the host that runs them                                                                                                                                 | One proxy can connect to multiple configured Docker servers, including remote servers ([server configuration](https://github.com/almeidapaulopt/tsdproxy/blob/cc0c124946d2a76b172fb9cd97cea1458f7a93a8/docs/content/docs/serverconfig.md))             |

Services requirements are quoted from the [Tailscale Services documentation](https://tailscale.com/docs/features/tailscale-services) (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](https://tslink.md/docs/comparisons.md) 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](https://tailscale.com/pricing) and [tags documentation](https://tailscale.com/docs/features/tags), 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](https://tailscale.com/docs/features/access-control/key-expiry).
* **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.

## When not to use TSLink

* **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](https://tslink.md/docs/when-to-use-tslink.md).
* **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.

## Related pages

* [Share an app, not your whole machine](https://tslink.md/docs/share-one-app.md): what each TSLink node exposes and how to set per-app access.
* [tailscale serve --set-path broke my app?](https://tslink.md/docs/serve-set-path-breaks-app.md): why a path mount breaks assets and logins.
* [Use your coding agent's web UI from your phone](https://tslink.md/docs/agent-ui-phone.md): the same one-node-per-app pattern for dev servers.
* [Comparisons](https://tslink.md/docs/comparisons.md) and [when you need TSLink](https://tslink.md/docs/when-to-use-tslink.md): fuller decision tables.

Official Tailscale sources linked above: accessed **2026-10-22**. TSLink behavior: v0.2.0. TSLink is an independent project by [anydoor7](https://github.com/anydoor7/tslink), **not made or endorsed by Tailscale**.
