Skip to content

Domains & public ports

A domain attaches a hostname to one of your services. Pier turns that into a Traefik router and asks Let’s Encrypt for a certificate — building directly on the edge proxy described in Proxy and SSL, so you never touch Traefik config by hand.

Adding a domain is a three-step flow: add → point DNS → activate.

  1. Add. Under a service, open Domains → Add and enter the hostname (for example app.example.com). Pier stores the domain as a draft — is_active = 0. No Traefik router is written and no certificate is requested yet, so configuring a domain never burns a Let’s Encrypt rate-limit slot prematurely.
  2. Point DNS. Create an A (or AAAA) record for the hostname pointing at your server’s public IP. Let’s Encrypt validates over HTTP on port 80, so the record must resolve before activation succeeds.
  3. Activate. Flip the activate toggle. Pier marks the domain active, writes the dynamic-config file, and Traefik picks it up within a second or two and requests the certificate.

Auto-generated sslip.io domains (created when a service is first deployed with the proxy enabled) skip this flow — they come up active immediately.

Each domain carries an ssl_status reflecting its certificate state. An SSL monitor reconciles it against Traefik’s acme.json:

StatusMeaning
provisioningJust activated; waiting for Traefik to obtain the certificate.
pendingAwaiting certificate issuance.
activeCertificate issued and serving over HTTPS.
expiringCertificate valid but expires within 7 days.
expiredCertificate is past its expiry date.

Whether the domain is live is a separate is_active flag: a draft or deactivated domain has no Traefik router regardless of its SSL status.

Deactivate (POST /api/v1/domains/{id}/deactivate) pulls the domain out of Traefik’s live config — routing stops within seconds. The database row stays and the issued certificate remains in acme.json, so re-activating later is instant.

Activate (POST /api/v1/domains/{id}/activate) is the inverse and is idempotent: calling it on an already-active domain just re-emits the config.

To purge a domain entirely, use delete (DELETE /api/v1/domains/{id}). This removes the row and regenerates the service’s Traefik config without it.

A domain gives you HTTPS at a hostname. When you instead want a raw host:port — a database admin tool, a game server, a TCP service — expose a public port rather than a domain.

Toggle it under the service’s ports (PUT /api/v1/resources/{id}/port-public). Pier publishes the chosen port as a direct Docker bind (0.0.0.0:port) on the service container itself — it does not route through Traefik. By default the public port matches the internal port Pier allocated; you can override it explicitly.

Public ports bypass Traefik entirely, so there is no automatic TLS. Use a domain when you need HTTPS termination; use a public port for non-HTTP protocols or direct access. See Ports and allocation for how ports are assigned.