Skip to content

Instantly share code, notes, and snippets.

@crazygit
Last active May 8, 2022 14:38
Show Gist options
  • Save crazygit/fa4c24c64de37fca400b67265d6feea8 to your computer and use it in GitHub Desktop.
Save crazygit/fa4c24c64de37fca400b67265d6feea8 to your computer and use it in GitHub Desktop.
Use traefik in docker swarm cluster, Ultimate configuration
ACME_EMAIL=your_mail@example.com
DASHBOARD_DOMAIN=traefik.example.com
WHOAMI_SERVICE_DOMAIN=whoami.example.com
# echo "DASHBOARD_USER=$(htpasswd -nb your_name your_password)" >> .env
DASHBOARD_USER=your_name:$apr1$eMFHYd7e$2rl6G/UF80alLYInwv/tz0
version: '3.8'
services:
reverse_proxy:
image: traefik:v2.6
command:
# - "--log.level=DEBUG"
# Enable Docker in Traefik, so that it reads labels from Docker services
- "--providers.docker"
# Do not expose all Docker services, only the ones explicitly exposed
- "--providers.docker.exposedbydefault=false"
# Set default Docker network used
- "--providers.docker.network=traefik-public"
# Enable Docker Swarm mode
- "--providers.docker.swarmmode"
# Create an entrypoint "http" listening on port 80
- "--entrypoints.web.address=:80"
# Create an entrypoint "https" listening on port 443
- "--entrypoints.websecure.address=:443"
# Enable the access log, with HTTP requests
- "--accesslog"
# Enable the Traefik log, for configurations and errors
- "--log"
# Enable the Dashboard and API
- "--api.dashboard=true"
# Use the Http Challenge for Let's Encrypt
- "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true"
# Use the HTTP Challenge
- "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web"
# Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
- "--certificatesresolvers.letsencryptresolver.acme.email=${ACME_EMAIL}"
# Store the Let's Encrypt certificates in the mounted volume
- "--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json"
# If you uncommented the acme.caserver line, you will get an SSL error, but if you display the certificate and see it was emitted by Fake LE Intermediate X1 then it means all is good. (It is the staging environment intermediate certificate used by let's encrypt). You can now safely comment the acme.caserver line, remove the letsencrypt/acme.json file and restart Traefik to issue a valid certificate.
- "--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
# Global HTTP -> HTTPS
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
ports:
# use host mode so traefik can get real client ip
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- certificates:/letsencrypt
# Since the Swarm API is only exposed on the manager nodes, these are the nodes that Traefik should be scheduled on by deploying Traefik with a constraint on the node "role":
deploy:
placement:
constraints:
- node.role == manager
labels:
# Enable Traefik for this service, to make it available in the public network
- "traefik.enable=true"
# Use the traefik-public network
- "traefik.docker.network=traefik-public"
# dashboard-auth middleware with HTTP Basic auth
- "traefik.http.middlewares.auth.basicauth.users=${DASHBOARD_USER}"
# dashboard https router
- "traefik.http.routers.dashboard.rule=Host(`${DASHBOARD_DOMAIN}`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls.certresolver=letsencryptresolver"
- "traefik.http.routers.dashboard.middlewares=auth"
# Dummy service for Swarm port detection. The port can be any valid integer value.
- "traefik.http.services.dummy-svc.loadbalancer.server.port=9999"
networks:
# Use the public network created to be shared between Traefik and
# any other service that needs to be publicly available with HTTPS
- traefik-public
whoami:
image: "traefik/whoami"
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`${WHOAMI_SERVICE_DOMAIN}`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencryptresolver"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
# add service health check
- "traefik.http.services.whoami.loadbalancer.healthcheck.interval=30s"
- "traefik.http.services.whoami.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.whoami.loadbalancer.healthcheck.timeout=5s"
# more health check options
# - "traefik.http.services.whoami.loadbalancer.healthcheck.port=80"
# - "traefik.http.services.whoami.loadbalancer.healthcheck.scheme=http"
# - "traefik.http.services.whoami.loadbalancer.healthcheck.hostname=${WHOAMI_SERVICE_DOMAIN}"
# - "traefik.http.services.whoami.loadbalancer.healthcheck.headers.X-Health-Check=healthcheck"
networks:
- traefik-public
volumes:
# Create a volume to store the certificates, there is a constraint to make sure
# Traefik is always deployed to the same Docker node with the same volume containing
# the HTTPS certificates
certificates:
networks:
# services that need to be publicly available via this Traefik
traefik-public:
external: true
@crazygit
Copy link
Author

crazygit commented May 8, 2022

Use traefik in docker swarm cluster, Ultimate configuration

Feature

  • export traefik dashboard in security mode with basic auth
  • global redirect http to https
  • get real client ip
  • auto get https certificates from let's encrypt and auto renew it

How to usage

Preconditions

You need a docker swarm cluster and ssh into docker swarm master node first

Step 1

create traefik-public network

$ docker network create --driver=overlay traefik-public

Step 2

create your .env file from .env.example

$ copy .env.example .env

then update the configuration in .env file to yours,

you may need to install below package to use htpasswd command to set your auth user info

$ sudo apt install apache2-utils

Step 3

deploy traefik stack

$ export $(grep -v '^#' .env | xargs -d '\n')
$ docker stack deploy -c traefik.yml traefik

Step 4, Check access

Use browser to access below link

You will get an SSL error, don't worry. if you display the certificate and see it was emitted by Fake LE Intermediate X1 then it means all is good.

Step 5

Comment below line in traefik.yml file when deploy to production

   - "--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"

Enjoy !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment