Custom domains & TLS
What it is
Section titled “What it is”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.
How to use
Section titled “How to use”See Map a custom domain.
DNS requirements
Section titled “DNS requirements”- 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-httpClusterIssuer. - 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.
Status state machine
Section titled “Status state machine”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.
Limits & defaults
Section titled “Limits & defaults”- 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.euURL always serves alongside custom domains and cannot be removed. - DNS verification uses Go’s resolver with a 5-second timeout per check.
Endpoints
Section titled “Endpoints”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 statusPOST /domains/{domainID}/recheck— re-run DNS verificationDELETE /domains/{domainID}— remove the domain