Traefik as a frontend proxy?

Has anyone explored using Traefik with Tutor as a frontend proxy? Régis briefly mentioned it a while ago. I spun up Traefik on the same VPS as Tutor and then realized that exclusions would have to go in the docker-compose.yml file to prevent Traefik from picking up the non-web-accessible containers. I’m not keen on migrating all of the settings each update, so I stopped looking at that point.

As someone not so familiar with traefik, could you explain to me what benefits we could get from using it? Would it be a replacement for nginx? Would it allow multi server deployments?

I lack knowledge of Tutor to say if Traefik if a good fit for the project. Additionally, I just started using Traefik. However, I recognized its strengths straight away.

In my option, here is what does well:

  1. It can seamlessly replace Nginx as a frontend proxy for docker-based applications. You put the essential configuration data in a single traefik.toml file. It then watches all Docker containers and tries to build a frontend proxy to them.
    1.1. You have to configure the docker-compose.yml file for each service.
    1.2. You can tell Traefik to ignore containers that you don’t want to access through a proxy, such as a database.
  2. It can provide a reverse proxy to a service running on localhost, much the same that Nginx does with proxy_pass.
    2.1. Traefik calls this feature a file provider.
  3. It automatically generates an SSL certificate through Let’s Encrypt for each defined service.

Yes, if you are using Nginx for a reverse proxy. It also replaces the need to specify additional Let’s Encrypt information because Traefik generates the certs when the service starts. Personally, I have no intention of using Nginx locally unless I need to, such as with Tutor.

Good question. This is something to explore. Traefik should be able to provide most of the common proxy and load balancing services as Nginx.


Here is a basic config that I use in Docker. It might help you to understand what a Traefik configuration looks like or to get going if you want to explore it.

All files go in the same directory.

  1. Create acme.json for let’s encrypt.
    touch acme.json && chmod 0600 acme.json

  2. Create the network for Traefik and Docker.
    docker network create web

  3. Configure Traefik using traefik.toml. Please note acme fails if you use an @example.com email address.

    defaultEntryPoints = ["http", "https"]
    
    [entryPoints]
    [entryPoints.http]
      address = ":80"
      [entryPoints.http.redirect]
        entryPoint = "https"
    [entryPoints.https]
      address = ":443"
      [entryPoints.https.tls]
    
    [acme]
    email = "real@example.com"
    storage = "acme.json"
    entryPoint = "https"
    onHostRule = true
      [acme.httpChallenge]
      entryPoint = "http"
    
    [docker]
    domain = "example.com"
    watch = true
    network = "web"
    
  4. Configure docker-compose.yml or you can use docker run.

    version: '3'
    
    services:
      traefik:
        restart: always
        image: traefik:alpine
        hostname: traefik
        container_name: traefik
        ports:
          - 80:80
          - 443:443
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./traefik.toml:/traefik.toml
          - ./acme.json:/acme.json
        labels:
          - traefik.enable=false
        networks:
          - web
    
    networks:
      web:
        external:
          name: web
    

At this point, you can start Traefik, and it should be functioning.

You can then spin up a docker-compose.yml stack specifying the traefik settings in labels. For example, this configuration shows the default Nginx banner with an SSL cert already created. I left some of the HTTP headers to demonstrate the inclusion of features.

version: '3'

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

services:
  web:
    image: nginx:latest
    ## Needed for a real site
    # volumes:
    #  - ./code:/code
    #  - ./site.conf:/etc/nginx/conf.d/site.conf 
    restart: always
    depends_on:
      - php
    labels:
      - traefik.backend=Backend site name
      - traefik.frontend.rule=Host:www.example.com
      - traefik.docker.network=web
      - traefik.port=80
      #
      # Security settings
      #
      - traefik.frontend.headers.SSLRedirect=true
      - traefik.frontend.headers.STSSeconds=315360000
      - traefik.frontend.headers.STSIncludeSubdomains=true
      - traefik.frontend.headers.STSPreload=true
      - traefik.frontend.headers.contentTypeNosniff=true
      - traefik.frontend.headers.frameDeny=true
      - traefik.frontend.headers.browserXSSFilter=true

    networks:
      - internal
      - web
  php:
    image: php:7-fpm
    ## Needed for a real site
    # volumes:
    #  - ./code:/code
    networks:
      - internal
    labels:
      - traefik.enable=false
  1. Traefik will register the web service and create a proxy to the value defined in traefik.port=. In this case, it is 80 as defined by image nginx:latest
  2. It will generate the cert for the site defined in traefik.frontend.rule=Host:.
  3. Traefik will ignore service php because of label traefik.enable=false.
    3.1 Omitting this value will cause Traefik to try to create a proxy to the service and generate an SSL cert for it. Let’s Encrypt will register the failure in the traefik container.

There’s something I don’t quite understand, as nginx does more than just routin: it serves static assets, caches some resources and sets http headers, for instance. Traefik does not perform all these tasks, unless I’m mistaken?

Correct. Traefik is not a webserver, so it cannot define static assets, such as those definied incms.conf.
It can set HTTP headers. https://docs.traefik.io/v2.0/middlewares/headers/

My interest in using it is to use it as a proxy on the VPS to access the Tutor stack.

I understand. In that case, the only container that you need to redirect traffic to is the nginx container. This container is in charge of dispatching the traffic to the other containers. That way, you could get rid of the nginx running on the host.

I think Traefik could be serve as a routing layer in a multi-server platform deployed, for instance, with docker swarm. That might be a low hanging fruit to allow multi-server deployments with Tutor. I’m currently working on something else but I’ll certainly investigate that in the near future.