This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
This is the multi-page printable view of this section. Click here to print.
This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
With Traefik 2.2 it is now easier then ever to globally configure your entrypoints.
We will show you how you can define a global redirect to https
and how to set a default certResolver
. So you don’t have to set the https
redirect in each docker-compose file.
In order to follow along, you’ll need to read the advanced Traefik guide and the wildcard guide first!
Change the entrypoints in the basic Traefik configuration file (/opt/containers/traefik/data/traefik.yml
) as follows:
entryPoints:
http:
address: :80
http:
redirections:
entryPoint:
to: https
https:
address: :443
http:
middlewares:
- default-headers@file
tls:
certResolver: cloudflare
domains:
- main: example.com
sans:
- "*.example.com"
The file will then look like this:
api:
dashboard: true
debug: true
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
https:
address: ":443"
http:
middlewares:
- default-headers@file
tls:
certResolver: cloudflare
domains:
- main: example.com
sans:
- "*.example.com"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yml
certificatesResolvers:
http:
acme:
email: email@email.com
storage: acme.json
httpChallenge:
entryPoint: http
We added 2 things:
Global middleware default-headers@file
By default all containers will now have the defined headers from the /opt/containers/traefik/data/config.yml
created in the advanced guide.
Global certResolver cloudflare
Since we’re using wildcard domains, you’ll need to setup dns challenge first! If you get an error like this:
level=error msg=”middleware \”default-headers@file\” does not exist” routerName=traefik@docker entryPointName=https”
Please make sure you have the middleware default-headers
created in /opt/containers/traefik/data/config.yml
. If not, either create it or remove the middleware from the traefik.yml.
Because we defined the https
redirect and the certResolver
here, you can remove some labels from all your docker-compose.
The Traefik docker-compose (/opt/containers/traefik/docker-compose.yml
) now looks like this:
version: "3"
services:
traefik:
image: traefik:v2.2
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
environment:
- CF_API_EMAIL=your-cloudflare@email.com
- CF_API_KEY=your-cloudflare-api-key
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.routers.traefik.service=api@internal"
networks:
proxy:
external: true
The Portainer docker-compose (/opt/containers/portainer/docker-compose.yml
) now looks like this:
version: "3"
services:
portainer:
image: portainer/portainer:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=https"
- "traefik.http.routers.portainer.rule=Host(`portainer.example.com`)"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
As you can see, you only need 5 instead of 11 labels.
If you want to add more individual middlewares, you can still add them to your docker-compose. In this example we’ve added a redirect regex required for Nextcloud (line 4, 5, 6 and 7):
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud.example.com`)"
- "traefik.http.middlewares.nextcloud-redirectregex.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav"
- "traefik.http.middlewares.nextcloud-redirectregex.redirectregex.replacement=https://$$1/remote.php/dav/"
- "traefik.http.middlewares.nextcloud-redirectregex.redirectregex.permanent=true"
- "traefik.http.routers.nextcloud.middlewares=nextcloud-redirectregex"
- "traefik.http.routers.nextcloud.service=nextcloud"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
In this tutorial we will show you how you can route non-Docker services through Traefik.
Let’s suppose you want to access your Pi-hole admin console (http://192.168.0.10:80/admin) by browsing to pihole.example.com
.
You have read our other articles:
and you use this Traefik configuration.
Make sure you configure in the providers section of your /opt/traefik/data/traefik.yml
an external configuration file /config.yml
.
providers:
docker:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
file:
filename: /config.yml
Edit /opt/containers/traefik/data/config.yml
and create a new router pihole
:
http:
routers:
pihole:
entryPoints:
- https
rule: Host(`pihole.example.com`)
middlewares:
- addprefix-pihole
tls:
certResolver: http
service: pihole
Still in /opt/containers/traefik/data/config.yml
create a service for the new router:
services:
pihole:
loadBalancer:
servers:
- url: http://192.168.0.10:80
passHostHeader: true
Because the admin panel of Pi-hole is only reachable at the path /admin
, you have to create an additional middleware (also in /opt/containers/traefik/data/config.yml
):
middlewares:
addprefix-pihole:
addPrefix:
prefix: /admin
If you have configured Traefik as we’ve described in the advanced tutorial, your config.yml
should now look like this:
http:
routers:
pihole:
entryPoints:
- "https"
rule: "Host(`pihole.example.com`)"
middlewares:
- default-headers
- addprefix-pihole
tls:
certResolver: http
service: pihole
services:
pihole:
loadBalancer:
servers:
- url: "http://192.168.0.10:80"
passHostHeader: true
middlewares:
addprefix-pihole:
addPrefix:
prefix: "/admin"
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
default-whitelist:
ipWhiteList:
sourceRange:
- "10.0.0.0/24"
- "192.168.0.0/16"
- "172.0.0.0/8"
secured:
chain:
middlewares:
- default-whitelist
- default-headers
We also added the middleware default-headers
to the new pihole
router.
Don’t forget to restart Traefik docker restart traefik
to reload the new config.yml
!
If you use a wildcard certificate as described in this article, you must leave the tls
section empty {}
:
http:
routers:
pihole:
entryPoints:
- https
rule: Host(`pihole.example.com`)
middlewares:
- default-headers
- addprefix-pihole
tls: {}
service: pihole
Here you can find a complete config.yml
to route a Synology Diskstation and Pi-hole through Traefik.
http:
routers:
pihole:
entryPoints:
- "https"
rule: "Host(`pihole.example.com`)"
middlewares:
- default-headers
- addprefix-pihole
tls:
certResolver: http
service: pihole
synology:
entryPoints:
- "https"
rule: "Host(`synology.example.com`)"
middlewares:
- default-headers
tls:
certResolver: http
service: synology
services:
pihole:
loadBalancer:
servers:
- url: "http://192.168.0.10:80"
passHostHeader: true
synology:
loadBalancer:
servers:
- url: "http://192.168.0.11:5000"
passHostHeader: true
middlewares:
addprefix-pihole:
addPrefix:
prefix: "/admin"
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
default-whitelist:
ipWhiteList:
sourceRange:
- "10.0.0.0/24"
- "192.168.0.0/16"
- "172.0.0.0/8"
secured:
chain:
middlewares:
- default-whitelist
- default-headers
As you can see, the Synology router has no extra middleware, because a Synology Disksation is accessible without any additional path.
If you have followed our previous guides, you mount the Docker Socket ( /var/run/docker.sock
) into the Traefik container. If someone gets access into the Traefik container, they can gain full access to your host machine. This makes our paranoia level increase slightly…
We found a nice little container (Socket-Proxy) which “filters” all requests to the Docker API. We can allow only get
requests to the Docker API and restrict it to /containers/*
.
The Socket Proxy uses the official Alpine-based HAProxy image. It blocks access to the Docker socket API according to the environment variables you set. It returns a HTTP 403 Forbidden
status for those dangerous requests that should never happen.
Let’s create the socket-proxy container (/opt/containers/docker-socket/docker-compose.yml
):
version: "3.6"
services:
socket-proxy:
image: tecnativa/docker-socket-proxy
container_name: socket-proxy
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: 1
networks:
- proxy
networks:
proxy:
external: true
The environment variable CONTAINERS: 1
tells the proxy to grant get
requests to /containers/*
from the Docker API. Post
requests are disabled by default.
All possible settings are described here.
Now we have to change the endpoint in the providers section of the traefik.yml file (/opt/containers/traefik/data/traefik.yml
):
api:
dashboard: true
debug: false
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "tcp://socket-proxy:2375"
watch: true
exposedbydefault: false
Restart the Traefik container and feel a little bit more safe!
In this tutorial we will setup Traefik to obtain wildcard certificates from Let’s Encrypt. This requires DNS challenge to be setup. Usually Traefik obtains a certificate for every subdomain. We can simplify this process by telling Traefik to use a wildcard (*.example.com) certificate instead.
In this tutorial we will use Cloudflare as our DNS servers for our domain.
If you have followed our other guides, chances are you currently use HTTP challenge. These types of challenges define how Let’s Encrypt assures that you are the owner of the domain you want to obtain a certificate for.
In order to get a wildcard certificate, you have to use DNS challenge.
First of all make sure you connect your domain with one of the supported DNS providers. We are using Cloudflare. This depends on where you bought your domain, so we can’t show you exactly how to do it.
In the Traefik Docker compose file we add the following lines:
environment:
- CF_API_EMAIL=your-cloudflare@email.com
- CF_API_KEY=your-cloudflare-api-key
Here is the full Traefik Docker compose
Next, we tell Traefik to use DNS challenge (edit the file traefik.yml):
certificatesResolvers:
cloudflare:
acme:
email: your@email.com
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
Here is the full Traefik configuration file
Create a backup of your existing acme.json and clear the current file:
cp -p acme.json acme.json.bak && > acme.json
Change the Traefik Docker compose labels (make sure to change your domain accordingly):
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=cloudflare"
- "traefik.http.routers.traefik.tls.domains[0].main=example.com"
- "traefik.http.routers.traefik.tls.domains[0].sans=*.example.com"
- "traefik.http.routers.traefik.service=api@internal"
Here is the full Traefik Docker compose
Now we have to remove one label from every service:
- traefik.http.routers.service.tls.certresolver=cloudflare
Here is an example compose file
Once you have removed the line above from all your services, Traefik should always use the wildcard certificate.
If you have followed our previous guides, chances are that you have a domain, some DNS records pointing to your public IP, port forwarding enabled and a Docker server running some services.
Most likely your domain resolves to your public IP from you internal network as well. This causes a problem: All the traffic between your devices (e.g. your phone) to your server (physically in the same location) gets routed trough the internet, which means you have to utilize your upload and download bandwidth at the same time (e.g. while streaming from Plex), which not only causes a slower connection but also adds an unnecessary high latency.
If you have a Pi-hole running at home (which you should) you can configure it to resolve your domain (*.example.com and example.com) to your servers local IP instead of your public IP. This means all your devices will directly connect to your server without looping through the internet, making everything faster. Yay!
Since Pi-hole is nothing else but a DNS server with some special software, we can easily configure the underlying dnsmasq service.
Here’s how we can achieve that:
Connect to your Raspberry Pi (or wherever Pi-hole is running) via SSH
Open the file /etc/dnsmasq.d/05-custom.conf
sudo nano /etc/dnsmasq.d/05-custom.conf
Add the following line (change example.com to your domain and 192.168.1.10 to your servers local IP)
address=/example.com/192.168.1.10
Restart the DNS service
sudo pihole restartdns
You can verify the changes by looking up your domain:
Before
[user@server ~]$ dig +short example.com
216.91.241.176
After:
[user@server ~]$ dig +short example.com
192.168.1.10
If you don’t have dig
installed, you can use the following command to install it on Ubuntu:
sudo apt install dnsutils
That’s it!
In this tutorial we will go trough the following things:
You will find all the required configuration files in our Git repository.
In order to follow along, you need these things:
Let’s get started by setting up Traefik.
First, create a directory for our containers:
mkdir -p /opt/containers/{traefik,portainer}
Create the data folder and config files for Traefik:
mkdir -p /opt/containers/traefik/data
touch /opt/containers/traefik/data/acme.json
chmod 600 /opt/containers/traefik/data/acme.json
touch /opt/containers/traefik/data/traefik.yml
The acme.json
file is the storage file for the HTTPS certificates.
Now we create the basic Traefik configuration file (/opt/containers/traefik/data/traefik.yml
):
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
http:
acme:
email: email@example.com
storage: acme.json
httpChallenge:
entryPoint: http
Please change the email
address for the certificatesresolvers at line 18.
Here is the Docker Compose file for Traefik (/opt/containers/traefik/docker-compose.yml
):
version: "3"
services:
traefik:
image: traefik:v2.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
proxy:
external: true
Using this compose file, Traefik will also expose a dashboard (line 32). Please change the host rule at line 23 and 28 to your subdomain.
In addition, change the credentials at line 24. Those credentials must be in htpasswd format.
To generate htpasswd credentials, you can use the following command (change <USER>
and <PASSWORD>
):
echo $(htpasswd -nb <USER> <PASSWORD>) | sed -e s/\\$/\\$\\$/g
Once that’s done we can create the proxy network an fire up Traefik:
docker network create proxy
cd /opt/containers/traefik
docker-compose up -d
Visit traefik.example.com
and enjoy the new dashboard.
Here is the Docker Compose file for Portainer (/opt/containers/portainer/docker-compose.yml
):
version: "3"
services:
portainer:
image: portainer/portainer:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(`portainer.example.com`)"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(`portainer.example.com`)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.tls.certresolver=http"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
Again, change the subdomain portainer.example.com at line 18 and 22.
Fire up Portainer:
cd /opt/containers/portainer
docker-compose up -d
You can now visit Portainer by browsing to portainer.example.com
.
This tutorial is the second part of this article. We will go trough the following configurations:
traefik.yml
config.yml
.You will find all the required configuration files in our Git repository.
In order to follow along, you’ll need to read this post!
To setup a reusable middleware add an additional provider in the Traefik configuration file traefik.yml
(/opt/containers/traefik/traefik.yml
) (lines 15 and 16).
api:
dashboard: true
debug: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yml
certificatesResolvers:
http:
acme:
email: email@example.com
storage: acme.json
httpChallenge:
entryPoint: http
Create a file for the central configuration:
touch /opt/containers/traefik/data/config.yml
Add a middleware to redirect http to https (/opt/containers/traefik/data/config.yml
):
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
Mount the new config.yml
file in the docker-compose file for Traefik (/opt/containers/traefik/docker-compose.yml
) (line 20):
version: "3"
services:
traefik:
image: traefik:v2.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
- ./data/config.yml:/config.yml:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
proxy:
external: true
Recreate Traefik container:
docker-compose up -d
Attention, Attention:
The redirection in the file provider does not work in the docker-compose for Traefik!
As a template we use the docker-compose of Portainer from the previous article. Replace the lines 19 and 20 with following line:
- "traefik.http.routers.traefik.middlewares=https-redirect@file"
The Portainer docker-compose (/opt/containers/portainer/docker-compose.yml
) now looks like this:
version: "3"
services:
portainer:
image: portainer/portainer:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(`portainer.example.com`)"
- "traefik.http.routers.portainer.middlewares=https-redirect@file"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(`portainer.example.com`)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.tls.certresolver=http"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
The @file
instructs Traefik to look inside config.yml
for the corresponding middleware.
So every time you want to redirect http to https, you can add the middleware https-redirect
. You can add multiple middlewares separated with a comma.
The chain middleware enables you to define reusable combinations of other pieces of middleware. It makes reusing the same groups easier.
The description above was stolen from here.
So let’s do this! Add some middlewares in the /opt/containers/traefik/data/config.yml
:
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
default-whitelist:
ipWhiteList:
sourceRange:
- "10.0.0.0/24"
- "192.168.0.0/16"
- "172.0.0.0/8"
default-header
middleware sets some basic security headers.default-whitelist
middleware allows only internal IP addresses.Then we add a middleware chain with the previously created middlewares:
secured:
chain:
middlewares:
- default-whitelist
- default-headers
The complete /opt/containers/traefik/data/config.yml
now looks like this:
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
default-whitelist:
ipWhiteList:
sourceRange:
- "10.0.0.0/24"
- "192.168.0.0/16"
- "172.0.0.0/8"
secured:
chain:
middlewares:
- default-whitelist
- default-headers
To use the chain we can add it as any other middleware:
- "traefik.http.routers.portainer-secure.middlewares=secured@file"
With the central middlewares and the middleware chain it’s easy to setup multiple containers with the same configuration.
You can also add additional labels for the same settings. Here an example for Nextcloud:
- "traefik.http.middlewares.nc-header.headers.customFrameOptionsValue=SAMEORIGIN"
- "traefik.http.routers.nextcloud-secure.middlewares=secured@file,nc-header"