(╯°□°)╯︵ uozɐɯɐ - (╯°□°)╯︵ ʞooqǝɔɐɟ - (╯°□°)╯︵ ǝlddɐ - (╯°□°)╯︵ ǝlƃoooƃ
/***********************************************************************************************
* \name NokiDev's blog
* \author Timothé "NokiDev" Van Deputte
* \brief A Tech blog about infrastructure and development
* \details Described with asciidoc, built with Hugo and hosted on Github.
* \note Source repository is available at https://github.com/NokiDev/blog
* If you find any inconsistencies or want to talk please submit an issue :)
***********************************************************************************************/

Using Traefik v2.2 to selfhost your first service.

Read this in : Français

Traefik is a modern reverse proxy that integrates with container technologies and related orchestrators. In our case we’re going to use it’s docker integration. Traefik uses docker socket to retrieve information about running containers, and labels that are attached to it. (if you use docker inspect you would get the idea.)

This article requires that you are already familiar with container thechnology and especially docker.

Disclaimer: This article is not meant to secure your services, it is a pretty basic setup to start with traefik, if you want to secure your services head to the next article of this series

Setting up traefik

We’ll use the following docker-compose.yml file :

version: '3.7'

networks:
  proxy:
    external: true

services:
  traefik:
    image: traefik:v2.2.1
    restart: unless-stopped
    container_name: traefik
    ports:
      - 127.0.0.1:8888:80 # Change 127.0.0.1 by 0.0.0.0 if you try this in a VM / or distant server
      - 127.0.0.1:8080:8080
    environment:
      TZ: "Europe/Paris" # Setting Timezone.
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # Needed to allow traefik access docker api.
      - /etc/localtime:/etc/localtime:ro # Sharing time with host OS as read only (ro).
      - ./config.yml:/etc/traefik/traefik.yml
    networks:
      - proxy

As you may have notice there is a network called proxy that is referenced by this file. It is defined as external, because we want other services to use it too, and defining it external allow to create other services before actually deploying this docker-compose file. + if you use docker-compose rm it won’t try to remove the network.

To create the proxy network simply call docker network create proxy

Let’s talk about the config volume that is defined too. Traefik can be configured either with command line arguments, env variables and configuration file (Called static configuration in the documentation), the latter will be used. And we will create it now. I prefer the yaml format because it avoids repeating your self between subsections and I’m lazy.

Our config will need to define one entrypoint and the docker provider section. I advice you to take a look at the docs and tweake it to follow your needs.

global:
  sendAnonymousUsage: false

api:
  dashboard: true ## Enable dashboard visulization on port 8080
ping: {}


providers:
  docker:
    network: proxy
    watch: true
    exposedByDefault: false

entrypoints:
  web: # This name is arbitrary you can name your entrypoint the way you want.
    address: ':80'

Finally you can run traefik by running docker-compose up -d and check that everything is running fine by going to the dashboard at localhost:8888 (or ip_of_the_machine:exposed_port)

Setting up our service

The services we’re gonna setup is : projectSend. I choose it because it is very easy to setup and don’t require any other external service to work.

We’ll be using this docker-compose.yml (Largely inspired from there: https://hub.docker.com/r/linuxserver/projectsend).

version: "3.7"

networks:
  proxy:
    external: true

services:
  projectsend:
    image: linuxserver/projectsend
    restart: unless-stopped
    container_name: projectsend
    environment:
      PUID: 1000
      PGID: 1000
      TZ: Europe/Paris
      MAX_UPLOAD: 5000
    volumes:
      - /etc/localtime:/etc/localtime:ro # Sharing time with host OS as read only (ro).
      - ./config:/config
      - ./data:/data
    ports:
      - 9999:80
    networks:
      - proxy
    labels:
      traefik.enable: true
      traefik.http.routers.projectsend.rule: Host(`127.0.0.1 or ip of your machine`)
      traefik.http.routers.projectsend.entrypoints: web
      traefik.http.services.projectsend.loadbalancer.server.port: 80

Okay so you may have noticed that we once again declare the proxy network and attached it the service (it is really important and it is a common mistake to omit it, so be careful).

The service is exposed on port 9999. It will be used for debugging purposes since all traffic should go over traefik and be accessible on port 8888.

Okay now, let’s take a look at the labels dict. The labels will be used by traefik for proxifying request to the service. It is known as Dynamic Configuration in the documentation and more precisely it is the docker Dynamic configuration, the complete reference can be found here. In this configuration, we ask traefik to enable the route (since we specified not exposedByDefault in the static configuration above).

Here there is two kind of concepts
  • The routers, that configure the way requests are provided to the service

  • The services, that give information about how the service is hosted and available.

In our case the configuration is pretty basic, we tell the router called projectsend to listen to traefik http entrypoint (port 8888). we tell the router to accept requests based on a rule, in our case either 127.0.0.1 or your host ip. And we tell traefik that a service called projectsend listens on port 80 which is container side exposed port. (we do not use port 9999 since this port is open from the host side.)

And that’s it. With such informations, traefik will be able to forward request comming from traefik:8888 → projectsend:80.

We can run docker-compose up -d and access projectsend from localhost:9999 and localhost:8888 which is traefik.

Congratulations you have selfhost your first service using traefik !

Before doing some crazy things and expose anything on the internet, you must add some security like HTTPS or secured http headers.

You can find this in the next article of this series : Secure your Traefik Installation

I also suggest you to take a look at the documentation, and doing some experiments locally.