Published on

Traefik setup with docker swarm

3 min read
Table of Contents

Docker swarm init

docker swarm init --advertise-addr 10.0.0.3

Create a traefik network

docker network create --driver overlay traefik-public

Create a htpasswd password

docker run --rm httpd:2.4-alpine htpasswd -nbB admin <password> | cut -d ":" -f 2

Escape the signinthepasswordbyaddingonemoresign in the password by adding one more

Create folders

for Traefik

create a folder and set 600 as permission.

mkdir /home/docker-login/data/traefik
touch /home/docker-login/data/traefik/acme.json
chmod 600 /home/docker-login/data/traefik/acme.json

for Swarmpit

mkdir /home/docker-login/data/db-data
mkdir /home/docker-login/data/influx-data

for Portainer

mkdir /mnt/volume2/portainer

Traefik docker compose yml

Sample yml

version: '3.3'

services:
  traefik:
    image: 'traefik:v2.1.4'
    command:
      - --log.level=INFO
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker
      - --providers.docker.exposedbydefault=false
      - --providers.docker.swarmmode=true
      - --providers.docker.network=traefik-public
      - --api
      - --api.dashboard=true
      - --certificatesresolvers.leresolver.acme.caserver=https://acme-v02.api.letsencrypt.org/directory
      # update your email here
      - --certificatesresolvers.leresolver.acme.email=youremail@test.com
      # Make sure the this file is available and permission is set correctly
      - --certificatesresolvers.leresolver.acme.storage=/le/acme.json
      - --certificatesresolvers.leresolver.acme.tlschallenge=true
    ports:
      - '80:80'
      - '443:443'
    networks:
      - traefik-public
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
      # Make sure the volume folder is created
      - '/home/docker-login/data/traefik/acme.json:/le/acme.json'
    deploy:
      labels:
        # Dashboard
        - 'traefik.enable=true'
        # Change the host url here
        - 'traefik.http.routers.traefik.rule=Host(`traefik.example.com`)'
        - 'traefik.http.routers.traefik.service=api@internal'
        - 'traefik.http.services.traefik.loadbalancer.server.port=8080'
        - 'traefik.http.routers.traefik.tls.certresolver=leresolver'
        - 'traefik.http.routers.traefik.entrypoints=websecure'
        - 'traefik.http.routers.traefik.middlewares=authtraefik'
        # Change the auth password here
        - 'traefik.http.middlewares.authtraefik.basicauth.users=admin:yournewpassword' # user/password

        # global redirect to https
        - 'traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)'
        - 'traefik.http.routers.http-catchall.entrypoints=web'
        - 'traefik.http.routers.http-catchall.middlewares=redirect-to-https'

        # middleware redirect
        - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'

  my-app:
    image: containous/whoami:v1.3.0
    networks:
      - traefik-public
    command:
      - --port=8082 # Our service listens on 8082
    deploy:
      labels:
        - 'traefik.enable=true'
        # Change the host url here
        - 'traefik.http.routers.my-app.rule=Host(`whoami.example.com`)'
        - 'traefik.http.services.my-app.loadbalancer.server.port=8082'
        - 'traefik.http.routers.my-app.middlewares=auth'
        - 'traefik.http.routers.my-app.entrypoints=websecure'
        - 'traefik.http.routers.my-app.tls=true'
        - 'traefik.http.routers.my-app.tls.certresolver=leresolver'
        # Change the password here
        - 'traefik.http.middlewares.auth.basicauth.users=admin:changeme' # user/password

networks:
  traefik-public:
    external: true

Swarmpit Docker compose

Make sure the service name for swarmpit is "app"

version: '3.3'

services:
  app:
    image: swarmpit/swarmpit:latest
    environment:
      - SWARMPIT_DB=http://db:5984
      - SWARMPIT_INFLUXDB=http://influxdb:8086
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - traefik-public
    deploy:
      labels:
        - 'traefik.enable=true'
        # change the host name here
        - 'traefik.http.routers.app.rule=Host(`swarm.example.com`)'
        - 'traefik.http.services.app.loadbalancer.server.port=8080'
        - 'traefik.http.routers.app.tls=true'
        - 'traefik.http.routers.app.tls.certresolver=leresolver'
        - 'traefik.docker.network=traefik-public'
      resources:
        limits:
          cpus: '0.50'
          memory: 1024M
        reservations:
          cpus: '0.25'
          memory: 512M
      placement:
        constraints:
          - node.role == manager

  db:
    image: couchdb:2.3.0
    volumes:
      # make sure the folder is available
      - /home/docker-login/data/db-data:/opt/couchdb/data
    networks:
      - traefik-public
    deploy:
      resources:
        limits:
          cpus: '0.30'
          memory: 256M
        reservations:
          cpus: '0.15'
          memory: 128M

  influxdb:
    image: influxdb:1.7
    volumes:
      # make sure the folder is available
      - /home/docker-login/data/influx-data:/var/lib/influxdb
    networks:
      - traefik-public
    deploy:
      resources:
        limits:
          cpus: '0.60'
          memory: 512M
        reservations:
          cpus: '0.30'
          memory: 128M

  agent:
    image: swarmpit/agent:latest
    environment:
      - DOCKER_API_VERSION=1.35
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - traefik-public
    deploy:
      mode: global
      labels:
        swarmpit.agent: 'true'
      resources:
        limits:
          cpus: '0.10'
          memory: 64M
        reservations:
          cpus: '0.05'
          memory: 32M

networks:
  traefik-public:
    external: true

Portainer

version: '3.2'

services:
  agent:
    image: portainer/agent
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - traefik-public
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # make sure the folder is available
      - /mnt/volume2/portainer:/data
    networks:
      - traefik-public
    deploy:
      labels:
        - 'traefik.enable=true'
        # change the host here
        - 'traefik.http.routers.portainer.rule=Host(`admin.example.com`)'
        - 'traefik.http.services.portainer.loadbalancer.server.port=9000'
        - 'traefik.http.routers.portainer.entrypoints=websecure'
        - 'traefik.http.routers.portainer.tls=true'
        - 'traefik.http.routers.portainer.tls.certresolver=leresolver'
      mode: replicated
      placement:
        constraints: [node.role == manager]

networks:
  traefik-public:
    external: true