Skip to content

Latest commit

 

History

History
186 lines (148 loc) · 5.09 KB

File metadata and controls

186 lines (148 loc) · 5.09 KB

Traefik

This is one of the best reverse-proxy solutions for self-hosting. Very easy to run & maintain (once you pass the setup).

Traefik can detect docker services and use docker labels to automatically create routes. However, I prefer to keep my docker-compose files clean and explicitly set routers & services myself, so this solution does exactly that.

Traefik can also be set-up to automatically provide Let's Encrypt certs for your services. However, there are some services that need cert files (AdGuard Home, Mailcow), and because I want to have a single wildcard certificate for my whole domain (and all subdomains) I prefer to generate it manually (i.e. scripts in cron) and just reference it whenever it's required - so this setup reflects that.

General overview

Traefik has 2 types of config:

  • static - requires restart of the container
  • dynamic - refreshes live.

Dynamic config can be provided as a folder, where all toml/yml files are parsed and configuration from them is applied to the running server.

You can create multiple files and split the dynamic config to your preference. I prefer to keep 1 main file (for tls/cert settings and global middlewares), and then add 1 config file per service (with route & service definition).

It's also good to keep a note with a table of service-port mapping (to quickly see which ports are used by which service).


docker-compose.yml

version: '3'
services:
  traefik:
    image: traefik:v2.3
    container_name: traefik
    restart: unless-stopped
    security_opt: ["no-new-privileges"]
    ports:
      - "80:80"
      - "443:443"
      - "3080:8080"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /path/to/certs:/certs:ro
      - ./config:/config:ro
      - ./traefik.yml:/traefik.yml:ro

Static config

traefik.yml

global:
  checkNewVersion: true
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

serversTransport:
  insecureSkipVerify: true

providers:
  file:
    directory: /config
    watch: true

Dynamic config

config/_main.toml

[[tls.certificates]]
certFile = "/certs-com/fullchain.cer"
keyFile = "/certs-com/example.com.key"
stores = [ "default" ]

[[tls.certificates]]
certFile = "/certs-org/fullchain.cer"
keyFile = "/certs-org/example.org.key"
stores = [ "default" ]

[tls.stores.default.defaultCertificate]
certFile = "/certs-com/fullchain.cer"
keyFile = "/certs-com/example.com.key"

[http.middlewares.redirect-to-https.redirectScheme]
scheme = "https"
permanent = true

[http.middlewares.security-headers.headers]
referrerPolicy = "same-origin"
contentTypeNosniff = true
frameDeny = false
forceSTSHeader = true
stsIncludeSubdomains = true
stsPreload = true
stsSeconds = 15_552_000

[[http.services.noop.loadBalancer.servers]]
url = "http://192.168.0.1:666"  # this is a fake url

[http.routers.http-catchall]
rule = "HostRegexp(`{host:(www\\.)?.+}`)"
entryPoints = [ "http" ]
middlewares = [ "redirect-to-https" ]
service = "noop"

config/service-authelia.toml

[http.middlewares.authelia.forwardAuth]
address = "http://<SERVER IP>:9091/api/verify?rd=https://login.example.com/"
trustForwardHeader = true

[[http.services.authelia.loadBalancer.servers]]
url = "http://<SERVER IP>:9091"

[http.routers.authelia]
rule ="Host(`login.example.com`)"
service = "authelia"
tls = { }
middlewares = [ "security-headers" ]

config/service-nextcloud.toml

[http.middlewares.nextcloud-redirectregex.redirectRegex]
permanent = true
regex = "https://(.*)/.well-known/(card|cal)dav"
replacement = "https://${1}/remote.php/dav/"

[[http.services.nextcloud.loadBalancer.servers]]
url = "http://<SERVER IP:3000"

[http.routers.nextcloud]
rule = "Host(`cloud.example.com`)"
service = "nextcloud"
tls = { }
middlewares = [ "security-headers", "nextcloud-redirectregex" ]

config/service-sonarr.toml

[[http.services.sonarr.loadBalancer.servers]]
url = "http://<SERVER IP>:8989/"

[http.routers.sonarr]
rule = "Host(`sonarr.example.com`)"
service = "sonarr"
tls = { }
middlewares = [ "security-headers", "authelia" ]

config/service-traefik.toml

[[http.services.traefik.loadBalancer.servers]]
url = "http://<SERVER IP>:3080"

[http.routers.traefik]
rule = "Host(`traefik.example.com`) && PathPrefix(`/dashboard`)"
service = "traefik"
tls = { }
middlewares = [ "security-headers", "authelia" ]

[http.routers.traefik_api]
rule = "Host(`traefik.example.com`)"
service = "api@internal"
tls = { }
middlewares = [ "security-headers", "authelia" ]

Useful links