Traefik¶
This is a practical guide for using Traefik v2 with docker-compose, I used this pattern previously, but have now gone all-in on Kubernetes.
Create docker network¶
First, lets make two docker networks dedicated to reverse proxying. One for our local network, and one for accessing externally outside our network.
We seperate these, so that we can isolate applications that are accessible outside the network.
Run the following commands to create the docker networks, these networks will be created in bridge mode and will persist after reboot
1 2 |
|
We need to run these docker commands manually, defining these network in a
docker-compose.yml
will take down the networks if we rundocker-compose down
, which will make dependent containers fail to start.
Basic traefik container¶
If you have not already done it, I recommend to create a folder hierarchy for easier management of your docker-compose files, as mentioned in my introduction post.
The volumes and network created by docker-compose will append the folder name to the docker resources, so in this case the internal network will be called
traefik_internal
.
1 2 |
|
Inside the traefik folder, we can now create the docker-compose.yml
file for traefik
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 |
|
Line | Description |
---|---|
L3:L8 | For networks, we add the docker network we created earlier as a external network. Which means that docker will try to connect to this network, but never create nor destroy it. We also have a internal network, which will only be used between services in this docker-compose. |
L15 | Change the timezone to your current one, this will be used by things like traefik dashboard and logs. |
L16:L18 | Traefik will bind to port 80 and 443 on the host, as this will be our primary reverse proxy. |
L19:L22 | Here we define the networks that Traefik will connect to, we will add more networks later for other integrations. Also, L3:L8 only makes networks available for the containers. |
L23:L26 | The traefik configuration files, mounts files in the traefik folder into the container. |
L28 | The traefik container will not start before the docker proxy. |
L29 | Traefik will restart on reboot, unless you stop the application with docker-compose down |
L31 | Mounting a container to the docker API on the host is a huge security risk, so we can use a sidecar container which will make only a partion of the API accessible to the traefik container over a dedicated docker network. I highly recommend to search the web for this topic. |
L37 | Here we can define which docker APIs that are available for read-only access, you can read more about the available APIs here. |
Basic Traefik configuration files¶
Now that we have the docker-compose.yml
in place, we need to create the configuration files for traefik, which will be mounted from the root folder into the docker container.
First we need to create two folders in our traefik folder. Create a config
folder and a dynamic
folder inside the config
folder.
1 |
|
Inside the config
folder we can now create a traefik.yml
file, which will be the primary config 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 |
|
Line | Description |
---|---|
L1:L5 | Here we define which ports Traefik should listen on. |
L7:L13 | This bit is related to the automatic certificate generation for sites that are available externally, change the email to get warnings for expiring certificates. |
L17 | The default docker network when configuring backends, if the app runs in another network, this needs to be overridden by a label on the container. |
L18 | Do not expose containers when they are detected in the docker API, we need to add a traefik.enabled label to the container since this is false. |
L19 | Traefik connects to the docker-proxy over the traefik_internal network when connecting to the docker API. |
L21 | Traefik will monitor this directory for configuration files, and automatically reload these if there are any changes made to the files. |
L24 | Readies the dashboard by enabling the necessary APIs, further configuration is needed. |
ACME certificate file¶
ACME requires a dedicated acme.json
file for storing its certificates, create it by running
1 |
|
Starting Traefik¶
We have now added all of the necessary static configuration files for running Traefik. We can now start Traefik to see if it is running properly
1 |
|
If the application starts, and there are no errors. You can close the session above, and let it run in the background
1 |
|
Now you should open up a new shell and follow the logs for the traefik
container for the next steps, where you will see that traefik
dynamically loads the configuration files as we edit them.
1 2 |
|
Dynamic configuration files¶
Every configuration file that you create inside the dynamic
folder, will be automatically reloaded. This makes it easy to create new routing rules, as you can listen for the Traefik container logs and check the endpoint while editing files for efficient setup.
Let's add two dynamic configurations, dashboard.yml
for the Traefik dashboard and redirect.yml
for redirecting any external sites from HTTP to HTTPS
dashboard.yml
:
1 2 3 4 5 6 7 8 9 |
|
Line | Description |
---|---|
L4 | The domin where the Traefik dashboard will be available from. |
L5 | Connects the dashboard router to the traefik api which we made available in traefik.yml |
L9 | Dashboard will only be available from the local lab network |
redirect.yml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Line | Description |
---|---|
L5 | This rule applies to incoming traffic on HTTP (Port 80) |
L6 | Only redirect traffic if its coming from yourexternaldomain.com, change to your own FQDN. |
L7:L8 | If the L6 rule is active, use the https_redirect middleware on L17:L21 |
L11:L15 | Services are used for forwarding traffic, since we only want to redirect the traffic to HTTPS, we set this to the host ip. |
L17:L21 | Use the redirectScheme middleware to redirect the request from HTTP to HTTPS |
Folder structure after you are done¶
When you are done with all the config files above, the traefik
folder should look like this
1 2 3 4 5 6 7 8 9 |
|
Next, take a look at the Traefik Usage guide, and/or the PiHole guide for resolving .lab
HTTP requests.
Practical examples¶
Use Case 1: Local lab network only¶
Local network only example using homer, which is available from http://home.lab/, if you have setup a DNS server as i have done in the PiHole guide.
Example .env
enviroment file, which i use for all my Traefik applications
1 2 3 4 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Line | Description |
---|---|
L3:L5 | We only want homer to be accessible from our lab network |
L14:L15 | The network will be mounted by the container |
L17 | In traefik.yaml we have set exposedbydefault: false , so we need to enable Traefik for this application |
L18 | Tell Traefik that the entrypoint for this application is over HTTP |
L19 | Here we define the domain that Traefik should redirect traffic to this application, which is now http://home.lab |
L20 | This is the port that the application is listening for. If the application have a EXPOSE port defined in the Dockerfile, then Traefik should be able to auto-detect this. |
Use Case 2: Accessible from the internet¶
Continuing with the example above, we make some slight changes
1 2 3 4 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Line | Description |
---|---|
L3:L5 | Now we want homer to be accessible from the internet over the web network |
L14:L15 | The network will be mounted by the container |
L17 | In traefik.yaml we have set exposedbydefault: false , so we need to enable Traefik for this application |
L18 | Tell Traefik that the entrypoint for this application is over HTTPS |
L19 | Here we define the domain that Traefik should redirect traffic to this application, which is now https://home.yourdomain.com |
L20 | This is the port that the application is listening for. If the application have a EXPOSE port defined in the Dockerfile, then Traefik should be able to auto-detect this. |