Appearance
Provision TLS for a Custom Domain
When to Run This Runbook
Run this runbook every time an agency's custom domain transitions to verified status. Until TLS provisioning is automated (see v2 roadmap in the feature doc), the platform operator must manually register each verified domain in Dokploy so that Traefik can obtain a Let's Encrypt certificate and serve the domain over HTTPS.
Symptoms that indicate this runbook is needed:
- An agency admin reports that their custom domain shows as "Active" in the dashboard but is unreachable or shows a TLS warning in the browser.
- A new
verifiedrecord appears inidentity.agency_custom_domainsthat has no Dokploy domain entry yet.
Prerequisites
Before running this runbook, confirm:
Domain is
verifiedin the database. Run the following query against theidentityschema:sqlSELECT id, agency_id, hostname, status, verified_at FROM identity.agency_custom_domains WHERE hostname = '<hostname>' AND status = 'verified';If the query returns no rows, the domain is not yet verified. The agency admin must complete DNS verification first (see Agency Custom Domains — End-to-End Flow).
CNAME record points to
proxy.daramex.org. Confirm from a DNS lookup tool or terminal:bashdig CNAME <hostname> +short # Expected output: proxy.daramex.org.If the CNAME is missing or points elsewhere, ask the agency admin to add/correct their DNS records and wait for propagation before proceeding. Dokploy will fail to obtain a Let's Encrypt cert if the domain does not route to the server.
Dokploy access. You must have operator-level access to the Dokploy UI.
Step 1 — Log in to Dokploy
- Navigate to the Dokploy admin UI (internal URL — see infra ops docs).
- Sign in with your operator credentials.
Step 2 — Open the Panel Service
- From the Dokploy dashboard, click Applications.
- Locate the service that serves the DaraMex panel (typically named
daramex-panelor similar — confirm with the infra team if unsure). - Click on the service to open its detail view.
Step 3 — Add the Custom Domain
Click the Domains tab inside the service detail view.
Click Add Domain.
Fill in the fields:
Field Value Domain <hostname>(e.g.booking.kfc.com)HTTPS Enabled (checkbox checked) Certificate Let's Encrypt (select from dropdown) Port Match the panel service port (typically 3000) Click Save (or Add depending on Dokploy version).
Traefik will automatically initiate a Let's Encrypt ACME challenge. Certificate issuance typically completes within 30–90 seconds, assuming the CNAME is already propagated.
Step 4 — Verify the Certificate
Allow 60–90 seconds for cert issuance, then verify:
bash
# Check that the domain returns HTTP 200 and the cert is valid
curl -I https://<hostname>
# Check cert details
echo | openssl s_client -connect <hostname>:443 -servername <hostname> 2>/dev/null \
| openssl x509 -noout -dates -subjectExpected output:
HTTP/2 200(or redirect to the app route) in thecurlresponse.subject=CN = <hostname>in the cert output.notAfteris approximately 90 days from today (Let's Encrypt cert validity).
Failure Modes
DNS not pointing yet / propagation lag
Symptom: Cert issuance fails; Traefik logs show acme: error: 403 :: urn:ietf:params:acme:error:unauthorized or NXDOMAIN.
Resolution:
- Confirm the CNAME is set correctly with
dig CNAME <hostname> +short. - If the CNAME resolves correctly but issuance still fails, wait for propagation (up to 48 hours for high-TTL zones) and retry by removing and re-adding the domain in Dokploy.
- If the CNAME is not set, ask the agency admin to add it and wait for propagation.
Let's Encrypt rate limit exceeded
Symptom: Cert issuance fails with urn:ietf:params:acme:error:rateLimited in Traefik logs. Let's Encrypt enforces 5 certificates per registered domain per week (and account-level limits).
Resolution options:
- Wait 7 days. The rate limit window resets automatically.
- Use Let's Encrypt staging to test certificate issuance without consuming production quota (configure Traefik with the LE staging CA URL; staging certs are not trusted by browsers, so this is only for operator testing).
- If the same domain is being re-issued frequently (e.g. after repeated Dokploy domain removes/re-adds), avoid unnecessary changes to the domain entry.
Reference: Let's Encrypt Rate Limits
Certificate not renewing automatically
Symptom: notAfter date is within 30 days (Traefik should auto-renew before then) or the cert has already expired.
Resolution:
Check Traefik logs for renewal errors:
bash# On the Dokploy server or via Dokploy log viewer: docker logs <traefik-container-name> 2>&1 | grep -i "acme\|certificate\|renew"Common causes:
- The CNAME was removed or changed by the agency admin after initial provisioning → re-point the CNAME and wait for Traefik to retry renewal.
- ACME account key issue → may require recreating the Traefik ACME storage file (consult infra team).
- Let's Encrypt rate limit hit during renewal → wait and monitor.
If the cert cannot be renewed automatically and is expired, the domain will show a TLS error to end-users. Escalate to the infra team.
Agency removes domain from dashboard but cert is still active in Dokploy
Symptom: The agency_custom_domains record is in removed status, but Dokploy still shows the domain and Traefik still serves traffic from it.
Resolution:
- Open the Domains tab for the service in Dokploy.
- Find the domain entry for the removed hostname.
- Click Remove (or the trash icon).
- Traefik will stop routing traffic for that hostname.
The Redis key agency:host:<hostname> is invalidated automatically by the API on domain removal, so the tenant resolution returns 404 immediately. The Dokploy cleanup is a secondary step to free the Let's Encrypt quota and stop serving the (now-invalid) TLS cert.
Rollback
If you need to remove a domain from Dokploy (e.g. the agency removed it from the dashboard or a configuration error occurred):
- Open the Domains tab for the panel service in Dokploy.
- Find the domain row for the hostname.
- Click Remove.
- Traefik stops routing and certificate renewal for that hostname.
Removing the domain from Dokploy has no effect on the agency_custom_domains record in the database — those are managed exclusively through the API. Removing from Dokploy only stops TLS termination and routing at the infrastructure layer.