Back to Article List

How to set up SSL on Coolify

How to set up SSL on Coolify

I think Coolify SSL is one of those features that's either invisible or infuriating...

When everything works, you add a domain, Traefik issues a Let's Encrypt certificate within a minute, your site is HTTPS-only and you never think about it again. When it doesn't work, you're staring at "your connection is not private" warnings while you try to figure out if it's DNS, Cloudflare proxy, port 80, ACME rate limits or something else entirely.

This guide covers Coolify SSL end to end: the default Let's Encrypt setup, custom certificate uploads, wildcard certs via DNS-01 challenge, the Cloudflare proxy gotcha and the failure modes to recognize. Written against Coolify v4.0.0 which uses Traefik as the default reverse proxy.

If you don't have Coolify running yet, the LumaDock Coolify VPS ships with v4 pre-installed. The getting started guide covers initial dashboard access if you're new.

How Coolify SSL works by default

Coolify uses Traefik as its default reverse proxy. When you add a custom domain to an application, Traefik kicks off an ACME HTTP-01 challenge with Let's Encrypt automatically. The challenge works like this: Traefik creates a temporary file on the server, Let's Encrypt fetches it over port 80 to verify you control the domain, then issues the certificate. Total time: about 30 to 90 seconds once DNS resolves.

Traefik handles renewal too. Certificates expire after 90 days, Traefik renews them automatically about 30 days before expiry. You don't need to do anything as long as the same conditions that let the initial issue succeed (DNS pointing at your server, port 80 reachable, no Cloudflare proxy interference) keep working.

Certificates are stored in /data/coolify/proxy/acme.json on the host. This file is sensitive (it contains private keys), Coolify sets the permissions automatically. If you back up /data/coolify you've already backed up your certificates.

Step 1, add a domain and get an automatic Coolify SSL certificate

The standard flow is:

  1. Open your application in Coolify, go to the Domains tab
  2. Add your domain in the format https://app.example.com (the https:// prefix tells Coolify you want SSL)
  3. Save
  4. Go to your DNS provider, set an A record pointing app.example.com at your Coolify server's IP
  5. Wait 1-2 minutes for DNS to propagate
  6. Coolify's Traefik issues the cert, refreshes the dashboard, you should see a green padlock

If the cert doesn't issue within a few minutes, check the application's Logs tab and look for ACME-related errors. The most common reasons it fails are listed in the troubleshooting section below.

Step 2, custom Coolify SSL certificates

Sometimes Let's Encrypt isn't the right answer. You might have an existing wildcard cert from your enterprise CA, you might be on a domain that can't reach Let's Encrypt for compliance reasons or you might be using a paid CA for stronger validation. Coolify v4 supports custom certificate uploads.

The mechanism: Coolify reads custom certificates from /data/coolify/proxy/certs/ on the host. The file naming convention is:

  • Certificate file ends in .cert (full chain, PEM format)
  • Key file ends in .key (PEM format)
  • Both files share the same base name (e.g., example.cert and example.key)

SSH into your Coolify server, copy your cert and key files into /data/coolify/proxy/certs/, set ownership and permissions appropriately:

scp example.cert example.key root@your-coolify-server:/data/coolify/proxy/certs/

# Then on the server:
chmod 600 /data/coolify/proxy/certs/example.key
chmod 644 /data/coolify/proxy/certs/example.cert

Restart Traefik (the proxy container) so it picks up the new certificate. From the Coolify dashboard, go to Servers, find your server, click the proxy restart option. Or from the command line:

docker restart coolify-proxy

Once Traefik restarts, the custom certificate is used for any domain that matches its Common Name or Subject Alternative Name list, in preference to a Let's Encrypt cert.

Buying a paid SSL certificate from LumaDock at checkout

If you're ordering a Coolify VPS from LumaDock and you specifically want a paid CA-issued certificate (compliance reasons, enterprise procurement, EV/OV validation, branded green padlock), you can add a RapidSSL or RapidSSL Wildcard certificate to your order during checkout.

  • RapidSSL, single domain (covers example.com and the matching www.example.com)
  • RapidSSL Wildcard, covers all subdomains of one apex (e.g., *.example.com)

The advantage over rolling Let's Encrypt yourself is that LumaDock handles the issuance and validation paperwork for you. The advantage over Let's Encrypt itself is the longer cert lifetime (typically 1 year vs 90 days), the wider browser trust bundle and the support contract that comes with a paid CA. For most projects Let's Encrypt is fine, RapidSSL is the right choice when a procurement or compliance team specifically asks for a paid commercial CA.

Once LumaDock issues the cert and sends you the cert and key files, the upload flow is the same as any custom certificate above. Drop the files into /data/coolify/proxy/certs/, restart the proxy, Coolify picks them up.

Step 3, Coolify wildcard SSL certificates

Wildcard certificates (the *.example.com kind) cover any subdomain of a base domain with a single certificate. They're useful for preview deployments where each PR gets a unique subdomain or for any setup where you'd otherwise issue many individual certs.

The catch: Let's Encrypt won't issue wildcard certs through HTTP-01 challenge. Wildcard certs require DNS-01 challenge, where instead of fetching a file over HTTP, Let's Encrypt asks you to create a TXT record on the domain to prove control. That requires Traefik to have API access to your DNS provider so it can create and delete the TXT records on demand.

Setting up DNS-01 with Cloudflare

The most common setup, because Cloudflare's API is well-supported and free:

  1. In Cloudflare dashboard, go to My Profile → API Tokens → Create Token
  2. Use the "Edit zone DNS" template, scope to your specific zone
  3. Copy the token (you won't see it again)
  4. In Coolify, go to Servers → your server → settings → Proxy (or wherever the wildcard cert UI lives in your version)
  5. Configure the DNS-01 challenge with provider cloudflare and the API token
  6. Add the wildcard domain (*.example.com) to your application or service that needs it

Traefik creates the TXT record via Cloudflare's API, Let's Encrypt verifies, the wildcard cert issues. Renewal works the same way automatically.

Other DNS providers

Traefik supports many DNS providers via Lego (Cloudflare, Route 53, DigitalOcean, Hetzner, Linode, Vultr, OVH, Gandi, Namecheap and dozens of others). The setup pattern is the same: get an API key from the provider with permission to create TXT records, configure Coolify with the provider name and credentials, point at the wildcard domain.

Check the Coolify wildcard certs documentation for the current list of supported providers and the exact configuration syntax for each.

The Cloudflare proxy issue (most common Coolify SSL failure)

This is the single most common reason Coolify SSL fails for new users. The story:

You add a domain to Cloudflare. Cloudflare offers two modes for the A record, "DNS only" (gray cloud) and "Proxied" (orange cloud). The default for new records is Proxied. With Proxied mode on, Cloudflare intercepts incoming HTTP and HTTPS traffic, including the Let's Encrypt HTTP-01 challenge that needs to reach your server on port 80.

Result: Traefik thinks the challenge will work. Let's Encrypt makes the request. Cloudflare answers (because it's proxying) but the answer doesn't include the validation file Traefik created. Let's Encrypt fails the challenge. Coolify shows ACME errors. You're stuck.

The fix has two paths:

Path A: Switch Cloudflare to DNS only briefly

  1. In Cloudflare, set the A record's proxy status to DNS only (gray cloud)
  2. Wait a minute for the DNS change to propagate
  3. In Coolify, retry SSL or re-save the domain to retrigger the ACME challenge
  4. Once the cert is issued, switch Cloudflare back to Proxied (orange cloud)
  5. Set Cloudflare's SSL/TLS mode to Full (strict) in the SSL/TLS overview

Renewal will face the same problem 60 days later when Traefik tries to renew. You'd need to flip to DNS only briefly each time, which isn't great. Path B is the better long-term fix.

Path B: Use DNS-01 challenge instead

Switch the cert issuance method to DNS-01 (the same wildcard pattern from Step 3). DNS-01 works regardless of Cloudflare proxy status because the validation happens via DNS, not HTTP. Renewal also works automatically, no manual flips required.

This is the recommended setup if your domain is on Cloudflare and you want to use the proxy. Set up the Cloudflare API token, configure Coolify with the DNS-01 method, your certs (including renewals) just work.

Common Coolify SSL failures and how to fix them

ACME error: "no record found in DNS"

DNS hasn't propagated yet or the A record points at the wrong IP. Wait 5-10 minutes after creating the DNS record, then check propagation with dig +short app.example.com from your laptop. The result should be your Coolify server's IP. If it isn't, fix the DNS record.

ACME error: "fetching ... timeout" or "connection refused on port 80"

Port 80 is blocked. Either your firewall is blocking it (check ufw status on Ubuntu, ensure 80 and 443 are allowed) or your hosting provider has port 80 blocked at the network level (rare but happens with some VPS providers). Open port 80, retry SSL.

ACME error: "too many failed authorizations"

Let's Encrypt rate-limits failures. If you've been trying multiple times with broken DNS or Cloudflare proxy on, you can hit the limit. The lockout is per-domain, lasts about an hour. Wait, fix the actual problem (DNS, Cloudflare proxy, etc.), retry once. Avoid making rapid retries during this window.

"Certificate is for a different domain"

Traefik issued a cert but it's serving a default self-signed cert instead. Usually means the domain in your application's Domains tab doesn't match the host header browsers are sending. Check the exact spelling, including www vs apex and make sure the Domains tab includes every variant you're hitting.

SSL works on www but not the apex (or vice versa)

You added one but not the other. In Coolify's Domains tab, list both domains separated by a comma: https://example.com,https://www.example.com. Save, Traefik issues a cert covering both. Your DNS needs A records (or CNAMEs) for both as well.

"Certificate signed by unknown CA" warning in browsers

Your custom uploaded certificate is missing the intermediate CA chain. Recreate the cert file as the full chain (your domain cert plus intermediates plus root, in that order, concatenated into one PEM file). Upload again.

Wildcard cert doesn't cover sub-subdomains

By design. *.example.com covers app.example.com but not foo.app.example.com. For sub-subdomains you need either an additional wildcard (*.app.example.com) or to issue individual certs. The Coolify wildcard troubleshooting page covers the limits.

SSL renewal failed silently

Check the proxy logs (docker logs coolify-proxy on the host) for ACME errors near the renewal time. The most common cause is that something changed since initial issue (DNS pointing at a different server now, port 80 firewall added later, Cloudflare flipped to Proxied) and Traefik can no longer complete the challenge. Fix the underlying problem, force a renewal by removing the cert from acme.json and restarting Traefik.

Database SSL on Coolify

Quick adjacent topic. The SSL we've been discussing is for HTTP traffic. If you also need SSL for database connections (Postgres, MySQL connections from external tools), that's a separate setup. Coolify databases run inside the Docker network without SSL by default, which is fine for app-to-database traffic on the same host.

For external database connections, you'd expose the database port publicly (Coolify supports this in the database resource settings) and either use a self-signed cert with client cert verification or front the database with a TCP-layer proxy that adds TLS. The Coolify docs have a separate page on database SSL configuration.

So, what now?

SSL is one piece of the production puzzle. Once it's working, set up automated database backups (the Coolify backups guide covers Postgres, MySQL and MongoDB), monitoring (the Coolify monitoring guide covers Sentinel plus Prometheus and Grafana) and security hardening on the underlying server (the production server security guide covers SSH, firewall and Fail2ban patterns that apply regardless of runtime).

If you're setting up wildcard SSL specifically for preview deployments, the Coolify GitHub PR previews guide walks through the wildcard DNS setup paired with the GitHub App preview deploy feature.

Stop installing. Start shipping.

LumaDock Coolify plans come with the dashboard pre-installed, unmetered bandwidth and a flat monthly bill. Try the server risk free with a 30-day refund guarantee.

GPU products are in high demand at the moment. Fill the form to get notified as soon as your preferred GPU server is back in stock.