Prerequisites

  • Docker installed and working on Machine

Step 1 - Create a Docker network

Run the following command:

1
docker network create traefik_public

If using swarm, run this instead:

1
docker network create -d overlay traefik_public

Step 2 - Create a Docker Compose file

Create a new Docker Compose file for Traefik named docker-compose.yml and add the following configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
version: "3.8"

services:
traefik:
image: "traefik:latest"
command:
- "--api.dashboard=true" # Enabling the dashboard
- "--providers.docker=true" # Enabling docker as the provider for traefik
- "--entrypoints.web.address=:80" # Defining an entrypoint for port :80 named web
- "--entrypoints.websecure.address=:443" # Defining an entrypoint for port :443 named websecure - SSL port (HTTPS)
- "--providers.docker.exposedbydefault=false" # Don't expose every container to traefik, only expose enabled ones
- "--providers.docker.swarmMode=true" # Enable swarm mode (Comment this if not using Swarm)
- "--providers.docker.network=traefik_public"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
# SSL configuration - Let's Encrypt
- "--certificatesresolvers.le.acme.httpchallenge=true"
- "[email protected]"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.tlschallenge=true"
# Global redirect HTTP to HTTPS
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
ports:
- "80:80" # http
- "8080:8080" # traefik dashboard
- "443:443" # https
volumes:
- "traefik_certificates:/letsencrypt" # Volume for SSL certificates
- "/var/run/docker.sock:/var/run/docker.sock" # Volume for docker admin
deploy: # Swarm mode (Comment this if not using Swarm)
mode: replicated
replicas: 1
# resources: # Uncomment this if you want to limit resources on Traefik
# limits:
# cpus: '0.25'
# memory: 300M
placement:
constraints:
- node.role == manager
networks:
- traefik_public
volumes:
traefik_certificates: # SSL certificates
external: true

networks:
traefik_public: # Public network
external: true

More info: Traefik

Step 3 - Run the config

Run the following command:

1
docker-compose up -d

If using swarm, run this:

1
docker stack deploy --compose-file docker-compose.yml traefik

Step 4 - Check it’s running

Run the following command:

1
docker ps

If using swarm run this:

1
docker stack services traefik

More info: Docker Swarm

Bonus - Example (Portainer - Docker Swarm)

Create portainer-agent-stack.yml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
version: '3.2'

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

portainer:
image: portainer/portainer-ce:2.19.1
command: -H tcp://tasks.agent:9001 --tlsskipverify
# ports: # Remove these ports if traefik is used
# - "9443:9443"
# - "9000:9000"
# - "8000:8000"
volumes:
- portainer_data:/data
networks:
- agent_network
- traefik_public # Traefik public network
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
labels:
- "traefik.enable=true" # Enable traefik
- "traefik.http.routers.portainer.rule=Host(`portainer.yourdomain.com`)" # Set the portainer subdomain
- "traefik.http.services.portainer.loadbalancer.server.port=9000" # Load balance port 9000
- "traefik.http.routers.portainer.service=portainer" # Set the portainer service
- "traefik.http.routers.portainer.tls.certresolver=le" # Use the Let's Encrypt resolver
- "traefik.http.routers.portainer.entrypoints=websecure" # Use the websecure entrypoint
- "traefik.http.routers.portainer.tls=true" # Enable TLS
networks:
agent_network:
driver: overlay
attachable: true
traefik_public: # Traefik public network
external: true

volumes:
portainer_data:

Run:

1
docker stack deploy portainer -c portainer-agent-stack.yml

Bonus - Example (Docker + Traefik + Portainer)

Create docker-compose.yml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
version: "3.3"

services:
traefik:
container_name: traefik
image: "traefik:latest"
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --api.dashboard=true
- --providers.docker
- --log.level=ERROR
- --certificatesresolvers.leresolver.acme.httpchallenge=true
- [email protected] #Set your email address here, is for the generation of SSL certificates with Let's Encrypt.
- --certificatesresolvers.leresolver.acme.storage=./acme.json
- --certificatesresolvers.leresolver.acme.httpchallenge.entrypoint=web
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./acme.json:/acme.json"
labels:
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.domain.com`)"
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=leresolver"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:password" # Use this site to generate the password: https://hostingcanada.org/htpasswd-generator/
- "traefik.http.routers.traefik-dashboard.middlewares=traefik-auth"

portainer:
image: portainer/portainer-ce:latest
command: -H unix:///var/run/docker.sock
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
labels:
# Frontend
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`portainer.domain.com`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.services.frontend.loadbalancer.server.port=9000"
- "traefik.http.routers.frontend.service=frontend"
- "traefik.http.routers.frontend.tls.certresolver=leresolver"

# Edge
- "traefik.http.routers.edge.rule=Host(`edge.domain.com`)"
- "traefik.http.routers.edge.entrypoints=websecure"
- "traefik.http.services.edge.loadbalancer.server.port=8000"
- "traefik.http.routers.edge.service=edge"
- "traefik.http.routers.edge.tls.certresolver=leresolver"

volumes:
portainer_data:

Create the file acme.json in same folder

Run:

1
sudo chmod 600 acme.json

Next, run:

1
docker compose up -d

If you need to edit the Docker Compose file again, run:

1
2
3
4
5
nano docker-compose.yml 

docker compose down
docker compose pull
docker compose up -d

More info: Portainer

Sorry for any grammatical or spelling errors. I am practicing my english.