Add a Custom Domain and SSL to a Dokploy App
22 Oct 2025Getting a real domain and a valid certificate onto a Dokploy app takes about five minutes, most of which is DNS. Here’s the full path, including the Let’s Encrypt challenge Traefik handles for you:
sequenceDiagram
participant You
participant DNS
participant Traefik
participant LE as LetsEncrypt
You->>DNS: Point A record at server IP
You->>Traefik: Add domain and enable HTTPS
Traefik->>LE: Request certificate
LE->>Traefik: HTTP-01 challenge on port 80
Traefik-->>LE: Challenge response
LE-->>Traefik: Certificate issued
1. Point DNS at your server
Create an A record for your domain pointing to the server’s public IP:
Type: A
Name: app (or @ for the root domain)
Value: 203.0.113.42
TTL: 300
Use a low TTL like 300 while you are setting things up. Raise it later.
If you use Cloudflare, set the record to DNS only (grey cloud) for now. Let’s Encrypt needs to reach your server directly to complete the HTTP challenge. You can turn the proxy back on afterwards.
Verify it resolves before continuing:
dig +short app.example.com
You should see your server IP. If you see nothing, wait — do not proceed.
2. Add the domain in Dokploy
Open the application → Domains → Add Domain:
- Host:
app.example.com - Path:
/ - Container Port: whatever your app listens on, e.g.
3000 - HTTPS: on
- Certificate Provider: Let’s Encrypt
Save. Traefik picks up the change and requests a certificate within a few seconds.
3. Confirm the certificate issued
curl -sI https://app.example.com | head -1
A 200 or 302 means you are done. If you get a certificate error, check the Traefik logs:
docker service logs dokploy-traefik --tail 50
Common failures
Port 80 is blocked. The HTTP-01 challenge needs inbound port 80 even though your site runs on 443. Open it:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Rate limited. Let’s Encrypt allows 5 failed attempts per hostname per hour. If you have been retrying a broken config, wait an hour. Test with the staging issuer first next time.
Cloudflare proxy on with Flexible SSL. This creates a redirect loop. If you proxy through Cloudflare, set SSL mode to Full (Strict), not Flexible.
Wrong container port. Traefik gets a certificate but every request returns 502. The domain is fine; the port is wrong. Check what your app actually binds to.
Force HTTPS and add www
Add a second domain entry for www.app.example.com if you want it to work, and enable the HTTPS redirect toggle so plain HTTP visitors get bumped to TLS. Pick one canonical hostname and redirect the other — do not serve both, it splits your SEO.
Renewal
Traefik renews automatically at 30 days remaining. You do not need a cron job. What you do need is to keep port 80 open, because renewal uses the same challenge as issuance. Closing it three months later is a classic delayed outage.