Search code examples
lets-encrypttraefik

Use existing LetsEncrypt certificates in Traefik


Is it possible to use existing LetsEncrypt certificates (.pem format) in Traefik?

I have Traefik/Docker set up to generate acme.json - can I import my existing certificates for a set of domains?


Solution

  • Eventually I found the correct solution - not to use Traefik's ACME integration but instead to simply mount a network volume (EFS) containing certificates as issued by certbot in manual mode.

    Why was this my chosen method? Because I'm mounting that certificate-holding NFS volume on two servers (blue and green). These servers are the live & staging servers for the web servers. At any time one will be "live" and the other can be either running a release candidate or otherwise in a "hot standby" role.

    For this reason, better to make a separation of concerns and have a third server run as a dedicated "certificate manager". This t2.nano server will basically never be touched and has the sole responsibility of running certbot once a week, writing the certificates into an NFS mount that is shared (in read-only mode) by the two web servers.

    In this way, Traefik runs on both blue and green servers to takes care of its primary concern of proxying web traffic, and simply points to the certbot-issued certificate files. For those who found this page and could benefit from the same solution, here is the relevant extract from my traefik.toml file:

    defaultEntryPoints = ["https","http"]
    
    [docker]
    watch = true
    exposedbydefault = false
    swarmMode = true
    
    [entryPoints]
      [entryPoints.http]
      address = ":80"
        [entryPoints.http.redirect]
        entryPoint = "https"
      [entryPoints.https]
      address = ":443"
      [entryPoints.https.tls]
        [[entryPoints.https.tls.certificates]]
        certFile = "/cert.pem"
        keyFile = "/privkey.pem"
    

    Here is the relevant section from my Docker swarm stack file:

    version: '3.2'
    
    volumes:
     composer:
    
    networks:
      traefik:
        external: true
    
    services:
      proxy:
        image: traefik:latest
        command: --docker --web --docker.swarmmode --logLevel=DEBUG
        ports:
          - "80:80"
          - "443:443"
          - "8080:8080"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./traefik.toml:/traefik.toml
          - "./certs/live/example.com/fullchain.pem:/cert.pem"
          - "./certs/live/example.com/privkey.pem:/privkey.pem"
        networks:
          - traefik
    

    And finally here is the command that cron runs once a week on the dedicated cert server, configured to use ACME v2 for wildcard certs and Route 53 integration for challenge automation:

    sudo docker run -it --rm --name certbot                                      \
                -v `pwd`/certs:/etc/letsencrypt                                  \
                -v `pwd`/lib:/var/lib/letsencrypt                                \
                -v `pwd`/log:/var/log/letsencrypt                                \
                --env-file ./env                                                 \
                certbot/dns-route53                                              \
                certonly --dns-route53                                           \
                         --server https://acme-v02.api.letsencrypt.org/directory \
                         -d example.com                                          \
                         -d example.net                                          \
                         -d *.example.com                                        \
                         -d *.example.net                                        \
                         --non-interactive                                       \
                         -m me@example.org                                       \
                         --agree-tos
    

    The folder certs is the NFS volume shared between the three servers.