Skip to content

blog.lammel.ch

Menu
  • Home
  • Link Library
  • Enterprise Architecture
  • Impressum
Menu

Reverse Proxy with Traefik

Posted on April 12, 2025April 29, 2025 by ben

  1. Context
  2. Traefik
    1. docker-compose.yml
    2. data/traefik.yml
    3. data/acme.json
  3. whoami (service 1)
    1. docker-compose.yml
  4. stirling-pdf (service 2)
    1. docker-compose.yml

Context

In order to expose containerized apps and make them available from the public internet with HTTPS/TLS enabled, a reverse proxy is a powerful and essential tool. It acts as a gateway that routes external requests to the appropriate internal services, all while handling encryption, domain mapping, and other network-layer concerns.

graph LR
    subgraph public internet
        LE[Let's Encrypt]
        C1[client 1]
        C2[client n]
    end

    subgraph services
        RP[reverse proxy]
        S1[containerized service 1]
        S2[containerized service n]
    end

    LE <--> RP
    C1 <--> RP
    C2 <--> RP
    RP <--> S1
    RP <--> S2

Let’s Encrypt is a free, automated, and open Certificate Authority (CA). Let’s Encrypt fundamentally changed the internet by making HTTPS encryption more accessible, affordable, and widespread. Before its launch in 2016, SSL/TLS certificates (which enable HTTPS) were costly and complex to manage, making them less accessible for many website owners.

There are several tools available for setting up a reverse proxy, including Caddy, go-doxy, HAProxy, Jauth, Nginx Proxy Manager and Traefik.

In this post, we’ll walk through a setup using Traefik.

Traefik

My preferred way to manage containers is docker-compose, therfore the following descriptions are oriented by that.

docker-compose.yml

version: '3'

services:
  traefik:
    image: traefik:latest
    ports:
      - "80:80" #HTTP port
      - "443:443" #HTTPS port
      - "8080:8080"  #Web UI (enabled by --api.insecure=true)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data/traefik.yml:/etc/traefik/traefik.yml:ro
      - ./data/acme.json:/etc/traefik/acme.json
      - ./logs:/log
    environment:
      - TZ=Europe/Berlin
    networks:
      - nw-proxy-exposed

networks:
  nw-proxy-exposed:
    external: true

data/traefik.yml

################################################################
# Global configuration
################################################################
global:
  checkNewVersion: true
  sendAnonymousUsage: false

################################################################
# EntryPoints configuration
################################################################

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    address: :443
    
################################################################
# Traefik logs configuration
################################################################

log:
  level: DEBUG
  filePath: log/traefik.log

################################################################
# Access logs configuration
################################################################

accessLog:
  filePath: log/access.log

################################################################
# API and dashboard configuration
################################################################

api:
  insecure: false
  dashboard: true

################################################################
# Docker configuration backend
################################################################

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

################################################################
# Let's Encrypt¶
################################################################

certificatesResolvers:
  myresolver:
    acme:
      email: web@lammel.ch
      storage: /etc/traefik/acme.json
      httpChallenge:
        # used during the challenge
        entryPoint: web

data/acme.json

This file needs to be created without any content. It will be used as storage.

whoami (service 1)

The Docker service traefik/whoami is a tiny web application designed for testing and debugging in reverse proxy setups like Traefik.

Tiny Go webserver that prints OS information and HTTP request to output.

docker-compose.yml

Traefik uses Docker labels to configure and discover services. In my setup, five specific labels are required to ensure the service is properly detected and routed by the reverse proxy.

It’s important to note that the service must be on the same Docker network as the reverse proxy to allow proper communication and routing.

version: '3'

services:
  whoami:
    image: traefik/whoami
    hostname: "whoami"
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami-traefik.rule=Host(`service.lammel.ch`) || Host(`whoami.service.lammel.ch`)
      - traefik.http.routers.whoami-traefik.service=whoami-traefik
      - traefik.http.routers.whoami-traefik.tls=true
      - traefik.http.routers.whoami-traefik.tls.certresolver=myresolver
    networks:
      - nw-proxy-exposed

networks:
  nw-proxy-exposed:
    external: true

stirling-pdf (service 2)

Stirling-PDF is a free, open-source, locally hosted web application designed for comprehensive PDF manipulation.

docker-compose.yml

For this particular service, an additional label is required to specify the internal port the application is running on. Since Stirling-PDF listens on port 8080, the label traefik.http.services.pdf-service.loadbalancer.server.port=8080 must be set accordingly.

An interesting point: once the service is routed through the reverse proxy, there’s no need to expose the container port to the host system—Traefik handles the internal communication entirely within the Docker network.

version: '3.3'
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest
    container_name: stirling-pdf
    restart: unless-stopped
    labels:
      - traefik.enable=true
      - traefik.http.routers.pdf-service.rule=Host(`pdf.service.lammel.ch`)
      - traefik.http.routers.pdf-service.service=pdf-service
      - traefik.http.routers.pdf-service.tls=true
      - traefik.http.routers.pdf-service.tls.certresolver=myresolver
      - traefik.http.services.pdf-service.loadbalancer.server.port=8080
    volumes:
      - ./StirlingPDF/trainingData:/usr/share/tessdata
      - ./StirlingPDF/extraConfigs:/configs
      - ./StirlingPDF/customFiles:/customFiles/
      - ./StirlingPDF/logs:/logs/
      - ./StirlingPDF/pipeline:/pipeline/
    environment:
      - DOCKER_ENABLE_SECURITY=false
      - LANGS=en_GB
    networks:
      - nw-proxy-nonexposed

networks:
  nw-proxy-nonexposed:
    external: true

Recent Posts

  • Athens, Greece — A Quick Travel Recap
  • QuickRef: The Developer’s Cheat Sheet Companion
  • Killed by Google: A Digital Graveyard
  • The Magic of Rubber Duck Debugging
  • Reverse Proxy with Traefik

Categories

  • Home Assistant (1)
  • Interesting (3)
  • Raspberry PI (2)
  • Travel (1)
  • Uncategorized (1)

Tags

  • container (1)
  • english (6)
  • guide (2)
  • knowledge (1)
  • link (2)
  • MQTT (1)
  • tech (2)
  • term (1)
  • travel (1)
  • zigbee (1)
© 2025 blog.lammel.ch | Powered by Minimalist Blog WordPress Theme