Anto Subash.

Posts in the Series

Part 1. Setting up Ubuntu Server with docker in Hetzner

Part 2. Setting up docker swarm with traefik and portainer (this post)

Part 3. Deploy redis, rabbitmq, seq, registry and postgres in docker swarm

Part 4. Deploy the microservice in docker swarm

Table of contents

Intro

In this post we will see how to create a docker swarm and deploy traefik and portainer in our ubuntu server.

What is traefik?

Traefik is a leading modern reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically.

For more info visit : https://traefik.io/traefik/

What is portainer?

Portainer is the definitive container management tool for Docker, Docker Swarm with it's highly intuitive GUI and API. Portainer is a fully featured management tool for Docker. It runs locally, giving developers a rich UI to build and publish container images, deploy and manage applications and leverage data persistence and horizontal scaling for their applications. And, once an application is deployed into a container, Portainer makes it easy for users to secure, monitor and measure the performance of the platform. The tool negates the need for developers to learn Infrastructure as Code and makes it easy for them to maximize their efficiency which means both users and organizations love it.

For more info visit: https://www.portainer.io/

What is Docker Swarm?

Docker swarm is a container orchestration tool, meaning that it allows the user to manage multiple containers deployed across multiple host machines. One of the key benefits associated with the operation of a docker swarm is the high level of availability offered for applications.

For more info: https://docs.docker.com/engine/swarm/

Init Docker Swarm

1docker swarm init --advertise-addr 10.0.0.3 # change the ip here with your machine ip

This will initialize docker in swarm mode and also display a join token for the other machines to join the cluster.

Create a traefik network

1docker network create --driver overlay traefik-public 

This is our primary network for the traefik.

Create a htpasswd password

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

Escape the $ sign in the password by adding one more $ to the generated password. We need this password to protect our end point in the traefik proxy.

Create folders

for Traefik

create a folder and set 600 as permission.

1mkdir /mnt/data
2mkdir /mnt/data/traefik
3touch /mnt/data/traefik/acme.json
4chmod 600 /mnt/data/traefik/acme.json

for Portainer

1mkdir /mnt/data/portainer

Traefik docker compose

Traefik is our main reverse proxy and it will sit in front of all out application. we will control all the routes to our containers using traefik.

1version: "3.3"
2
3services:
4  traefik:
5    image: "traefik:v2.1.4"
6    command:
7      - --log.level=INFO
8      - --entrypoints.web.address=:80
9      - --entrypoints.websecure.address=:443
10      - --providers.docker
11      - --providers.docker.exposedbydefault=false
12      - --providers.docker.swarmmode=true
13      - --providers.docker.network=traefik-public
14      - --api
15      - --api.dashboard=true
16      - --certificatesresolvers.leresolver.acme.caserver=https://acme-v02.api.letsencrypt.org/directory
17      # update your email here
18      - --certificatesresolvers.leresolver.acme.email=youremail@test.com
19      # Make sure the this file is available and permission is set correctly
20      - --certificatesresolvers.leresolver.acme.storage=/le/acme.json
21      - --certificatesresolvers.leresolver.acme.tlschallenge=true
22    ports:
23      - "80:80"
24      - "443:443"
25    networks:
26      - traefik-public
27    volumes:
28      - "/var/run/docker.sock:/var/run/docker.sock:ro"
29      # Make sure the volume folder is created
30      - "/mnt/data/traefik/acme.json:/le/acme.json"
31    deploy:
32      labels:
33        # Dashboard
34        - "traefik.enable=true"
35        # Change the host url here
36        - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
37        - "traefik.http.routers.traefik.service=api@internal"
38        - "traefik.http.services.traefik.loadbalancer.server.port=8080"
39        - "traefik.http.routers.traefik.tls.certresolver=leresolver"
40        - "traefik.http.routers.traefik.entrypoints=websecure"
41        - "traefik.http.routers.traefik.middlewares=authtraefik"
42        # Change the auth password here
43        - "traefik.http.middlewares.authtraefik.basicauth.users=admin:yournewpassword" # user/password
44
45        # global redirect to https
46        - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
47        - "traefik.http.routers.http-catchall.entrypoints=web"
48        - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
49
50        # middleware redirect
51        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
52
53  my-app:
54    image: containous/whoami:v1.3.0
55    networks:
56      - traefik-public
57    command:
58      - --port=8082 # Our service listens on 8082
59    deploy:
60      labels:
61        - "traefik.enable=true"
62        # Change the host url here
63        - "traefik.http.routers.my-app.rule=Host(`whoami.example.com`)"
64        - "traefik.http.services.my-app.loadbalancer.server.port=8082"
65        - "traefik.http.routers.my-app.middlewares=auth"
66        - "traefik.http.routers.my-app.entrypoints=websecure"
67        - "traefik.http.routers.my-app.tls=true"
68        - "traefik.http.routers.my-app.tls.certresolver=leresolver"
69        # Change the password here
70        - "traefik.http.middlewares.auth.basicauth.users=admin:changeme" # user/password
71
72networks:
73  traefik-public:
74    external: true

Portainer

Portainer is our container management software. We will use to deploy our docker containers.

1version: "3.2"
2
3services:
4  agent:
5    image: portainer/agent
6    volumes:
7      - /var/run/docker.sock:/var/run/docker.sock
8      - /var/lib/docker/volumes:/var/lib/docker/volumes
9    networks:
10      - traefik-public
11    deploy:
12      mode: global
13      placement:
14        constraints: [node.platform.os == linux]
15
16  portainer:
17    image: portainer/portainer
18    command: -H tcp://tasks.agent:9001 --tlsskipverify
19    volumes:
20      - /var/run/docker.sock:/var/run/docker.sock
21      # make sure the folder is available
22      - /mnt/volume2/portainer:/data
23    networks:
24      - traefik-public
25    deploy:
26      labels:
27        - "traefik.enable=true"
28        # change the host here
29        - "traefik.http.routers.portainer.rule=Host(`admin.example.com`)"
30        - "traefik.http.services.portainer.loadbalancer.server.port=9000"
31        - "traefik.http.routers.portainer.entrypoints=websecure"
32        - "traefik.http.routers.portainer.tls=true"
33        - "traefik.http.routers.portainer.tls.certresolver=leresolver"
34      mode: replicated
35      placement:
36        constraints: [node.role == manager]
37
38networks:
39  traefik-public:
40    external: true