---
title: "Traefik migrated to v2"
author: Yarmo Mackenbach
slug: traefik-migration
date: "2020-05-09 23:01:34"
published: true
---

`#100DaysToOffload >> 2020-05-09 >> 015/100`

Last september, [traefik](https://containo.us/traefik/) received its [big version 2 update](https://containo.us/blog/traefik-2-0-6531ec5196c2/). I was very excited about TCP routers and the newly implemented middlewares. Can't have been more than a few days later that I tried to migrate my homelab to the new version. I remember being annoyed by the lack of a proper migration guide. Sure, it's possible that I didn't look good enough, but I searched for it for a few days without results. I tried using the new documentation and failed, everything crashed and could not get it working. As I did not have the time to do much more extensive research and also, I needed the selfhosted services on a daily basis, so I left it.

Until today. The whole migration took me a little over three hours and I learned quite a bit on the way. Also, the [migration guide](https://docs.traefik.io/migration/v1-to-v2/) has helped quite a bit. If this was updated since September, great article. If not, still a great article and I really did not take the appropriate amount of time to prepare my migration.

## Easy steps

The first thing I did was a general search-and-replace for the docker labels (both routers and services). What was `traefik.frontend.rule=Host:xyz` now is `traefik.http.routers.router0.rule=Host(``xyz``)`. What was `traefik.port=80` now is `traefik.http.services.service0.loadbalancer.server.port=80`. Quite a bit longer and more cumbersome, but in the end, more extensible.

The `traefik.docker.network=xyz` is now unnecessary in most cases as you can define a default network in the `traefik.toml` file. Speaking of which, you can now work with a YAML file. It's not to everyone's taste, but I will switch to it in the future when I have some more time.

The `traefik.toml` still needed quite the makeover, but everything is will explained in the [migration guide](https://docs.traefik.io/migration/v1-to-v2/) and the [reference page](https://docs.traefik.io/reference/static-configuration/file/). Content-wise, I changed little, it's just that the syntax is different. Notable changes are the domains for which certificates are needed now are declared in the `entrypoints` section instead of the `acme` section and the `file` section can no longer include the "router/service declarations", they belong in a separate file.

## Pitfalls

Doing this resulted in a non-functional state. Two different possibilities: either the container could not be redirected to the correct service resulting in a 404, or the redirect was correct but without correct certificate. That first possibility was mostly on me: containers are now no longer exposed by default and I forgot to add `traefik.enable=true`. Mind you, I always set `traefik.enable=false` when I didn't want a container exposed and still do.

However this did not solve the issue for all the containers. I suspect there's still some trickery I need to do in case of using multiple routers. I tried explicitly specifying the `service` for the different routers but that wasn't the solution.

As for the other issue, the solution was simple but finding the source was quite hard: as it turns out, I renamed the `certificateResolver` to something other than `default`. If such is the case, then containers will NOT automatically use it for their certificates. Adding `traefik.http.routers.router0.tls=true` and `traefik.http.routers.router0.tls.certresolver=mycertresolver` to each container solves this issue.

## Todo

One thing I haven't got working yet is using the `providers.file` provider. I tried to mimic the container labels but to no avail. Yet.

---

**Update 2020-05-12**: I fixed the `providers.file` issue. Remember kids, always read the documentation well. It turns out, I missed the line that starts with `*` in the code below.

```
[http.services]
    [http.services.Service01]
        [http.services.Service01.loadBalancer]
*           [[http.services.Service01.loadBalancer.servers]]
                url = "foobar"
```