Traefik
Introduction
In this post, we’ll walk through the steps to install and configure Traefik as a reverse proxy and load balancer for your Docker environment. Traefik is a powerful tool that dynamically discovers backend services and can automatically generate SSL certificates via ACME providers like Let’s Encrypt.
This guide assumes you are familiar with docker and have it installed on your system if you didnt you can follow our detailed Docker installation guide.
Step 1: Download and Extract Traefik
First, download the appropriate version of Traefik you would like to use for your system from the official Traefik GitHub releases page.
1
2
wget https://github.com/traefik/traefik/releases/download/vX.X.X/traefik_linux_amd64.tar.gz
tar -xzvf traefik_linux_amd64.tar.gz
Step 2: Move Traefik to a System Path
Make the Traefik binary executable and move it to a directory in your system’s PATH:
1
2
chmod +x traefik
sudo mv traefik /usr/local/bin/traefik
To allow Traefik to bind to privileged ports (like 80 and 443) as a non-root user, execute the following command:
1
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/traefik
Step 3: Set Up User and Directories
Now, we’ll create the necessary user, group, and directories for Traefik. This ensures that Traefik runs with limited permissions, improving security.
1
2
sudo groupadd -g 321 traefik docker
sudo useradd -g traefik --no-user-group --home-dir /var/www --no-create-home --shell /usr/sbin/nologin --system --uid 321 traefik
Create the configuration directories:
1
2
3
4
sudo mkdir -p /etc/traefik/{acme,dynamic} /var/log/traefik/
sudo touch /var/log/traefik/{traefik.log,debug.log}
sudo chown -R root:root /etc/traefik
sudo chown -R traefik:traefik /etc/traefik/acme
Set appropriate ownership and permissions:
1
2
sudo chown root:root /etc/traefik/traefik.yaml
sudo chmod 644 /etc/traefik/traefik.yaml /etc/traefik/dynamic/config.yml /var/log/traefik/{traefik.log,debug.log}
Step 4: Create and Configure Traefik Files
You need to place the traefik.yaml
configuration file in /etc/traefik/
and config.yml
configuration file in /etc/traefik/dynamic/config.yaml
.
This file defines global settings, entry points, logging, and providers for Docker and file-based configurations.
Update sample traefik.yaml
according to your needs:
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
################################################################
# Global configuration
################################################################
#global:
# checkNewVersion = true
# sendAnonymousUsage = true
################################################################
# API and dashboard configuration
################################################################
api:
dashboard: true
debug: true
################################################################
# Traefik logs configuration
################################################################
log:
level: DEBUG
filePath: /var/log/traefik/debug.log
#format: json
accessLog:
filePath: "/var/log/traefik/traefik.log"
bufferingSize: 100
#format: json
################################################################
# EntryPoints configuration
################################################################
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
https:
address: ":443"
serversTransport:
insecureSkipVerify: true
################################################################
# Docker configuration backend
################################################################
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
useBindPortIP: true
network: proxy
watch: true
file:
directory: /etc/traefik/dynamic/
watch: true
################################################################
# Certificate resolvers
################################################################
certificatesResolvers:
cloudflare:
acme:
email: XXXXXXXXXX
storage: /etc/traefik/acme/acme.json
dnsChallenge:
provider: cloudflare
#disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
Update sample config.yaml
according to your needs:
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
http:
routers:
test:
entryPoints:
- "https"
rule: "Host(`test.example.com`)"
middlewares:
- secured
tls:
certResolver: cloudflare
domains:
- main: "example.com"
sans:
- "*.example.com"
service: test
traefik:
entryPoints:
- "https"
rule: "Host(`traefik-detract.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
middlewares:
- default-headers
tls:
certResolver: cloudflare
domains:
- main: "example.com"
sans:
- "*.example.com"
service: api@internal
############################################################################################
### services
############################################################################################
services:
test:
loadBalancer:
sticky:
cookie:
secure: true
httpOnly: true
servers:
- url: "https://$IP:$PORT/"
passHostHeader: true
############################################################################################
### middlewares
############################################################################################
middlewares:
https-redirectscheme:
redirectScheme:
scheme: https
permanent: true
gzip:
compress: {}
default-headers:
headers:
frameDeny: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
customResponseHeaders:
Access-Control-Allow-Origin: "*"
cors:
headers:
accessControlAllowOriginList: ["*"]
accessControlAllowCredentials: true
accessControlAllowHeaders: ["*"]
accessControlAllowMethods: ["*"]
accessControlMaxAge: 100
addVaryHeader: true
tls:
options:
# To use with the label "traefik.http.routers.myrouter.tls.options=modern@file"
modern:
minVersion: "VersionTLS13" # Minimum TLS Version
sniStrict: true # Strict SNI Checking
# To use with the label "traefik.http.routers.myrouter.tls.options=intermediate@file"
intermediate:
cipherSuites:
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
minVersion: "VersionTLS12" # Minimum TLS Version
sniStrict: true # Strict SNI Checking
# To use with the label "traefik.http.routers.myrouter.tls.options=old@file"
old:
cipherSuites:
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
- "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
- "TLS_RSA_WITH_AES_128_GCM_SHA256"
- "TLS_RSA_WITH_AES_256_GCM_SHA384"
- "TLS_RSA_WITH_AES_128_CBC_SHA256"
- "TLS_RSA_WITH_AES_128_CBC_SHA"
- "TLS_RSA_WITH_AES_256_CBC_SHA"
- "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
minVersion: "TLSv1" # Minimum TLS Version
sniStrict: true # Strict SNI Checking
Step 5: Create Systemd Service
Create a systemd service file for Traefik to manage its lifecycle.
1
2
3
sudo nano /etc/systemd/system/traefik.service
sudo chown root:root /etc/systemd/system/traefik.service
sudo chmod 644 /etc/systemd/system/traefik.service
Update sample traefik.service
according to your needs:
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
[Unit]
Description=Traefik
Documentation=https://doc.traefik.io/traefik/
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
Environment="CF_API_EMAIL=XXXXXXXXXX"
Environment="CF_DNS_API_TOKEN=XXXXXXXXXX"
Environment="CF_API_KEY=XXXXXXXXXX"
Restart=always
RestartSec=3
; User and group the process will run as.
User=traefik
Group=traefik
; Always set "-root" to something safe in case it gets forgotten in the traefikfile.
ExecStart=/usr/local/bin/traefik --configfile=/etc/traefik/traefik.toml --api=true --api.insecure=true --api.dashboard=true --api.debug=true
; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
LimitNOFILE=1048576
; Use private /tmp and /var/tmp, which are discarded after traefik stops.
PrivateTmp=true
; Use a minimal /dev (May bring additional security if switched to 'true', but it may not work on Raspberry Pis or other devices, so it has been disabled in this dist.)
PrivateDevices=false
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; … except /etc/ssl/traefik, because we want Letsencrypt-certificates there.
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
ReadWriteDirectories=/etc/traefik/acme
; The following additional security directives only work with systemd v229 or later.
; They further restrict privileges that can be gained by traefik. Uncomment if you like.
; Note that you may have to add capabilities required by any plugins in use.
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Reload systemd and start the Traefik service:
1
2
sudo systemctl daemon-reload
sudo systemctl start traefik.service
To enable Traefik to start automatically at boot:
1
sudo systemctl enable traefik.service
Conclusion
You now have Traefik up and running, configured to work with Docker and your Cloudflare DNS for SSL certificates. For more advanced configurations, such as setting up middlewares or further customizing TLS options, refer to the official Traefik documentation.