Uplink Docs
Custom Domains
Documentation

Custom Domains

Custom domains alias a hostname you own to a generated Uplink tunnel host. The generated host remains the durable tunnel identity for routing and policy; the custom domain becomes the visitor-facing address.

That means a service can keep its canonical Uplink host:

web-lapp1p1a2qwer.ny.uplink.computer

while visitors—and managed analytics labels—see:

app.example.com

There are two workflows: managed aliases live in your Uplink account and are verified and assigned through the dashboard; standalone key-mode aliases live in a YAML policy on the edge you operate.

Managed account aliases

Add and verify a domain

Create custom-domain aliases in the Uplink dashboard:

  1. Open Custom Domains.
  2. Add the full hostname, such as app.example.com.
  3. Add the shown CNAME record at your DNS provider.
  4. Verify the domain after DNS propagates.

A plain CNAME is not enough on its own. Uplink also verifies ownership, obtains edge TLS authority, and registers the hostname as an alias for a canonical tunnel host.

A verified domain doesn’t need to be assigned right away — a verified-but-unassigned alias can be attached later from uplink.yaml or from the connector app’s publish menu (below).

Assign from the app

In the desktop app or uplink ui, each tunnel’s address segment opens a publish menu (“Choose where this tunnel is published”). It lists your managed regions, added self-hosted edges, and managed account aliases. Pick an alias to assign it to the tunnel, pick the generated host to clear it, or pick a region/edge to move the tunnel’s home.

Assign from uplink.yaml

Once the alias exists in your account, declare it on a service. custom_domain is part of the managed account workflow; a standalone edge uses its local alias file instead.

services:
  web:
    port: 3000
    public: true
    custom_domain: app.example.com

Then run:

uplink up
# or
uplink reload

If the alias is verified and available, the CLI assigns it to the service’s generated host. If the alias is missing or still waiting on DNS, the canonical tunnel still serves and the CLI prints the next step. If the alias is already assigned to another generated host, or belongs to a different edge than the service, the command fails before rewriting local serving state.

custom_domain must be a hostname, not a URL, and it must be a subdomain such as app.example.com.

Move or remove a managed domain

Removing custom_domain from uplink.yaml does not unassign the alias. Unassign or move a custom domain in the dashboard, or from the connector app’s publish menu on the tunnel’s address segment; then run uplink reload if you changed the service declaration.

If a service is renamed, its generated Uplink host changes. Unassign the custom domain from the old host before assigning it to the renamed service.

Self-hosted aliases

A standalone key-mode edge can route aliases without a Uplink account or dashboard. The edge operator owns both the DNS record and a local alias-to-canonical-host map. These aliases do not appear in the connector’s publish picker and should not be set with custom_domain in uplink.yaml.

First publish the service to your self-hosted edge, then copy its exact generated host from uplink status or the tunnel card in the desktop app. On the edge, create a policy file such as:

aliases:
  docs.example.com: docs-laptop.edge.example.com
  api.example.com: api-server.edge.example.com

Each value must be a generated host under this edge’s public domain.

For the recommended Compose deployment, save the policy in the bind-mounted configuration directory:

cd ~/uplink-edge
${EDITOR:-vi} configuration/aliases.yaml
chmod 644 configuration/aliases.yaml

Alias hostnames are not secrets; the read bit lets the fixed non-root container user load the bind-mounted file. Add its container path to .env, then recreate the edge container once:

UPLINK_EDGE_ALIAS_POLICY_FILE=/operator/aliases.yaml
docker compose up -d uplink-edge
docker compose logs --tail=50 uplink-edge

The setup-generated Caddyfile already uses the edge’s allowlist to guard on-demand TLS. Confirm that the edge started cleanly and loaded the policy. Then create a DNS-only CNAME from each alias to the edge’s public domain, such as docs.example.com to edge.example.com. If your DNS provider does not allow a CNAME at the zone apex, use its equivalent flattening record.

Valid file edits hot-reload within a few seconds; no further restart is needed. An unreadable or invalid edit keeps the last valid snapshot active and writes a warning to the edge log. Inspect it with docker compose logs --tail=50 uplink-edge. To remove one alias, delete its mapping; use aliases: {} to clear them all. After the reload the hostname no longer routes and future on-demand certificate requests are denied. Caddy may retain a previously issued certificate in its storage, but that does not keep the edge route active. Remove the DNS record after the policy change has loaded.

A local alias file is key-mode only and cannot be combined with UPLINK_CONTROL_URL, which prevents two policy sources from racing.

Analytics labels

For managed aliases, analytics, bandwidth, security, filters, and tunnel detail links still group by the generated Uplink host. The views display the custom domain as the visible label and keep the canonical host as the stable identity. Standalone aliases do not feed Uplink’s hosted analytics; the edge operator can configure an OTLP export.

Search across 15 pages.
↑↓ navigate openEsc close