Skip to content

Custom domains & TLS

Every app serves its default URL at {slug}.run.uploy.eu (wildcard TLS already provisioned). You can additionally map one or more custom subdomains to the app. An NGINX-class Ingress handles routing; cert-manager issues Let’s Encrypt certificates automatically via HTTP-01.

See Map a custom domain.

  • Subdomain → CNAME pointing to {project-slug}.run.uploy.eu. The exact target is shown in the dashboard when you add the domain.
  • Apex domains (bare example.com) and wildcards (*.example.com) are not supported in this release.
  • Issuer: Let’s Encrypt production via the letsencrypt-prod-http ClusterIssuer.
  • Challenge: HTTP-01 (port 80 must be reachable — Uploy handles this).
  • Renewals: automatic, handled by cert-manager; transparent to you.
  • Failure visibility: if issuance or renewal fails, the Domains tab shows the error and the cert-manager reason; the row is marked Failed.
pending_dns ─(Recheck: CNAME ok)→ pending_cert ─(cert Ready)→ live
│ │
│ └─(cert Failed)→ failed
└─(Recheck: CNAME wrong)─→ pending_dns (status_detail explains)
  • pending_dns — DNS check has not yet matched {slug}.run.uploy.eu.
  • pending_cert — DNS verified; cert-manager is issuing.
  • live — TLS active.
  • failed — cert issuance or a prior Recheck error; retry via Recheck.
  • deleting — transient state during removal.
  • Multiple custom domains per app (no per-app hard cap in this release).
  • Domain uniqueness is global — one domain can attach to one app at a time.
  • The default {slug}.run.uploy.eu URL always serves alongside custom domains and cannot be removed.
  • DNS verification uses Go’s resolver with a 5-second timeout per check.

Under /api/apps/{appID} (the app’s environment is implied by the app itself, no env ID needed in the URL):

  • POST /domains — add a domain (body: {"domain": "..."})
  • GET /domains — list domains with current status
  • POST /domains/{domainID}/recheck — re-run DNS verification
  • DELETE /domains/{domainID} — remove the domain