0

I have a basic docker compose file with two services: traefik and nginx

services:

  traefik:
    image: traefik:v3.2
    command:
    # - "--api.debug=true"
    - "--log.level=DEBUG"
    - "--api.insecure=true"
    - "--providers.file.directory=/etc/traefik"
    - "--providers.file.watch=true"
    - "--entryPoints.web.address=:80"
    - "--entryPoints.websecure.address=:443"
    - "[email protected]"
    - "--certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme.json"
    - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
    - "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
    # - "--serverstransport.insecureskipverify"
    depends_on:
    - nginx
    volumes:
      - ./traefik:/etc/traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    restart: "unless-stopped"

  nginx:
    image: nginx:latest
    ports:
      - "80"
    volumes:
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/conf/conf.d:/etc/nginx/conf.d
      - ./nginx/data:/usr/share/nginx
    restart: "unless-stopped"

my traefik dynamic config is the following:

http:
  routers:
    nginx:
      entrypoints:
      - web
      - websecure
      rule: "Host(`www.host1.com`) || Host(`www.host2.com`) || Host(`host1.com`) || Host(`host2.com`)"
      service: nginx
  middlewares:
    redirect-to-https:
      redirectScheme:
        permanent: true
        scheme: https
  services:
    nginx:
      loadBalancer:
        servers:
        - url: http://nginx/

When i spin up the compose environment, I see an empty acme.json file created under ./traefik. I cannot make it generate a certificate (here using the staging acme server, but same happens with prod).

root@cloud:~/cloud# docker compose up
[+] Running 3/1
 ✔ Network cloud_default      Created                                                                                                                                                0.1s
 ✔ Container cloud-nginx-1    Created                                                                                                                                                0.0s
 ✔ Container cloud-traefik-1  Created                                                                                                                                                0.0s
Attaching to nginx-1, traefik-1
nginx-1    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx-1    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx-1    | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx-1    | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
nginx-1    | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
nginx-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx-1    | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: using the "epoll" event method
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: nginx/1.25.4
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: OS: Linux 5.15.0-125-generic
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: start worker processes
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: start worker process 29
nginx-1    | 2024/11/11 12:00:56 [notice] 1#1: start worker process 30
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/cmd/traefik/traefik.go:103 > Traefik version 3.2.0 built on 2024-10-28T14:49:00Z version=3.2.0
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/cmd/traefik/traefik.go:110 > Static configuration loaded [json] staticConfiguration={"api":{"dashboard":true,"insecure":true},"certificatesResolvers":{"myresolver":{"acme":{"caServer":"https://acme-staging-v02.api.letsencrypt.org/directory","certificatesDuration":2160,"email":"[email protected]","httpChallenge":{"entryPoint":"web"},"keyType":"RSA4096","storage":"/etc/traefik/acme.json"}}},"entryPoints":{"traefik":{"address":":8080","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}},"web":{"address":":80","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}},"websecure":{"address":":443","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}}},"global":{"checkNewVersion":true},"log":{"format":"common","level":"DEBUG"},"providers":{"file":{"directory":"/etc/traefik","watch":true},"providersThrottleDuration":"2s"},"serversTransport":{"maxIdleConnsPerHost":200},"tcpServersTransport":{"dialKeepAlive":"15s","dialTimeout":"30s"}}
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/cmd/traefik/traefik.go:626 >
traefik-1  | Stats collection is disabled.
traefik-1  | Help us improve Traefik by turning this feature on :)
traefik-1  | More details on: https://doc.traefik.io/traefik/contributing/data-collection/
traefik-1  |
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:73 > Starting provider aggregator aggregator.ProviderAggregator
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/server_entrypoint_tcp.go:231 > Starting TCP Server entryPointName=web
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/server_entrypoint_tcp.go:231 > Starting TCP Server entryPointName=websecure
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/server_entrypoint_tcp.go:231 > Starting TCP Server entryPointName=traefik
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *file.Provider
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *file.Provider provider configuration config={"directory":"/etc/traefik","watch":true}
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/file/file.go:122 > add watcher on: /etc/traefik
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/file/file.go:122 > add watcher on: /etc/traefik/.gitignore
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/file/file.go:122 > add watcher on: /etc/traefik/acme.json
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/file/file.go:122 > add watcher on: /etc/traefik/base.yml
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *traefik.Provider
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *traefik.Provider provider configuration config={}
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *acme.Provider
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *acme.Provider provider configuration config={"HTTPChallengeProvider":{},"ResolverName":"myresolver","TLSChallengeProvider":{},"caServer":"https://acme-staging-v02.api.letsencrypt.org/directory","certificatesDuration":2160,"email":"[email protected]","httpChallenge":{"entryPoint":"web"},"keyType":"RSA4096","storage":"/etc/traefik/acme.json","store":{}}
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:221 > Attempt to renew certificates "720h0m0s" before expiry and check every "24h0m0s" acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory providerName=myresolver.acme
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:859 > Testing certificate renew... acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory providerName=myresolver.acme
traefik-1  | 2024-11-11T12:00:56Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *acme.ChallengeTLSALPN
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *acme.ChallengeTLSALPN provider configuration config={}
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{"middlewares":{"redirect-to-https":{"redirectScheme":{"permanent":true,"scheme":"https"}}},"routers":{"nginx":{"entryPoints":["web","websecure"],"rule":"Host(`www.host1.com`) || Host(`www.host2.com`) || Host(`host1.com`) || Host(`host2.com`)","service":"nginx"}},"services":{"nginx":{"loadBalancer":{"passHostHeader":true,"responseForwarding":{"flushInterval":"100ms"},"servers":[{"url":"http://nginx/"}]}}}},"tcp":{},"tls":{},"udp":{}} providerName=file
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{"middlewares":{"dashboard_redirect":{"redirectRegex":{"permanent":true,"regex":"^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$","replacement":"${1}/dashboard/"}},"dashboard_stripprefix":{"stripPrefix":{"prefixes":["/dashboard/","/dashboard"]}}},"routers":{"acme-http":{"entryPoints":["web"],"priority":9223372036854775807,"rule":"PathPrefix(`/.well-known/acme-challenge/`)","ruleSyntax":"v3","service":"acme-http@internal"},"api":{"entryPoints":["traefik"],"priority":9223372036854775806,"rule":"PathPrefix(`/api`)","ruleSyntax":"v3","service":"api@internal"},"dashboard":{"entryPoints":["traefik"],"middlewares":["dashboard_redirect@internal","dashboard_stripprefix@internal"],"priority":9223372036854775805,"rule":"PathPrefix(`/`)","ruleSyntax":"v3","service":"dashboard@internal"}},"serversTransports":{"default":{"maxIdleConnsPerHost":200}},"services":{"acme-http":{},"api":{},"dashboard":{},"noop":{}}},"tcp":{"serversTransports":{"default":{"dialKeepAlive":"15s","dialTimeout":"30s"}}},"tls":{},"udp":{}} providerName=internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{},"tcp":{},"tls":{},"udp":{}} providerName=myresolver.acme
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:299 > Creating load-balancer entryPointName=web routerName=nginx@file serviceName=nginx@file
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:336 > Creating server entryPointName=web routerName=nginx@file serverName=70a994c85944ea66 serviceName=nginx@file target=http://nginx/
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=websecure middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/stripprefix/strip_prefix.go:32 > Creating middleware entryPointName=traefik middlewareName=dashboard_stripprefix@internal middlewareType=StripPrefix routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=traefik middlewareName=dashboard_stripprefix@internal routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_regex.go:17 > Creating middleware entryPointName=traefik middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_regex.go:18 > Setting up redirection from ^(http:\/\/(\[[\w:.]+\]|[\w\._-]+)(:\d+)?)\/$ to ${1}/dashboard/ entryPointName=traefik middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=traefik middlewareName=dashboard_redirect@internal routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=traefik middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:299 > Creating load-balancer entryPointName=websecure routerName=nginx@file serviceName=nginx@file
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:336 > Creating server entryPointName=websecure routerName=nginx@file serverName=70a994c85944ea66 serviceName=nginx@file target=http://nginx/
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=websecure middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/stripprefix/strip_prefix.go:32 > Creating middleware entryPointName=traefik middlewareName=dashboard_stripprefix@internal middlewareType=StripPrefix routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=traefik middlewareName=dashboard_stripprefix@internal routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_regex.go:17 > Creating middleware entryPointName=traefik middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_regex.go:18 > Setting up redirection from ^(http:\/\/(\[[\w:.]+\]|[\w\._-]+)(:\d+)?)\/$ to ${1}/dashboard/ entryPointName=traefik middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=traefik middlewareName=dashboard_redirect@internal routerName=dashboard@internal
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=traefik middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery

DNS resolution works correctly for all the domains used in the config: i.e. all points to the same IP address, that of the server where this is deployed.

Why isn't traefik receiving the certificate?

traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{},"tcp":{},"tls":{},"udp":{}} providerName=myresolver.acme
traefik-1  | 2024-11-11T12:00:56Z DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default

1 Answer 1

1

You need to define the certificate resolver also in the dynamic config for each router, like this:

http:
  routers:
    nginx:
      entrypoints:
      - web
      - websecure
      rule: "Host(`www.host1.com`) || Host(`www.host2.com`) || Host(`host1.com`) || Host(`host2.com`)"
      service: nginx
      tls:
        certResolver: myresolver

Or alternatively in the service labels in docker compose:

  nginx:
    image: nginx:latest
    ...
    labels:
      - traefik.http.routers.nginx.tls=true
      - traefik.http.routers.nginx.tls.certresolver=myresolver

but since you already do most of the stuff in the dynamic config, having it defined there would make more sense.

Be sure to revisit the traefik documentation example.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.