This guide details how to deploy Traefik using Docker compose (with Dockge) and Cloudflare as our DNS Challenge provider to generate Let’s Encrypt certificates for local infrastructure (not internet-accessible) and use basic authentication to protect the Traefik Dashboard. The configuration files presented can also be used with other deployment methods, such as Unraid.
This guide details how to deploy Traefik using Docker compose (with Dockge) and Cloudflare as our DNS Challenge provider to generate Let’s Encrypt certificates for local infrastructure (not internet-accessible) and use basic authentication to protect the Traefik Dashboard. The configuration files presented can also be used with other deployment methods, such as Unraid.
Revision: 20240908-0 (init: 20240831)
This post details installing the Traefik Proxy using docker compose (with Dockge). We perform a deployment using a traefik.yaml configuration file and dynamic independent configurations to provide proxying for docker containers and external services.
Traefik is an open-source reverse proxy and load balancer designed for cloud-native applications. It is particularly suited for microservices and containerized environments like Docker and Kubernetes.
Traefik serves several key functions:
Automatic Service Discovery for Docker services and routes traffic to them without requiring manual configuration (when enabled)
Load Balancing for HTTP, TCP, and UDP traffic.
It supports SSL/TLS termination and automatically generates certificates using ACME providers like Let's Encrypt.
Dynamic Configuration: It continuously updates its configuration in real time, eliminating the need for restarts or manual updates when services are added or removed.
It includes various middleware options for tasks such as authentication or rate limiting.
Traefik is based on the concept of EntryPoints, Routers, Middlewares and Services.
The main features include dynamic configuration, automatic service discovery, and support for multiple backends and protocols.
EntryPoints: EntryPoints are the network entry points into Traefik. They define the port which will receive the packets, and whether to listen for TCP or UDP.
Routers: A router is in charge of connecting incoming requests to the services that can handle them.
Middlewares: Attached to the routers, middlewares can modify the requests or responses before they are sent to your service
Services: Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
Acknowledgments
The configuration files for this guide were developed thanks to the many other great primers, in particular:
Please review the Preamble and Prerequisites section of a previous blog post on Reverse Proxy for some of the concepts we will use here as well.
To use this guide you will need to have a DNS hosted at Cloudflare.
Pre-requisite:
An A record for *.example.com (wildcard) setup at Cloudflare pointing to the private IP on the host that will host Traefik: 192.168.22.11
A custom Cloudflare Token:
From the Cloudflare Dashboard, on the “Overview” section, look for “Get your API token” (on the left side), then “Create Token → Create Custom Token”
Give it a name, for example traefik (example.com)
For “Permissions”, select:
“Zone - Zone Settings - Read” and “Zone - Zone - Read” to allow the token to Read DNS Zones
“Zone - DNS - Edit” to allow the token to edit DNS records (required for the DNS-01 challenge)
For “Zone Resources”, select:
“Include - Specific Zone” select the example.com zone.
After the token is created, make sure to store it in a safe place, it will not be displayed again.
Docker compose setup
👉
We will use Dockge to deploy Traefik.
Please refer to a previous Dockge post for details on setting it up.
From the Dockge dashboard “+Compose” a new traefik stack and “Save” it (do not deploy just yet).
We need to prepare a few files in the /opt/stacks/traefik directory (make sure you are able to write in the directory):
# Create the configuration base directory (config)
# and the dynamic configuration directory (conf)
mkdir -p config/conf
# Create an empty acme.json file to store our Certificates details
touch config/acme.json
# Change the file permission. An error will occur if this is not done
chmod 600 config/acme.json
Although we are deploying this setup using Dockge, it is possible to use the following files with other deployment methods, such as from Unraid’s Community Applications — in which case we would not make use of the provided compose.yaml file and would use the Unraid template’s environment variables to pass some values.
We added comments to the file to help you review its content and adapt some sections accordingly. Among the settings the file sets:
the global: section checks for updates and disables usage reporting
the api: section enables the dashboard (we will specify its url on the command line)
the entrypoints: section sets the http and https ”entrypoints” which will be used by our “routers” configuration.
The http settings always redirects entries to the https.
The https settings specify the certResolver name we will use as well as the domains used, including our *.example.com wildcard certificate.
the middlewares section specifies some @file rules; those will be defined in the config/conf directory.
the providers: section sets
the file ”providers” as the content of the conf directory
the docker ”provider” for
containers that are on the traefik_default network (this network will be created by Dockge when the stack is started)
container are not exposed by default: a traefik.enable label must be set to true for the container to be seen by Traefik (see the whoami example in the compose.yaml file)
will automatically name the resulting URL as the container’s name (ex: dozzle.example.com). In case of potential service collisions, renaming each container is an option or a rule label can be used:
traefik.http.routers.my-container.rule=Host(`container-url.example.com`)
the certificatesResolvers: section is where the ACME exchange with Let’s Encrypt using Cloudflare for the DNS Challenge is performed.
the resolvers: section will verify that the _acmeTXT entry was added to the Zone (example.com)’s DNS. The recommended entry for Cloudflare is 1.1.1.1. If you have a system that performs DNS over HTTPs upgrades, you will want to point that resolver directly to the IP of that system.
Dynamic Configurations (config/conf destination)
💡
Note that the file name does not matter, only the file content does, although it is recommended to name those files in such a way as to enable you to find those later.
The following files go in the /opt/stacks/traefik/config/conf folder and are all available for download at the same GitHub repo.
tls.yaml
Download the tls.yaml file. This file contains some requirements for minimum supported ciphers and TLS versions for access to the services.
middlewares-securityHeaders_light.yaml
The middlewares-securityHeaders_light.yaml file defines a limited number of restrictions. It is usable for https-upgrading of private accessible networks only, as it will among other allow iFrames embedding. It is the default entry used by the https entrypoints.
The middlewares-gzip.yaml file specifies that connections should use the gzip compression.
middlewares-dashboardauth.yaml
In the middlewares-dashboardauth.yaml is a basicAuth configuration that we will be using to protect the Traefik Dashboard. Modify the value of the user and password by using htpasswd (example command line in the comments).
middlewares-localonly.yaml
Download the middlewares-localonly.yaml file. It defines another “middleware” to limit access to localhost, the LAN subnet (here 192.168.22.1/24, adapt as needed) and commented is the Tailscale 100. range (CGNAT: 100.64.0.0/10). If you have another VPN setup to reach your subnet, add the tunnel’s network pool to that list.
We note that we are not making use of this middleware in any entrypoint.
compose.yaml
Obtain the compose.yaml file and fill the Dockge entry with it. You will need to replace 2x entries with example.com with the value of your domain (for the dashboard and the whoami service).
We need to create an environment variable for this stack (replace with the token you obtained earlier) CF_DNS_API_TOKEN=REPLACE_WITH_YOUR_SECRET_API_KEY
Depending on which guide you follow, you will see most entries that we placed in configuration files within the command: section of the compose.yaml (ours is empty). In the labels: section we have added definitions for the Traefik dashboard configuration: its URL (the rule entry), and its middlewares (here the dashboardauth@file , i.e. dashboardauth middleware found in a file placed in the directory set in the fileproviders:.
The definition of the whoami stack explains simply how to have Traefik create a reverse proxy for the service, the traefik.enable=true label tells it to create a rule. By default, the URL would be using the container’s name, this is overridden by the rule entry that sets the full URL. This also defines that the routers:’s name is whoami: traefik.http.routers.whoami.rule. This name is again used to specify the entrypoint: traefik.http.routers.whoami.entrypoints=https.
After saving and starting the stack, within a few seconds, you will have some content within the /opt/stacks/traefik/acme.json file, among which the email address you specified for Let’s Encrypt, and the Certificates for your domain.
Once this is confirmed, the whoami service will be available at https://whoami.example.com/. When accessing it, we will see details of the connection, confirming that Traefik is up and running and upgrading connections to HTTPs for our example.com domain.
Accessing the Traefik Dashboard is done by going to the URL set in the rule entry of the compose.yaml: https://traefik.example.com/ with the caveat that you will be prompted for the username and password that you set in the middlewares-dashboardauth.yaml file (the defaults in that file are admin and password).
Adding services
Dockge containers
To add a container existing within Dockge to the list of url proxied by Traefik, we need to extend that stack’s compose.yaml with additional content.
We will use the Dozzle service as an example, as detailed in the Dockge post. Stop that stack before editing it.
To have the service being recognized by Traefik, we need to
Make the service use the traefik_default network
networks:
- traefik_default
, and recognize the network as external to the container:
networks:
traefik_default:
external: true
Add labels for the container to be seen by Traefik, specify its url (rule) and specifying the https entrypoint (as defined in our traefik.yaml's entryPoints: section):
After restarting the stack, we can now access it at https://dozzle.example.com/
💡
Because the container_name is dozzle we do not need to add the rule label, as the service url would have been the value of that variable (per the defaultRule for dockerproviders: entry in the traefik.yaml).
We recommend the habit of using all three labels.
Adding an external service
To add a proxy for a service that is not on the Dockge stack or on another host, we have to define specific routers: and services:. Because we are using files to store our configuration, create a new yaml file in the config/conf directory that is being watched by Traefik. We have added an exampleroute-ollama.yaml in the GitHub with all its content commented (to avoid the content from being used if you copied all the files).
Its uncommented content would be as follows:
http:
# Routers and Services -- https://doc.traefik.io/traefik/routing/overview/
routers:
ollama: # name
entryPoints:
- https # use the "https" entrypoint
rule: 'Host(`ollama.example.com`)' # Destination URL to resolve
service: ollama # name for services matching entry
# middlewares: # specify middleware(s) if any
# - "securityHeaders@file" # the default "https" entrypoint follows the "light" security headers version, uncomment this section to enble the more restrictive version
services:
ollama:
loadBalancer:
servers:
- url: http://192.168.22.12:11434/
This define a new ollama.example.com URL the would reverse-proxy to http://192.168.22.12:11434/ (notice the different IP on our subnet).
Simply adding the file in the folder will enable the new proxied entry.
We have commented the more restrictive security headers as a demonstration of how to include the additional middlewares to the default one. If using those as labels, this ollama example would be added using traefik.http.routers.ollama.middlewares=securityHeaders@file
Docker labels
The following are useful for copy→adapt→paste.
Generic labels
When using Traefik, adding a new service to the reverse proxy can be as simple as extending the labels: section of the compose.yaml file with something akin to:
replace example.com with your domain (1x replacement)
update SLUG to reflect the base URL of the service you are exposing (3x replacements)
Unraid labels
(This is only usable if Unraid was Traefik’s deployment method)
Although it is possible to manually “Add” “labels” for each required label using the Unraid WebUI, it is also possible to modify the Docker service’s XML file.
Those are in the /boot/config/plugins/dockerMan/templates-user folder and are named my-<SERVICE>.xml . Once we have found the match entry, we can edit it and copy the adapted lines before the final </Container> line:
SLUG with the base URL of the service whose port you are exposing — this will replace the values in .routers. and Host( (6x replacements)
💡 After modifying the XML file, from Unraid’s “Docker” tab, Edit the Service then make and undo any change to enable the Save button. Save it to restart the updated service.
docker compose setup for HomePage with Dashdot and Watchtower widgets from Komodo or Dockge, including detailing the dashboard setup for a multi-tab layout with four sections of content: system metrics, static content, dynamic applications (docker service discovery), and service monitors.
Dockge deployment of the “Nginx Proxy Manager” reverse proxy to create private-network routable URLs with a Let’s Encrypt wildcard certificate and Cloudflare as our DNS provider.
Linux host set-up instructions for Dockge, a self-hosted Docker Compose stacks management tool with a feature-rich interface for self-hosting and home lab setups. It provides access to an all-in-one view of logs, a YAML editor, a web terminal, container controls, and monitoring.