Dokploy / Dokploy/dokploy

Cloudflare Origin CA: "Certificate: None" does not stop Let's Encrypt for the domain (websecure entrypoint default)

Open
#4,949 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage🔍
Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

To Reproduce
  1. Deploy an application and create a domain with Certificate: Let's Encrypt. Wait until Traefik has issued the certificate, so that an entry for the hostname exists in /etc/dokploy/traefik/dynamic/acme.json.
  2. In the Cloudflare dashboard, go to SSL/TLS > Origin Server > Create Certificate and create an Origin CA certificate covering the domain, for example example.com and *.example.com, valid for 15 years.
  3. In Dokploy, go to Certificates > Add Certificate and paste the Origin Certificate and Private Key, following Using Cloudflare's Origin CA.
  4. Edit the existing domain and change the Certificate field from Let's Encrypt to None.
  5. In Cloudflare, set the SSL/TLS encryption mode to Full (Strict).
  6. On the server, check which certificate Traefik actually serves for that hostname:
echo | openssl s_client -connect 127.0.0.1:443 -servername app.example.com 2>/dev/null \
  | openssl x509 -noout -issuer -enddate
Current vs. Expected behavior

Current behavior

Traefik keeps serving the old Let's Encrypt certificate, not the Origin CA one:

issuer=C = US, O = Let's Encrypt, CN = R12
notAfter=Jul 28 14:45:05 2026 GMT

Traefik also keeps attempting to renew it. Once that certificate expires, Cloudflare returns Error 526 (Invalid SSL certificate) in Full (Strict) mode, even though the Origin CA certificate was uploaded correctly and the domain is set to Certificate: None. Nothing in the UI indicates which certificate is in use, so the setup looks correct while the site is down.

Expected behavior

Setting Certificate: None should stop Let's Encrypt for that domain and let the uploaded Origin CA certificate take over.

Workaround

Removing the hostname's entry from acme.json and restarting Traefik makes the Origin CA certificate take over immediately. On my instance all 13 hostnames switched to CloudFlare Origin SSL Certificate Authority (valid until 2041) with no other change.

Provide environment information
Operating System:
  OS: Ubuntu 24.04.4 LTS
  Arch: x86_64
  Kernel: 6.8.0-136-generic
Dokploy version: v0.29.13
Traefik version: v3.6.7
Docker version: 29.4.1 (Swarm active)
VPS Provider: Hetzner
What applications/services are you trying to deploy?
  Next.js apps, Node APIs, PostgreSQL, MinIO, Redis, Uptime Kuma
Which area(s) are affected? (Select all that apply)

Traefik, Application

Are you deploying the applications where Dokploy is installed or on a remote server?

Same server where Dokploy is installed

Additional context

Two separate mechanisms seem to be involved.

1. Certificate: None only clears the router-level resolver.

The websecure entrypoint carries an instance-wide default that applies to every router which does not define its own TLS block, so the router still falls back to the ACME resolver.

packages/server/src/setup/traefik-setup.ts L286-L298:

websecure: {
  address: `:${TRAEFIK_SSL_PORT}`,
  http3: { advertisedPort: TRAEFIK_HTTP3_PORT },
  ...(process.env.NODE_ENV === "production" && {
    http: { tls: { certResolver: "letsencrypt" } },
  }),
},

The same block exists unconditionally in getDefaultServerTraefikConfig (L344-L354), while Certificate: None only skips the per-router assignment in packages/server/src/utils/traefik/domain.ts L213-L217.

2. Certificate selection favours the old certificate.

Traefik picks the more specific match, so a Let's Encrypt certificate with DNS:app.example.com wins over an Origin CA certificate with DNS:*.example.com. I confirmed this on my instance: hostnames that only the wildcard could match were already served the Origin CA certificate, while hostnames with an exact-match Let's Encrypt entry kept the expired one.

What I could not verify

My ACME challenges were being intercepted by Cloudflare Access, so Traefik could never obtain a new Let's Encrypt certificate. I therefore could not observe whether, on an instance where ACME succeeds, the entrypoint default causes a fresh certificate to be issued for a Certificate: None domain and shadow the Origin CA one. That last link is inferred from Traefik's documented entrypoint-default semantics, not measured. It would be good if someone could confirm it.

Possible directions

  • Do not set certResolver at the entrypoint level, and rely on the per-router value Dokploy already writes for Let's Encrypt domains. Mixed setups keep working, since those routers carry their own tls.certResolver.
  • Or, when a domain is switched away from Let's Encrypt, drop its entry from acme.json.
  • At minimum, document the migration path. I have opened a docs PR for this: Dokploy/website#172

Related to #1839, which asked for Origin CA support before the Certificates feature existed.

Will you send a PR to fix it?

Maybe, need help

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading packages/server/src/setup/traefik-setup.ts, especially the websecure configuration in lines 286-298 and getDefaultServerTraefikConfig, then compare it with packages/server/src/utils/traefik/domain.ts lines 213-217. Reproduce the behavior with a domain changed from Let's Encrypt to None and inspect the generated Traefik configuration and served certificate. Done means the intended certificate is selected and ACME does not continue for the None domain, with mixed certificate configurations still working.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, typescript
Domain
devops, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.