How to Add a Custom Domain in Coolify

By Mustafa Campwala · ·5 min read

Every new app in Coolify gets an sslip.io URL like http://abc123.203.0.113.10.sslip.io so you can check the deploy worked. Good enough for a quick test, but you’ll want a real domain with HTTPS before anyone else uses it. These are my notes for getting from there to https://app.example.com, plus the errors you’re most likely to hit. The official reference is the Coolify domains docs, this is the condensed version with the troubleshooting I wish was in one place.

If you want every subdomain to land on one server (preview deployments, lots of small apps), read Setting Up Coolify with a Subdomain Wildcard after this.

1. Point DNS at the right server

Create the record wherever your DNS lives (Cloudflare, Namecheap, Route 53…). It needs to point at the server the app runs on, which isn’t always the server running the Coolify dashboard. With one server it’s the same box. If you’ve added remote servers, check which one the app is on first.

You want Type Name Value
example.com A @ server IPv4
app.example.com A app server IPv4
www.example.com A or CNAME www server IPv4 / example.com
IPv6 (optional) AAAA same name server IPv6

Only add an AAAA record if the server really answers on IPv6 on ports 80 and 443. Let’s Encrypt may validate over IPv6, and a half-working IPv6 path is one of the most common reasons a certificate never issues.

Check it from your own machine before you touch Coolify:

dig +short app.example.com A
dig @1.1.1.1 +short app.example.com A   # the resolver Coolify validates against by default

Both should print your server IP. If not, fix the record or wait out the old TTL. Don’t bother debugging Coolify until this part is right.

2. Add the domain to the app

In Coolify open the application (or service), then Domains in its sidebar:

  1. Add domain.
  2. Pick https as the protocol. This is what makes the proxy (Traefik or Caddy) request a Let’s Encrypt certificate.
  3. Enter the hostname, e.g. app.example.com.
  4. Leave Port empty unless the container listens on something other than the first port in Ports Exposes. For a Node app on 3000 you would set 3000.
  5. For Docker Compose apps, choose which service receives the traffic.
  6. Save, then Redeploy. The proxy only picks up the new route on deploy.

Older Coolify versions use one comma-separated Domains field instead of the form. The values look the same: https://app.example.com,https://www.example.com.

Ports and paths

The port in a domain is the port inside the container. It does not open anything on the host; visitors still come in through 443.

Domain value What the proxy does
https://app.example.com hostname → default container port
https://app.example.com:3000 hostname → container port 3000
https://example.com/api /api/* → default port, /api stripped
https://example.com:8080/api /api/* → container port 8080

Port goes before the path (:8080/api, never /api:8080). Coolify strips the path prefix by default, so /api/users reaches your app as /users. If your app expects the full path, set Advanced → Proxy → Path prefixes to keep paths as-is.

3. www and non-www

Add both hostnames as domains and create DNS records for both. Then edit a domain and set www redirect to Redirect to non-www (or the other way round). Which one you pick doesn’t matter much, just pick one. Serving the same site on both without a redirect means Google sees two copies of it.

4. Check it works

curl -sI https://app.example.com | head -5
curl -sI http://app.example.com | grep -i location   # should redirect to https

Then open it in a browser and check the certificate. If the issuer says TRAEFIK DEFAULT CERT, routing works but Let’s Encrypt failed, see below.

Staging and preview domains: keep them out of Google

For a staging domain, edit it, set Search engine indexing to Noindex and redeploy. The proxy then adds X-Robots-Tag: noindex, nofollow for that hostname only (preview deployments get this automatically). It only stops search engines, anyone with the URL can still open it, so use basic auth if it’s private.

When the domain doesn’t work

ERR_CERT_AUTHORITY_INVALID / Traefik default certificate. Let’s Encrypt couldn’t validate the domain. Usual suspects:

  • Port 80 is closed (firewall, cloud security group). The default HTTP challenge needs port 80 open to the internet.
  • The record is proxied through Cloudflare (orange cloud). Either switch it to DNS-only until the cert issues, or move to the DNS challenge, which doesn’t care about ports or proxies.
  • A stale AAAA record pointing somewhere that doesn’t answer.
  • Rate limits after lots of retries: look for 429 in Servers → Proxy → Logs and wait.

If the certificate store itself is broken, you can delete /data/coolify/proxy/acme.json on the server and hit Restart Proxy. That re-requests every certificate on the server, so don’t do it right after a rate limit.

404 page not found (plain text, from Traefik). The proxy got the request but no router matched. The domain isn’t saved on any app, it has a typo, or you didn’t redeploy after saving.

502 Bad Gateway / no available server. The route matched but the container isn’t answering. Wrong port (your app listens on 3000 but the proxy targets 80), the app binds to 127.0.0.1 instead of 0.0.0.0, or the container is crash-looping. Check the app’s logs first.

“Domain already in use” warning. Some other app, service or the dashboard itself already has that domain. Remove it there first, otherwise routing between the two is a coin flip.

Dashboard domain. The Coolify UI gets its own domain under Settings → General → URL (e.g. https://coolify.example.com, pointed at the Coolify server). Don’t reuse an app’s domain for it.

Quick checklist

  • dig returns the app server’s IP (and no broken AAAA)
  • Ports 80 and 443 open on that server
  • Domain added with https://, correct container port
  • Redeployed
  • Certificate issuer is Let’s Encrypt, not Traefik default
  • www/non-www redirect chosen; staging domains set to Noindex

Next: running lots of subdomains on one box? See wildcard subdomains in Coolify. Need a wildcard certificate or have port 80 blocked? See Coolify DNS challenge with Cloudflare.

More posts