Crony Akatsuki

Setup Traefik

19-01-2024


Do you use docker? Do you use nginx or apachi to proxy the container? Fear not you won’t be needing them anymore once you are done with this tutorial.

Traefik is a simple docker centric proxy manager that is amazing and allows you to easilly proxy you docker containers with just a couple of labels.

Setting up Traefik

In this part we will setup traefik, with the dashboard enabled and secured with https and a password.

Create a directory where you will keep traefik configuration files and the docker compose. Inside it we will save all the configuration files.

docker-compose.yml

version: '3'

services:
  traefik:
    image: traefik:v2.5 
    container_name: traefik
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./traefik.toml:/traefik.toml
      - ./traefik_dynamic.toml:/traefik_dynamic.toml
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./acme.json:/acme.json
    networks:
      - web
    labels:
      - traefik.enable=false
    restart: unless-stopped

networks:
  web:
    external: true

What we are doing here is binding the needed configuration files, the docker socket so traefik can listen to it and automatically proxy the services, and the acme.json which will keep our ssl certificates.

We are also forcing it to use the latest available stable image to make sure there are no bugs, and disabling proxying the traefik image itself io the lables to make sure it isn’t exposed by any means.

We are also making it so it can restart itself unless we specifically stop it, and binding it to port 80 and 443 because those are the default http and https ports that every browser uses when connecting.

traefik.toml

[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

[api]
  dashboard = true
  insecure = false

[certificatesResolvers.lets-encrypt.acme]
  email = "name@domain.tld"
  storage = "acme.json"
  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

[providers.docker]
  watch = true
  network = "web"

[providers.file]
  filename = "traefik_dynamic.toml"
  watch = true

In the entryPoints we are defining the http and https ports and forcing http to redirect to https.

In the api section we are enabling the dashboard, but disallowing insecure access to it.

In the rest of the config we are defining the mail and storage for tls certificates, and enabled docker provider binded to a web network, and enabled the file provider for the dashboard setup.

traefik_dynamic.toml

[http.middlewares.simpleAuth.basicAuth]
  users = [
    "somebody:$apr1$whatever"
  ]

[http.routers.api]
  rule = "Host(`monitor.domain.tld`)"
  entrypoints = ["websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"
  [http.routers.api.tls]
    certResolver = "lets-encrypt"

Here we are defining the basic auth credentials and routing the monitor domain to the dashboard with basic auth credentials and https.

Make sure to subsitute the string in qutes for users with what you get generated with httpasswd command: htpasswd -n somebody.

acme.toml

To create acme.toml run this command touch acme.toml && chmod 600 acme.toml and we are done.

docker web network

You might have seen the networks part in the docker compose, we need to create it to make other docker containers in different docker compose files be accessible to traefik so it can proxy to them.

To create it we just need to run docker network create web and we are done.


After all this is done, we can just run docker compose up -d and if everyting was setup correctly, running docker compose logs -f shouldn’t show any errors.

Using trafik to proxy to docker containers

Now I’m going to explain to you how to use traefik to proxy to docker containers by using labels. For that I will be using ntfy docker image as an example.

docker-compose.yml

version: "2.3"

services:
  ntfy:
    image: binwiederhier/ntfy
    container_name: ntfy
    command:
      - serve
    volumes:
      - ./cache:/var/cache/ntfy
      - ./ntfy:/etc/ntfy
      - ./users:/var/lib/ntfy
    healthcheck:
        test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
        interval: 60s
        timeout: 10s
        retries: 3
        start_period: 40s
    restart: unless-stopped
    networks:
      - web
    labels:
      - traefik.http.routers.ntfy.rule=Host(`ntfy.domain.tld`)
      - traefik.http.routers.ntfy.tls=true
      - traefik.http.routers.ntfy.entrypoints=websecure
      - traefik.http.routers.ntfy.tls.certresolver=lets-encrypt
      - traefik.port=80

networks:
  web:
    external: true

The important part’s of this docker compose are the following:

As you can see, with traefik you don’t need to expose port’s from the container making it a lot more secure as it can directly proxy to them from itself using the web network.

In labels we are defining the host domain we wan’t to proxy to our container, we are also enabled tls and with entrypoints making the container only acessible from https, making it impossible to be accessible with http no matter what.

We are also defining the certresolver to be lets-encrypt and setting the port from the container that traefik needs to proxy to 80, this port can be different depending on what you want to proxy.

We are also defining the web external network that is ussed so traefik can access to the container and proxy to it.


After you have accustomed the config to what you need, you can just docker compose up -d, go to your traefik monitor and after some time you will see ntfy addedd to reverse proxying with tls certficate and only accessible from https.

Disabling traefik

Next I will be talkling about how to disable traefik for containers because you don’t want it to work for containers you dont want accessible over the network.

Disabling for one service docker-compose

As the main example, I have a watchtower instance that I dont wan’t proxied to the outside world. To do that we just add traefik.enable=false to the labels and trafik will stop being naughty.

example

...
    labels:
      - traefik.enable=false
...

Take note that for this kind of docker-compose files, networks part IS NOT NEEDED, just create the docker compose file as you would usually without having the networks part.

Disabling for more complex docker-compose

Now here comes the more tricky part, disabling it for only specific docker containers, and making it so traefik cant access them from its network. To accomplish that we will use the traefik.enable=false label once again, and make use of multiple networks to make sure traefik can only access the web interfaces and keep other containers secure like databases and only accessible to the web interfaces.

example docker-compose.yml

version: "3"

networks:
  web:
    external: true
  internal:
    external: false

services:
  blog:
    image: wordpress:4.9.8-apache
    environment:
      WORDPRESS_DB_PASSWORD:
    labels:
      - traefik.http.routers.blog.rule=Host(`blog.domain.tld`)
      - traefik.http.routers.blog.tls=true
      - traefik.http.routers.blog.tls.certresolver=lets-encrypt
      - traefik.port=80
    networks:
      - internal
      - web
    depends_on:
      - mysql

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD:
    networks:
      - internal
    labels:
      - traefik.enable=false

  adminer:
    image: adminer:4.6.3-standalone
    labels:
    labels:
      - traefik.http.routers.adminer.rule=Host(`db-admin.domain.tld`)
      - traefik.http.routers.adminer.tls=true
      - traefik.http.routers.adminer.tls.certresolver=lets-encrypt
      - traefik.port=8080
    networks:
      - internal
      - web
    depends_on:
      - mysql

Here we can see what I was talking about in action, take note I took this docker compose file from this digital ocean blog post that explains it a lot better I could which you can use as a reference if you didnt understand something about what I was talking about.

Conclusing

I hope that you were able to setup traefik, or if not and were just reading to see what its all about I hope you had a good read and might have decided to try out traefik in the future.