Skip to main content

Traefik

Traefik is a free, open source proxy manager. It is configured via labels.

The project is very well integrated with the use of Docker containers.

Preparation

Docker network

First, a Docker network should be created. This then eliminates the need to release ports for each individual service. Sufficient then are ports 80 and 443 for the proxy manager, as well as others in certain cases if necessary.

caution

On some devices (especially on preconfigured NAS devices) it is not possible to publish port 80 and 443 because these ports are already used by another service. At this point you can first create a Macvlan network on which ports 80 and 443 can be released.

sudo docker network create proxy-network

Create directory

mkdir traefik
cd traefik
touch traefik.log
mkdir shared
mkdir acme
touch acme/acme.json
chmod 600 acme/acme.json
mkdir rules
touch rules/middlewares.toml
touch .env docker-compose.yml
info

If you are not in the home directory, you may have to add sudo to the commands.

Environment variables

Some environment variables are required to configure the Proxy Manager. A DNS challenge requires a domain from a supported provider.

An example is Netcup, with .de domains, which cost 5 EUR per year. (Affiliate-Link)

In this case you need the domain, your customer number, the API key and the API password.

These are entered into the .env together with an email address.

.../traefik/.env
DOMAINNAME=domain.de
NETCUP_CUSTOMER_NUMBER=50000
NETCUP_API_KEY=LDBfH4MNyDlgBgww0lGry0OkouhkMqUI5E
NETCUP_API_PASSWORD=uEzCAzISBUBwGqW9oSEzRJuL3D26Gm1yQFMlnqSB1Lhjb5Z98
EMAIL_ADDRESS=mail@hallo.de

Installation

Authentication

A username / password combination is required for authentication.

sudo apt install apache2-utils
htpasswd -nb username password > /shared/.htpasswd
info

Username and password should be adjusted, of course.

Afterwards the middleware has to be adjusted:

.../traefik/rules/middlewares.toml
[http.middlewares]
[http.middlewares.middlewares-basic-auth]
[http.middlewares.middlewares-basic-auth.basicAuth]
realm = "Traefik Basic Auth"
usersFile = "/shared/.htpasswd"

Docker Compose

The installation is done via Docker Compose.

.../traefik/docker-compose.yml
version: "3.7"

### NETWORKS ###
networks:
proxy-network:
external:
name: proxy-network

### SERVICES ###
services:
traefik:
container_name: traefik
image: traefik:latest
restart: unless-stopped
command:
- --global.checkNewVersion=true
- --global.sendAnonymousUsage=false
- --entryPoints.http.address=:80
- --entryPoints.https.address=:443
- --entryPoints.traefik.address=:8080
- --api=true
- --api.dashboard=true
- --log=true
- --log.level=WARN
- --accessLog=true
- --accessLog.filepath=/traefik.log
- --accessLog.bufferingSize=100
- --accessLog.filters.statusCodes=400-499
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.exposedByDefault=false
- --providers.docker.network=web
- --providers.docker.swarmMode=false
- --providers.file.directory=/rules
- --providers.file.watch=true
- --certificatesResolvers.dns-netcup.acme.dnsChallenge.provider=netcup
# - --certificatesResolvers.dns-netcup.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
- --certificatesResolvers.dns-netcup.acme.email=$EMAIL_ADDRESS
- --certificatesResolvers.dns-netcup.acme.storage=/acme.json
- --certificatesResolvers.dns-netcup.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53
- --certificatesResolvers.dns-netcup.acme.dnschallenge.delayBeforeCheck=300
networks:
- proxy-network
security_opt:
- no-new-privileges:true
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
- ./rules:/rules
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme/acme.json:/acme.json
- ./traefik.log:/traefik.log
- ./shared:/shared
environment:
- NETCUP_CUSTOMER_NUMBER=$NETCUP_CUSTOMER_NUMBER
- NETCUP_API_KEY=$NETCUP_API_KEY
- NETCUP_API_PASSWORD=$NETCUP_API_PASSWORD
labels:
- "traefik.enable=true"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.traefik-rtr.entrypoints=https"
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
- "traefik.http.routers.traefik-rtr.tls=true"
- "traefik.http.routers.traefik-rtr.tls.certresolver=dns-netcup"
- "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
- "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
- "traefik.http.routers.traefik-rtr.service=api@internal"
- "traefik.http.routers.traefik-rtr.middlewares=middlewares-basic-auth@file"
info

If you use a different provider, you have to adjust the corresponding lines.

info

If you are on the network behind a router, you need to forward port 80 and 443 to the server.

sudo docker compose up -d
info

For Docker Compose version 1, the command is sudo docker-compose up -d.

It may take a few minutes for traefik to load. Especially the DNS challenge can take a lot of time. Afterwards, the dashboard should be accessible under traefik.domain.de.

tip

If this did not work, you can stop the container and start it again with log.level=DEBUG. The log should then show why it does not work.

Andere Anwendung

Another application can be connected to traefik via labels.

mkdir homepage
cd homepage
mkdir html
touch html/index.html
touch docker-compose.yml
.../homepage/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Homepage</title>
</head>
<body>
<h1>Homepage</h1>
<p>This is a homepage.</p>
</body>
</html>
.../homepage/docker-compose.yml
version: "3.7"

networks:
proxy-network:
external:
name: proxy-network

### SERVICE ###
services:
testseite:
container_name: testseite
image: nginx:latest
restart: unless-stopped
networks:
- proxy-network
security_opt:
- no-new-privileges:true
volumes:
- /html:/usr/share/nginx/html:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.testseite-rtr.entrypoints=https"
- "traefik.http.routers.testseite-rtr.rule=Host(`homepage.$DOMAINNAME`)"
- "traefik.http.routers.testseite-rtr.tls=true"
- "traefik.http.routers.testseite-rtr.service=testseite-svc"
- "traefik.http.services.testseite-svc.loadbalancer.server.port=80"
sudo docker compose up -d

The page should now be accessible under homepage.domain.de.

Update

Thanks to Docker and Docker Compose, updating traefik is easy.

sudo docker compose pull
sudo docker compose down
sudo docker compose up -d