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:
- 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.
- In traefik.toml change the the email address you'd like to receive updates from Let's Encrypt at.
email = "email@example.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.
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"
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]
logLevel = "DEBUG" defaultEntryPoints = ["http", "https"] [web] [entryPoints] [entryPoints.http] address = ":80" [entryPoints.https] address = ":443" [entryPoints.https.tls] [acme] email = "firstname.lastname@example.org" storage = "acme.json" entryPoint = "https" OnHostRule = true [acme.httpChallenge] entryPoint = "http" [docker] domain = "traefik" watch = true swarmmode = true