Dynamic Traefik Configuration for multi host setup
Summary
In my Home Lab I have multiple hosts, some on the same machine virtualized with proxmox and some on different machines. I want to have a single entrypoint to my homelab protected with Traefik and Authelia. This is how I set it up.
Overview
My current HomeLab setup looks like this:
TODO: Insert image
One major annoyance in my setup has been routing Traefik between multiple hosts. Currently, I’ve achieved this using a static file configuration, where I manually define which ports on each server are used for each service. I then allow these ports through the firewalls on the respective servers.
While this approach works, it requires a lot of manual effort and is prone to errors. To address these issues, I aimed to automate and enhance this process, making it both dynamic and secure. My solution involves leveraging Traefik’s HTTP Provider to dynamically update Traefik’s configuration from a simple config file.
Goals
Here’s what I wanted to achieve:
- Edit a simple config file to define the services I want to expose.
- Commit changes to the configuration.
- Validate the configuration using a pre-commit hook.
- Push the configuration to the repository if validation passes.
- Trigger a Komodo build action to create a Docker image.
- Deploy the Docker image in a container on the same Docker network as Traefik.
- Notify a Discord channel when the new configuration is live.
- Allow Traefik to read the configuration from a REST endpoint and update accordingly.
Desired Config Structure
The configuration file is structured as follows:
Web API Provider
The first step was building the service. I had several technology options for this task. All the service needed to do was:
- Parse a
.toml
file. - Process the configuration.
- Generate a JSON object to expose through a REST API.
I chose Rust for this project because it’s a language I enjoy learning and using. Additionally, parsing .toml
files and creating JSON is straightforward with the Serde library. Building a simple web API is also easy with actix-web
.
CLI Commands
I used Clap to handle command-line arguments and implemented two commands:
start-api
: Starts the web API.validate
: Validates the configuration file.
The source code is available in my GitHub repository.
Pre-Commit Hook
To ensure configuration files are valid before being committed, I created a pre-commit hook.
Setting Up the Hook
-
Create a directory for hooks and set it as the
core.hooksPath
in Git: -
Create the
pre-commit
file in the hooks directory with the following content:
This ensures that any invalid configurations are caught early.
Automated Build and Deployment
I wanted to fully automate the workflow: edit config.toml
, push changes, and let the system handle the rest. This includes:
- Building the Docker image.
- Pushing it to a registry.
- Deploying it to the server.
Using Komodo for CI/CD
I used Komodo, a Rust-based CI/CD tool, for this process.
Setting Up the Registry
- Add the GitHub Container Registry to Komodo:
- Navigate to
Settings -> Providers
in Komodo. - Configure the provider:
- Domain:
ghcr.io
- Username: Your GitHub username.
- Password: A personal access token, generated as per this guide.
- Domain:
- Navigate to
Creating a Stack
I created a Komodo stack with the following configuration:
This stack points to a Docker Compose file in the repository’s run_directory
:
Automating Configuration Updates
To automatically update the container whenever config.toml
changes, I used Komodo Procedures. Procedures allow you to define a sequence of steps triggered by specific events.
Procedure for Updating the Container
Here’s the procedure I created:
Adding a Webhook
To trigger the procedure on push, I added a webhook from Komodo to my GitHub repository (Settings -> Webhooks
). The content type must be application/json
for it to work.
Integrating with Traefik
Finally, I configured Traefik to read the configuration from the Web API. Since the containers are on the same Docker network, communication is seamless.
I added the following to traefik.toml
:
Conclusion
With this setup, any changes to config.toml
are automatically validated, built, deployed, and reflected in Traefik’s configuration. Notifications are sent to Discord, keeping me informed every step of the way.
Future improvements
- Generate UFW rules for the services.
- Integrate with DNS-Cli-Tools