In order to serve several Docker services (simple Docker or orchestrated ones via Docker swarm) is good to setup a reverse proxy as Traefik (or Nginx).
This a receipt for deploying Traefik as a Docker swarm stack, including a simple who am I web service to test it.
version: '3.8'
services:
traefik:
image: traefik:2.10.4
command:
- '--log.level=WARN'
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.swarmMode=true'
- '--providers.docker.exposedbydefault=false'
- '--providers.docker.network=proxy_net'
- '--entrypoints.http.address=:80'
- '--entrypoints.http.http.redirections.entryPoint.to=https'
- '--entrypoints.http.http.redirections.entryPoint.scheme=https'
- '--entrypoints.https.address=:443'
- '--entryPoints.https.http.tls=true'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'
- '--certificatesresolvers.letsencrypt.acme.email=user@domain.com'
- '--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json'
volumes:
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
read_only: true
- type: bind
source: /shared/storage/path/traefik
target: /etc/traefik/acme
networks:
- proxy_net
ports:
- target: 80
published: 80
- target: 443
published: 443
deploy:
mode: global
placement:
constraints:
- node.role==manager
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
labels:
traefik.enable: 'true'
traefik.http.routers.https_traefik.rule: 'Host(`traefik.domain.com`)'
traefik.http.routers.https_traefik.entrypoints: 'https'
traefik.http.routers.https_traefik.tls.certresolver: 'letsencrypt'
traefik.http.services.traefik.loadbalancer.server.port: '8080'
whoami:
image: containous/whoami:v1.5.0
networks:
- proxy_net
deploy:
labels:
traefik.enable: 'true'
traefik.http.routers.https_whoami.rule: 'Host(`whoami.domain.com`)'
traefik.http.routers.https_whoami.entrypoints: 'https'
traefik.http.routers.https_whoami.tls.certresolver: 'letsencrypt'
traefik.http.services.whoami.loadbalancer.server.port: '80'
networks:
proxy_net:
external: true
Some interesting features of this configuration:
- It declares an external overlay network, it should be pre created before adding the stack, being external allows to redeploy the stack without errors because this network is used by other stacks.
- It includes auto provision of Let’s Encrypt SSL certificates, you need Internet connection at those Docker servers, also replace the admin email & domain names (for base domain at Traefik configuration, and auto provisioned web URLs), Traefik should be allowed to use HTTP (80/tcp) and HTTPS (443/tcp) ports.
- No extra tedious configuration files are required, all is defined at the YAML file.
- Traefik is configured to listen to Docker socket in order to auto discover any new Docker container requesting new sub URI of the defined base domain configured at Traefik service, this is my preferred behaviour for a reverse proxy, new services (as “who am I”) will add a few deployment labels to ask Traefik to do the job (in deed Traefik is the one reading those labels). Take care Traefik service should be placed in a manager node in order to do its job, placement constraint was added on deploy section.