[GH-ISSUE #176] How to use acme-dns with Traefik in a docker container? #71

Open
opened 2026-03-13 15:39:36 +03:00 by kerem · 12 comments
Owner

Originally created by @fairwood136 on GitHub (Aug 28, 2019).
Original GitHub issue: https://github.com/acme-dns/acme-dns/issues/176

Do you have an example of using Traefik (v2.0) using acme-dns in a docker container? I've used acme-dns in a container by itself, and it works great. When I add Traefik to the mix, I run into issues. Either I get a 504 Bad Gateway error or it can't talk to port 53.

Any ideas?

Originally created by @fairwood136 on GitHub (Aug 28, 2019). Original GitHub issue: https://github.com/acme-dns/acme-dns/issues/176 Do you have an example of using Traefik (v2.0) using acme-dns in a docker container? I've used acme-dns in a container by itself, and it works great. When I add Traefik to the mix, I run into issues. Either I get a 504 Bad Gateway error or it can't talk to port 53. Any ideas?
Author
Owner

@joohoi commented on GitHub (Sep 3, 2019):

Unfortunately I haven't personally tested such scenario.

<!-- gh-comment-id:527348341 --> @joohoi commented on GitHub (Sep 3, 2019): Unfortunately I haven't personally tested such scenario.
Author
Owner

@mrybak-ng commented on GitHub (Sep 27, 2019):

@fairwood136 do you have any solution to this issue?

<!-- gh-comment-id:536087520 --> @mrybak-ng commented on GitHub (Sep 27, 2019): @fairwood136 do you have any solution to this issue?
Author
Owner

@sbocinec commented on GitHub (Nov 7, 2019):

@fairwood136 / @mrybak-ng Traefik v1 is only a L7/HTTP load balancer/proxy, it can not handle TCP/UDP traffic so it was technically not possible to have neither tcp/53 not udp/53 working behind the proxy. Traefik v2 that has been released recently (mid Sept 2019) can now handle also TCP traffic, however, for the DNS server to work properly and securely, you need the proxy to handle the udp/53 port, what neither the traefik v2 can do.

You can still use traefik to handle the API HTTP requests for acme-dns but to have the DNS working you need to look elsewhere.

<!-- gh-comment-id:551091641 --> @sbocinec commented on GitHub (Nov 7, 2019): @fairwood136 / @mrybak-ng Traefik v1 is only a L7/HTTP load balancer/proxy, it can not handle TCP/UDP traffic so it was technically not possible to have neither tcp/53 not udp/53 working behind the proxy. Traefik v2 that has been released recently (mid Sept 2019) can now handle also TCP traffic, however, for the DNS server to work properly and securely, you need the proxy to handle the udp/53 port, what neither the traefik v2 can do. You can still use traefik to handle the API HTTP requests for acme-dns but to have the DNS working you need to look elsewhere.
Author
Owner

@justinvoelker commented on GitHub (Feb 11, 2020):

Though I'm slightly clueless about the technical details of how this needs to be implemented to work for us (using Traefik v2), might this just-merged PR be the ticket to getting this working?

Maybe not. I just built the traefik container from source and am still receiving the 502 gateway error.

<!-- gh-comment-id:584435254 --> @justinvoelker commented on GitHub (Feb 11, 2020): ~~Though I'm slightly clueless about the technical details of how this needs to be implemented to work for us (using Traefik v2), might [this just-merged PR](https://github.com/containous/traefik/pull/6172) be the ticket to getting this working?~~ Maybe not. I just built the traefik container from source and am still receiving the 502 gateway error.
Author
Owner

@justinvoelker commented on GitHub (Feb 13, 2020):

After three nights of effort, I have acme-dns working with Traefik v2. Not sure about your setup, but under v1 I had Traefik handle the HTTP traffic and simple exposed ports for the DNS portion (both TCP and UDP). When that didn't work with v2, I tried building Traefik from source to try the very recent updates that included UDP routing.

When nothing worked, I started over. Why didn't the same basic setup from v1 (Traefik for HTTP, exposed ports for DNS) work for v2? I don't know why, but it turns out that the typical "traefik.port=80" from v1 for the HTTP traffic does not work in this situation (I believe it has to do with the image exposing multiple ports). Something I found when trying to work with TCP/UDP was that you can directly assign ports to a router via a service. In the config below, I added the last two lines which tell the router to use a new service and define that service along with the port it should use.

- "traefik.enable=true"
- "traefik.http.routers.acme-dns.entrypoints=http,https"
- "traefik.http.routers.acme-dns.priority=20"
- "traefik.http.routers.acme-dns.rule=Host(`acme-dns.example.com`)"
- "traefik.http.routers.acme-dns.service=acme-dns"
- "traefik.http.services.acme-dns.loadbalancer.server.port=80"

With this config I was able to successfully pull a new wildcard certificate just a few minutes ago.

<!-- gh-comment-id:586005930 --> @justinvoelker commented on GitHub (Feb 13, 2020): After three nights of effort, I have acme-dns working with Traefik v2. Not sure about your setup, but under v1 I had Traefik handle the HTTP traffic and simple exposed ports for the DNS portion (both TCP and UDP). When that didn't work with v2, I tried building Traefik from source to try the very recent updates that included UDP routing. When nothing worked, I started over. Why didn't the same basic setup from v1 (Traefik for HTTP, exposed ports for DNS) work for v2? I don't know why, but it turns out that the typical "traefik.port=80" from v1 for the HTTP traffic does not work in this situation (I believe it has to do with the image exposing multiple ports). Something I found when trying to work with TCP/UDP was that you can directly assign ports to a router via a service. In the config below, I added the last two lines which tell the router to use a new service and define that service along with the port it should use. ``` - "traefik.enable=true" - "traefik.http.routers.acme-dns.entrypoints=http,https" - "traefik.http.routers.acme-dns.priority=20" - "traefik.http.routers.acme-dns.rule=Host(`acme-dns.example.com`)" - "traefik.http.routers.acme-dns.service=acme-dns" - "traefik.http.services.acme-dns.loadbalancer.server.port=80" ``` With this config I was able to successfully pull a new wildcard certificate just a few minutes ago.
Author
Owner

@totti777 commented on GitHub (Mar 6, 2020):

Hi @justinvoelker ,

Could you paste your docker-compose.yml and how you configure config of acme-dns? Please it's impossible for me configure acme-dns and traefik, I need to validate certificates with dns-challange.

Regards,

<!-- gh-comment-id:595709427 --> @totti777 commented on GitHub (Mar 6, 2020): Hi @justinvoelker , Could you paste your docker-compose.yml and how you configure config of acme-dns? Please it's impossible for me configure acme-dns and traefik, I need to validate certificates with dns-challange. Regards,
Author
Owner

@justinvoelker commented on GitHub (Mar 8, 2020):

@totti777 If you walk through the README document of this project it has a thorough walk through of setting up acme-dns that is easy to adapt to Traefik v1. Not sure if you are trying v1 or v2 but our problems here were using Traefik v2 and the small change to the labels I posted above are all that is necessary to move from Traefik v1 to v2.

@fairwood136 or @joohoi this issue can be closed since the addition of the Traefik v2 service config with loadbalancer port produces a working result.

<!-- gh-comment-id:596210752 --> @justinvoelker commented on GitHub (Mar 8, 2020): @totti777 If you walk through the README document of this project it has a thorough walk through of setting up acme-dns that is easy to adapt to Traefik v1. Not sure if you are trying v1 or v2 but our problems here were using Traefik v2 and the small change to the labels I posted above are all that is necessary to move from Traefik v1 to v2. @fairwood136 or @joohoi this issue can be closed since the addition of the Traefik v2 service config with loadbalancer port produces a working result.
Author
Owner

@Kugelschieber commented on GitHub (Dec 5, 2020):

In case anyone is looking for this, here is my working configuration. It also runs an additional container for a docker registry (not included here), so you should be able to add more services without interfering with acme-dns. I had to look up the service name for acme-dns on the Traefik dashboard. The server is called "utility" and therefore the service is acmedns-utility. This might be different for you. Notice that I have removed the domain name, paths to volumes, and my mail address. You should adjust them to your needs.

version: "3"

services:
  traefik:
    image: traefik:v2.3
    container_name: traefik
    restart: always
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"

      # Entrypoints for HTTP, HTTPS, and NX (TCP + UDP)
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.dns-tcp.address=:53"
      - "--entrypoints.dns-udp.address=:53/udp"

      # Letsencrypt
      - "--certificatesresolvers.tls-resolver.acme.httpchallenge=true"
      - "--certificatesresolvers.tls-resolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.tls-resolver.acme.email=..."
      - "--certificatesresolvers.tls-resolver.acme.storage=/letsencrypt/acme.json"
    ports:
      # Expose all required ports, including 53 TCP AND UDP
      - "80:80"
      - "443:443"
      - "53:53"
      - "53:53/udp"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

      # Persist certificates, so we can restart as often as needed
      - /where/ever/you/want/letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      - "traefik.port=9999"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=tls-resolver"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=..."

      # Global redirection: http to https
      - 'traefik.http.routers.http-catchall.rule=HostRegexp(`{host:(www\.)?.+}`)'
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=wwwtohttps"
      
      # Global redirection: https (www.) to https
      - 'traefik.http.routers.wwwsecure-catchall.rule=HostRegexp(`{host:(www\.).+}`)'
      - "traefik.http.routers.wwwsecure-catchall.entrypoints=websecure"
      - "traefik.http.routers.wwwsecure-catchall.tls=true"
      - "traefik.http.routers.wwwsecure-catchall.middlewares=wwwtohttps"
      
      # middleware: http(s)://(www.) to  https://
      - 'traefik.http.middlewares.wwwtohttps.redirectregex.regex=^https?://(?:www\.)?(.+)'
      - 'traefik.http.middlewares.wwwtohttps.redirectregex.replacement=https://$${1}'
      - 'traefik.http.middlewares.wwwtohttps.redirectregex.permanent=true'
  postgres:
    image: postgres:13-alpine
    container_name: postgres
    restart: always
    ports:
      - "5432:5432"
    env_file:
      - secrets
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - /where/ever/you/want/pgdata:/var/lib/postgresql/data/pgdata
  acmedns:
    restart: always
    image: joohoi/acme-dns:v0.8
    container_name: acmedns
    depends_on:
      - postgres
      - traefik
    volumes:
      - /where/ever/you/want/config:/etc/acme-dns:ro
      - /where/ever/you/want/data:/var/lib/acme-dns
    labels:
      - "traefik.enable=true"

      # Router for HTTPS API
      - "traefik.http.routers.acmedns-https.service=acmedns-https"
      - "traefik.http.routers.acmedns-https.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.acmedns-https.entrypoints=websecure"
      - "traefik.http.routers.acmedns-https.tls=true"
      - "traefik.http.routers.acmedns-https.tls.certresolver=tls-resolver"

      # Another router for the HTTP API. Don't know if this is actually required
      - "traefik.http.routers.acmedns-http.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.acmedns-http.service=acmedns-http"
      - "traefik.http.routers.acmedns-http.entrypoints=web"

      # TCP router (notice it's HostSNI, not Host!)
      - "traefik.tcp.routers.acmedns-dns.rule=HostSNI(`auth.example.com`)"
      - "traefik.tcp.routers.acmedns-dns.service=acmedns-utility" # I had to figure out the service name from the Traefik dashboard...
      - "traefik.tcp.routers.acmedns-dns.entrypoints=dns-tcp"

      # UDP router (no rule here!)
      - "traefik.udp.routers.acmedns-dns.service=acmedns-utility" # I had to figure out the service name from the Traefik dashboard...
      - "traefik.udp.routers.acmedns-dns.entrypoints=dns-udp"

      # Explicitly define services for HTTPS, HTTP, and DNS
      - "traefik.http.services.acmedns-https.loadbalancer.server.port=443"
      - "traefik.http.services.acmedns-http.loadbalancer.server.port=80"
      - "traefik.http.services.acmedns-dns.loadbalancer.server.port=53"
<!-- gh-comment-id:739402400 --> @Kugelschieber commented on GitHub (Dec 5, 2020): In case anyone is looking for this, here is my working configuration. It also runs an additional container for a docker registry (not included here), so you should be able to add more services without interfering with acme-dns. I had to look up the service name for acme-dns on the Traefik dashboard. The server is called "utility" and therefore the service is acmedns-utility. This might be different for you. Notice that I have removed the domain name, paths to volumes, and my mail address. You should adjust them to your needs. ```yaml version: "3" services: traefik: image: traefik:v2.3 container_name: traefik restart: always command: - "--api.dashboard=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" # Entrypoints for HTTP, HTTPS, and NX (TCP + UDP) - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.dns-tcp.address=:53" - "--entrypoints.dns-udp.address=:53/udp" # Letsencrypt - "--certificatesresolvers.tls-resolver.acme.httpchallenge=true" - "--certificatesresolvers.tls-resolver.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.tls-resolver.acme.email=..." - "--certificatesresolvers.tls-resolver.acme.storage=/letsencrypt/acme.json" ports: # Expose all required ports, including 53 TCP AND UDP - "80:80" - "443:443" - "53:53" - "53:53/udp" volumes: - /var/run/docker.sock:/var/run/docker.sock # Persist certificates, so we can restart as often as needed - /where/ever/you/want/letsencrypt:/letsencrypt labels: - "traefik.enable=true" - "traefik.port=9999" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.tls.certresolver=tls-resolver" - "traefik.http.routers.traefik.middlewares=traefik-auth" - "traefik.http.middlewares.traefik-auth.basicauth.users=..." # Global redirection: http to https - 'traefik.http.routers.http-catchall.rule=HostRegexp(`{host:(www\.)?.+}`)' - "traefik.http.routers.http-catchall.entrypoints=web" - "traefik.http.routers.http-catchall.middlewares=wwwtohttps" # Global redirection: https (www.) to https - 'traefik.http.routers.wwwsecure-catchall.rule=HostRegexp(`{host:(www\.).+}`)' - "traefik.http.routers.wwwsecure-catchall.entrypoints=websecure" - "traefik.http.routers.wwwsecure-catchall.tls=true" - "traefik.http.routers.wwwsecure-catchall.middlewares=wwwtohttps" # middleware: http(s)://(www.) to https:// - 'traefik.http.middlewares.wwwtohttps.redirectregex.regex=^https?://(?:www\.)?(.+)' - 'traefik.http.middlewares.wwwtohttps.redirectregex.replacement=https://$${1}' - 'traefik.http.middlewares.wwwtohttps.redirectregex.permanent=true' postgres: image: postgres:13-alpine container_name: postgres restart: always ports: - "5432:5432" env_file: - secrets environment: PGDATA: /var/lib/postgresql/data/pgdata volumes: - /where/ever/you/want/pgdata:/var/lib/postgresql/data/pgdata acmedns: restart: always image: joohoi/acme-dns:v0.8 container_name: acmedns depends_on: - postgres - traefik volumes: - /where/ever/you/want/config:/etc/acme-dns:ro - /where/ever/you/want/data:/var/lib/acme-dns labels: - "traefik.enable=true" # Router for HTTPS API - "traefik.http.routers.acmedns-https.service=acmedns-https" - "traefik.http.routers.acmedns-https.rule=Host(`auth.example.com`)" - "traefik.http.routers.acmedns-https.entrypoints=websecure" - "traefik.http.routers.acmedns-https.tls=true" - "traefik.http.routers.acmedns-https.tls.certresolver=tls-resolver" # Another router for the HTTP API. Don't know if this is actually required - "traefik.http.routers.acmedns-http.rule=Host(`auth.example.com`)" - "traefik.http.routers.acmedns-http.service=acmedns-http" - "traefik.http.routers.acmedns-http.entrypoints=web" # TCP router (notice it's HostSNI, not Host!) - "traefik.tcp.routers.acmedns-dns.rule=HostSNI(`auth.example.com`)" - "traefik.tcp.routers.acmedns-dns.service=acmedns-utility" # I had to figure out the service name from the Traefik dashboard... - "traefik.tcp.routers.acmedns-dns.entrypoints=dns-tcp" # UDP router (no rule here!) - "traefik.udp.routers.acmedns-dns.service=acmedns-utility" # I had to figure out the service name from the Traefik dashboard... - "traefik.udp.routers.acmedns-dns.entrypoints=dns-udp" # Explicitly define services for HTTPS, HTTP, and DNS - "traefik.http.services.acmedns-https.loadbalancer.server.port=443" - "traefik.http.services.acmedns-http.loadbalancer.server.port=80" - "traefik.http.services.acmedns-dns.loadbalancer.server.port=53" ```
Author
Owner

@kadaan commented on GitHub (Jun 14, 2021):

@Kugelschieber Thanks for the docker-compose config. What does the config file for acme-dns look like?

<!-- gh-comment-id:860793878 --> @kadaan commented on GitHub (Jun 14, 2021): @Kugelschieber Thanks for the docker-compose config. What does the config file for acme-dns look like?
Author
Owner

@Kugelschieber commented on GitHub (Jun 14, 2021):

That should look something like this:

version: '3'

services:
  postgres:
    image: postgres:11-alpine
    container_name: postgres
    restart: always
    ports:
      - "5432:5432"
    env_file:
      - secrets
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - /home/user/acmedns/pgdata:/var/lib/postgresql/data/pgdata
  acmedns:
    restart: always
    image: joohoi/acme-dns:v0.8
    container_name: acmedns
    depends_on:
      - postgres
    ports:
      - "443:443"
      - "53:53"
      - "53:53/udp"
      - "80:80"
    volumes:
      - /home/user/acmedns/config:/etc/acme-dns:ro
      - /home/user/acmedns/data:/var/lib/acme-dns
<!-- gh-comment-id:860800358 --> @Kugelschieber commented on GitHub (Jun 14, 2021): That should look something like this: ```yaml version: '3' services: postgres: image: postgres:11-alpine container_name: postgres restart: always ports: - "5432:5432" env_file: - secrets environment: PGDATA: /var/lib/postgresql/data/pgdata volumes: - /home/user/acmedns/pgdata:/var/lib/postgresql/data/pgdata acmedns: restart: always image: joohoi/acme-dns:v0.8 container_name: acmedns depends_on: - postgres ports: - "443:443" - "53:53" - "53:53/udp" - "80:80" volumes: - /home/user/acmedns/config:/etc/acme-dns:ro - /home/user/acmedns/data:/var/lib/acme-dns ```
Author
Owner

@kadaan commented on GitHub (Jun 14, 2021):

@Kugelschieber Did you configure any of the acme-dns specific options in the config.cfg file (this one: https://github.com/joohoi/acme-dns/blob/master/config.cfg)

I'm wondering about how those two config (docker-compose.yml and config.cfg) interact.

<!-- gh-comment-id:860815827 --> @kadaan commented on GitHub (Jun 14, 2021): @Kugelschieber Did you configure any of the acme-dns specific options in the config.cfg file (this one: https://github.com/joohoi/acme-dns/blob/master/config.cfg) I'm wondering about how those two config (docker-compose.yml and config.cfg) interact.
Author
Owner

@Kugelschieber commented on GitHub (Jun 14, 2021):

Hmm, I didn't make any special changes to that file. You just need to make sure the ports are open.

<!-- gh-comment-id:860821556 --> @Kugelschieber commented on GitHub (Jun 14, 2021): Hmm, I didn't make any special changes to that file. You just need to make sure the ports are open.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/acme-dns#71
No description provided.