Traefik2 is an Edge Router for your Services like Docker Containers. Unlike other reverse proxys Traefik comes with some nice additions like automatic service discovery and issuing of certificates. Unfortunaly there are few tutorials walking you through end to end.
Setting up Traefik
In most Tutorials Traefik itself is configured via labels, however I find it best to use a config file for clearity.
We begin with creating a docker network for our frontfacing services:
docker network create traefik2_net. Next we create an empty file called
acme.json here we will store the certificates. Important: This file has to have permisions set whith
chmod 600 ./acme.json.
Next we will create the docker-compose file:
version: "3.3" services: traefik: image: "traefik:v2.2" # Pin to a Version to avoid breaking changes container_name: "traefik" # Give the container a clear name restart: always # Always restart (unless-stoped is also ok!) ports: - "80:80" # Listen on port 80 - "443:443" # Listen on port 443 volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" # Read(-only) the Docker Socket - "./traefik.toml:/etc/traefik/traefik.toml:ro" # Read(-only) the Config File - "./acme.json:/acme.json" # A File to safe Certificates - "./config.toml:/config.toml:ro" # Further config file, also Read only networks: # Define a Front-Facing Network default: # It's this containers default network external: # It is not bound to this container name: traefik2_net # And its called traefik2_net
In this file we mentioned two config files we did not create yet.
config.toml we will get to them next.
The main config file is
[log] level = "ERROR" # Its a good Idea to have logs but we don't have to [providers] [providers.docker] # Our Provider is Docker endpoint = "unix:///var/run/docker.sock" # And its Endpoint is the SockFile exposedByDefault = "false" # We don't expose containers by default [providers.file] # Our second provider for aditional config filename = '/config.toml' [entryPoints] [entryPoints.http] # Our entrypoints named http and https the names are yours to choose address = ":80" # This entrypoint listens to everything on 80 [entryPoints.https] address = ":443" # https listens on 443 [certificatesResolvers.le.acme] # Provider for Certs email="firstname.lastname@example.org" # your email is needed storage="acme.json" # Here are the certs stored [certificatesResolvers.le.acme.tlsChallenge] # We will use the tls Challange
congif.toml defines a middleware for https redirect:
[http.middlewares] [http.middlewares.redirectHttps.redirectScheme] scheme = "https"
Armed with this config Files we are finaly able to start
docker-compose up -d
Configuring A Service
Services are configured via labels in the docker-compose file. This example will contain a Database and a service listening to a diffrent port than port 80
version: "3.7" services: db: # The Database image: postgres:12 environment: - PGDATA=/db-data - POSTGRES_PASSWORD=postgres volumes: - ./db:/db-data:rw # The Database will only connect to the backend Network networks: - backend app: image: example command: bash -c 'gunicorn example.wsgi -b :8080 --log-level=info' # Here we will configure Traefik with; labels: # This will make the service visible for Traefik - "traefik.enable=true" # The Traefik Network is this Network and not backend - "traefik.docker.network=traefik2_net" # This is the hostname we want use for http - "traefik.http.routers.example.rule=Host(`example.bithive.space`)" # The Entrypoint is http (as defined in traefik.toml) - "traefik.http.routers.example.entrypoints=http" # We want to have certs via our resolver defined in traefik.toml - "traefik.http.routers.example.tls.certresolver=le" # We want to redirect all trafic via our middleware defined in the file provider - "traefik.http.routers.example.middlewares=redirectHttps@file" # We will also listen on https: - "traefik.http.routers.example-https.entrypoints=https" # We will use certs for this connection - "traefik.http.routers.example-https.tls=true" # This is the host for https - "traefik.http.routers.example-https.rule=Host(`example.bithive.space`)" # Oh and we want to use a diffrent port than 80 - "traefik.http.services.exaple.loadbalancer.server.port=8080" depends_on: - db networks: # This service will be connected to the backend and the traefik2_net - traefik2_net - backend networks: traefik2_net: external: name: traefik2_net backend:
With this config the service is discoverable by Traefik and it can talk to its database but no other service will be able to talk to its databases. It will redirect http requests to https and secure the connection with a Let’s Encrypt Certificate.