Docker Swarm, Traefik, & Let's Encrypt SSL Certificates with ACME

Docker Swarm does not offer any easy way to implement SSL certificates for your services. Enter Traefik:

Træfik (pronounced like traffic) is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. It supports several backends (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS, and a lot more) to manage its configuration automatically and dynamically.

Traefik will proxy request from any of your swarm nodes to the correct service based off of deploy labels you add to your Docker Compose yaml files. It also has Let's Encrypt support built in that will use the ACME challenge to automatically issue certificates on your behalf.

This setup is very generic. In fact there are only two lines you need to change in the whole thing:

  1. In stage.yml you will need to change the line below to the domain name you'd like Traefik to register with Let's Encrypt and to forward traffic from.
    "traefik.frontend.rule=Host:traefik.tylerbuchea.com"
  2. In traefik.toml change the the email address you'd like to receive updates from Let's Encrypt at.
    email = "tyler@buchea.com"

For more details check out the Traefik Let's Encrypt Guide.

I also released my starter template as a repo you can use to test this configuration out: https://github.com/tylerbuchea/docker-swarm-traefik.

stage.yml

version: "3.3"

networks:  
  default:
    external: false
  proxy:
    external: true

services:

  site:
    build: ./site
    image: tylerbuchea/docker-traefik
    command: node index.js
    networks:
      - proxy
      - default
    deploy:
      labels:
        - "traefik.docker.backend=site"
        - "traefik.port=3001"
        - "traefik.frontend.rule=PathPrefix:/"
        - "traefik.frontend.rule=Host:traefik.tylerbuchea.com"
        - "traefik.docker.network=proxy"

traefik.yml

version: '3.3'

networks:  
  proxy:
    external: true

configs:  
  traefik.toml:
    file: ./traefik.toml

services:

  traefik:
    image: traefik
    ports:
      - "80:80"
      - "8080:8080"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    configs:
      - source: traefik.toml
        target: /etc/traefik/traefik.toml
    labels:
      - "traefik.enable=false"
    networks:
      - proxy
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]                                       

traefik.toml

logLevel = "DEBUG"  
defaultEntryPoints = ["http", "https"]

[web]

[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

[acme]
  email = "tyler@buchea.com"
  storage = "acme.json"
  entryPoint = "https"
  OnHostRule = true

[acme.httpChallenge]
  entryPoint = "http"

[docker]
  domain = "traefik"
  watch = true
  swarmmode = true

Resources

A set of UI components for React Native.
Get Carbon Native!