dokploy icon indicating copy to clipboard operation
dokploy copied to clipboard

Allow customisation of a domain's certResolver

Open benosman opened this issue 1 year ago • 3 comments

What problem will this feature address?

I have domains with different dns providers, and I want to set up multiple dns challenges for Let's Encrypt. I can do that in the traefik config but I need a way of choosing which certificates resolver to use when adding a domain.

Currently the resolver list is hardcoded here: https://github.com/Dokploy/dokploy/blob/379ea2ac65279b02f167b91374f8b2e193c376d2/apps/dokploy/components/dashboard/compose/domains/add-domain.tsx#L416-L418

Describe the solution you'd like

I would like the resolver list to be customisable, so I can add my additional certificate resolvers to this dropdown.

Describe alternatives you've considered

I have thought about manually editing the config for an app after adding a domain.

Additional context

This is how my traefik config looks

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme.json
      httpChallenge:
        entryPoint: web
  letsencrypt_hetzner:
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme_hetzner.json
      dnsChallenge:
        enabled: true
        provider: hetzner
        delayBeforeCheck: 3
  letsencrypt_route53:
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme_route53.json
      dnsChallenge:
        enabled: true
        provider: route53
        delayBeforeCheck: 3

I would like to add letsencrypt_hetzner and letsencrypt_route53 as certificate resolvers.

Will you send a PR to implement it?

Maybe, need help

benosman avatar Dec 26 '24 12:12 benosman

Good idea, currently there is no way to add provider's api keys.

docloulou avatar Jan 23 '25 22:01 docloulou

@docloulou I set the API Keys using environment variables on the Traefik instance, updated the traefik.yml with a new resolver, then updated the service's Traefik configuration (under Advanced for the service) to explicitly use the new resolver.

Settings > Server > Traefik > Environment

Under /dashboard/settings/server you can tap the Traefik button and "Modify Environment" where I set the CF_ZONE_API_TOKEN and CF_DNS_API_TOKEN in my case for use with Cloudflare DNS challenge provider.

CF_ZONE_API_TOKEN={zoneApiToken}
CF_DNS_API_TOKEN={dnsApiToken}
CLOUDFLARE_PROPAGATION_TIMEOUT=150

Settings > Traefik > traefik.yml

Then I added a new certificateResolvers entry in my traefik.yml with the dnsChallenge.provider = cloudflare:

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme.json
      dnsChallenge:
        provider: cloudflare # I might have just added this during testing and forgot to remove it
      httpChallenge:
        entryPoint: web
  letsencrypt-dns: # ✅ Added a new resolver with only the DNS Challenge
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:  # I also tweaked the DNS resolvers since I was having some DNS caching issues
          - 1.1.1.1:53
          - 1.0.0.1:53

Projects > My Project > My Service > Advanced > Traefik

For the particular Dokploy Service that I was configuring, it was a simple Node.js Application pulling from Github and automatically building with a Nixpack.

I originally was trying the default Domains section hoping my resolver would show up there like @benosman mentioned, but after trying that and it not working, I ended up using the Advanced tab of the service and at the very bottom under Traefik, I modified the configuration to explicitly use my new letsencrypt-dns resolver.

Something like:

http:
  routers:
    {project}-{service}-{instance}-router-3:
      rule: Host(`some.example.com`)
      service: {project}-{service}-{instance}-service-3
      middlewares:
        - redirect-to-https
      entryPoints:
        - web
    {project}-{service}-{instance}-router-websecure-3:
      rule: Host(`some.example.com`)
      service: {project}-{service}-{instance}-service-3
      middlewares: []
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt-dns # ✅ DNS-01 challenge
  services:
    {project}-{service}-{instance}-service-3:
      loadBalancer:
        servers:
          - url: http://{project}-{service}-{instance}:9003
        passHostHeader: true

docker-compose.yml alternative

For a Docker Compose project, I believe you could set the Traefik annotations as labels per the Dokploy Docker Compose example.

services:
   my-service:
      ...your config...
      expose:
         - 80
      network:
         - dokploy-network
      labels:
         - "traefik.enable=true"
         - "traefik.http.routers.<unique-name>.rule=Host(`your-domain.com`)"
         - "traefik.http.routers.<unique-name>.entrypoints=websecure"
         - "traefik.http.routers.<unique-name>.tls.certResolver=letsencrypt" # ✅ note the customization available here
         - "traefik.http.services.<unique-name>.loadbalancer.server.port=3000"

joshualyon avatar Jan 24 '25 22:01 joshualyon

I struggled a lot while trying to setup a DNS Challenge for Route53 managed subdomains.

What worked for me was a mix of @joshualyon solution with this topic Stackoverflow - Route53 DNS Challenge.

I'd also need to change the traefik.yml file as following:

...
certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme.json
      httpChallenge:
        entryPoint: web
  letsencrypt_dns: # ✅ Added a new resolver with only the DNS Challenge
    acme:
      email: [email protected]
      storage: /etc/dokploy/traefik/dynamic/acme_route53.json
      dnsChallenge:
        provider: route53 # <- It does the thing
        delayBeforeCheck: 0
...

This is most likely what @joshualyon did but using route53 provider instead.

Then I went to Settings > Web Server > Traefik > Modify Environment and added below env vars:

AWS_ACCESS_KEY_ID=iam_user_access_key
AWS_SECRET_ACCESS_KEY=iam_user_secret_key
AWS_HOSTED_ZONE_ID=domain_hosted_zone # You may find it on Route53 management tab
AWS_REGION=us-east-1 # Change according to your setup

If you follow Stackoverflow - Route53 DNS Challenge, you should have a custom IAM user for CertBot, so copy its credentials and fill into first AWS_ACCESS_KEY and AWS_SECRET_KEY variables.

Finally, don't forget to change your application certResolver with letsencrypt_dns or whatever you'd named it. Follow @joshualyon reply as example.

rickson-lima avatar Feb 11 '25 15:02 rickson-lima

In the next version you will be able to change the value, it will be an open field.

Siumauricio avatar Mar 09 '25 02:03 Siumauricio