Traefik
Deze pagina is vertaald door PageTurner AI (beta). Niet officieel goedgekeurd door het project. Een fout gevonden? Probleem melden →
Traefik is een moderne HTTP-reverseproxy en loadbalancer die het implementeren van microservices eenvoudig maakt. Traefik integreert met je bestaande infrastructuurcomponenten (zoals Docker) en configureert zichzelf dynamisch wanneer services worden toegevoegd of verwijderd.
Dit document biedt een complete configuratie voor Traefik v2.x en Jellyfin. Er worden meerdere bestanden gebruikt: een docker-compose.yml bestand, traefik.toml (je statische Traefik-configuratie), traefik-provider.toml (een bestandsgebaseerde provider voor Traefik), traefik.log (optioneel logbestand), .env (omgevingsvariabelen voor ACME/LetsEncrypt providers) en acme.json (certificaatstatus voor ACME/LetsEncrypt). Alle bestanden moeten in dezelfde map worden aangemaakt. Je kunt alternatief de paden in het volume-gedeelte van de traefik service in docker-compose.yml aanpassen. Je kunt delen van traefik.toml eventueel in labels van de Traefik-service in docker-compose.yml stoppen, maar deze methode is overzichtelijker en eenvoudiger te documenteren.
Zorg ervoor dat je basisbeveiliging via firewall of authenticatie inschakelt voor Traefik of schakel het dashboard uit. Als je dit niet doet, kan je dashboard vanaf het internet toegankelijk zijn. Let specifiek op IPv6-toegankelijkheid, want zelfs systemen in een intern thuisnetwerk kunnen direct bereikbaar zijn via IPv6. Zie api-insecure voor meer details over het beveiligen van het dashboard.
Traefik biedt diverse opties voor LetsEncrypt-configuratie met verschillende challenge-methoden. Als je server via poort 80 of 443 bereikbaar is vanaf internet, kun je HTTP-01 of TLS-ALPN-01 challenges gebruiken. In dat geval moet certificatesresolvers.leresolver.acme.httpchallenge.entrypoint bereikbaar zijn voor Let's Encrypt via poort 80/443. Je kunt ook een DNS-01 challenge gebruiken via een van de beschikbare providers. Configuratie valt buiten dit document. Deze handleiding ondersteunt zowel HTTP-01 als DNS-01 door blokken te commentariëren of de-commentariëren. HTTP-01 wordt waarschijnlijk gebruikt tenzij je volledige DNS-toegang hebt. Onderstaande configuratie gebruikt RFC2136 (ingesteld via certificatesresolvers.leresolver.acme.dnsChallenge in traefik.toml) en bijbehorende variabelen in .env als opmaakvoorbeeld. Raadpleeg providerdocumentatie voor je ACME-provider of wijzig de configuratie naar HTTP-01 via de comments in traefik.toml.
Onderstaande configuratie maakt een Traefik v2.x-installatie met toegang via entryPoints op poort 80 ('http'), 443 ('https') en 9999 ('secure'). Onafhankelijk van Jellyfin redirects het alle verkeer van http (poort 80) naar https (poort 443) voor versleutelde data. Voor Jellyfin maakt het de service beschikbaar zonder pad op het 'secure' entryPoint. Deze configuratie dient als startpunt en vereist waarschijnlijk aanpassingen. Wil je Jellyfin bereikbaar maken zonder poortnummer (via standaard https-poort 443), wijzig dan 'secure' in 'https' in docker-compose.yml en verwijder ':9999' uit de SSLHost-parameter. Voor pad-gebaseerde toegang (bv. '/jellyfin'), voeg PathPrefix toe en zie de opmerking aan het eind van dit document over Jellyfin-configuratie.
docker-compose.yml
services:
traefik:
container_name: traefik
image: traefik:chevrotin # the chevrotin tag refers to v2.2.x
restart: unless-stopped
volumes:
# So that Traefik can listen to the Docker events (read-only)
- /var/run/docker.sock:/var/run/docker.sock:ro
# TOML Configuration with global options
- /srv/traefik.toml:/traefik.toml
# Configuration for the file provider (needed for host networking and default TLS Options)
- /srv/traefik-provider.toml:/traefik-provider.toml
# LetsEncrypt ACME Configuration
- /srv/acme.json:/acme.json
# Log File (optional)
- /srv/traefik.log:/traefik.log
ports:
# The Web UI (enabled by --api.insecure=true in traefik.toml)
- 8080:8080
# The Available Ports (forward your router's incoming ports to the ports on the host)
- 80:80
- 443:443
- 9999:9999
env_file: .env
jellyfin:
image: jellyfin/jellyfin
container_name: 'jellyfin'
user: 1000:1000
group_add: # by id as these may not exist within the container. Needed to provide permissions to the VAAPI Devices
- '107' #render
- '44' #video
# Network mode of 'host' exposes the ports on the host. This is needed for DLNA access.
network_mode: 'host'
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
# Update this configuration as desired
- /path/to/media:/media
restart: always
devices:
# VAAPI Devices
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card0:/dev/dri/card0
labels:
- 'traefik.enable=true'
## HTTP Router
#### Entry point where Jellyfin is accessible via
#### Change secure to https in the line below to have accessible without needing to specify a port and change the SSLHost option below
- 'traefik.http.routers.jellyfin.entryPoints=secure'
#### Host or Path where Jellyfin is accessible
#### Remove (or change) this rule if you'd rather have Jellyfin accessible at a PathPrefix URI
- 'traefik.http.routers.jellyfin.rule=Host(`HOST_NAME.DOMAIN_NAME`)' # OPTIONAL: && PathPrefix(`/jellyfin`)
#### Enable TLS with the ACME/LetsEncrypt resolver for HOSTNAME.DOMAIN_NAME
- 'traefik.http.routers.jellyfin.tls=true'
- 'traefik.http.routers.jellyfin.tls.certResolver=leresolver'
- 'traefik.http.routers.jellyfin.tls.domains=HOSTNAME.DOMAIN_NAME'
## Middleware
- 'traefik.http.routers.jellyfin.middlewares=jellyfin-mw'
#### The customResponseHeaders option lists the Header names and values to apply to the response.
- 'traefik.http.middlewares.jellyfin-mw.headers.customResponseHeaders.X-Robots-Tag=noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex'
#### The sslRedirect is set to true, then only allow https requests.
- 'traefik.http.middlewares.jellyfin-mw.headers.SSLRedirect=true'
#### The sslHost option is the host name that is used to redirect http requests to https.
#### This is the exact URL that will be redirected to, so you can remove the :9999 port if using default SSL port
- 'traefik.http.middlewares.jellyfin-mw.headers.SSLHost=HOST_NAME.DOMAIN_NAME:9999'
#### Set sslForceHost to true and set SSLHost to forced requests to use SSLHost even the ones that are already using SSL.
#### Note that this uses SSLHost verbatim, so add the port to SSLHost if you are using an alternate port.
- 'traefik.http.middlewares.jellyfin-mw.headers.SSLForceHost=true'
#### The stsSeconds is the max-age of the Strict-Transport-Security header. If set to 0, would NOT include the header.
- 'traefik.http.middlewares.jellyfin-mw.headers.STSSeconds=315360000'
#### The stsIncludeSubdomains is set to true, the includeSubDomains directive will be
#### appended to the Strict-Transport-Security header.
- 'traefik.http.middlewares.jellyfin-mw.headers.STSIncludeSubdomains=true'
#### Set stsPreload to true to have the preload flag appended to the Strict-Transport-Security header.
- 'traefik.http.middlewares.jellyfin-mw.headers.STSPreload=true'
#### Set forceSTSHeader to true, to add the STS header even when the connection is HTTP.
- 'traefik.http.middlewares.jellyfin-mw.headers.forceSTSHeader=true'
#### Set frameDeny to true to add the X-Frame-Options header with the value of DENY.
- 'traefik.http.middlewares.jellyfin-mw.headers.frameDeny=true'
#### Set contentTypeNosniff to true to add the X-Content-Type-Options header with the value nosniff.
- 'traefik.http.middlewares.jellyfin-mw.headers.contentTypeNosniff=true'
#### Set browserXssFilter to true to add the X-XSS-Protection header with the value 1; mode=block.
- 'traefik.http.middlewares.jellyfin-mw.headers.customresponseheaders.X-XSS-PROTECTION=1'
#### The customFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This
#### overrides the FrameDeny option.
- "traefik.http.middlewares.jellyfin-mw.headers.customFrameOptionsValue='allow-from https://DOMAIN_NAME'"
## HTTP Service
# We define the port here as a port is required, but note that the service is pointing to the service defined in @file
- 'traefik.http.routers.jellyfin.service=jellyfin-svc@file'
- 'traefik.http.services.jellyfin-svc.loadBalancer.server.port=8096'
- 'traefik.http.services.jellyfin-svc.loadBalancer.passHostHeader=true'
## Redirection of HTTP on port 9999 to HTTPS on port 9999 (consistent protocol)
- 'traefik.http.routers.jellyfin-insecure.entryPoints=secure'
- 'traefik.http.routers.jellyfin-insecure.rule=Host(`HOST_NAME.DOMAIN_NAME`)' # OPTIONAL: && PathPrefix(`/jellyfin`)
- 'traefik.http.routers.jellyfin-insecure.middlewares=jellyfin-insecure-mw'
- 'traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.scheme=https'
- 'traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.port=9999' # remove if you are using a default port
- 'traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.permanent=false'
- 'traefik.http.routers.jellyfin-insecure.service=noop@internal'
TOML-bestanden ondersteunen geen omgevingsvariabelen, dus alle waarden moeten hardgecodeerd worden.
traefik.toml
[log]
# By default, the level is set to ERROR. Alternative logging levels
# are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO.
level = "DEBUG"
filePath = "/traefik.log"
[docker]
# Defines a default docker network to use for connections to all
# containers. This option can be overridden on a container basis
# with the traefik.docker.network label.
network = "traefik"
# Expose containers by default through Traefik. If set to false,
# containers that don't have a traefik.enable=true label will be
# ignored from the resulting routing configuration.
exposedbydefault = false
[api]
# Enable the API in insecure mode, which means that the API will be
# available directly on the entryPoint named traefik. If the entryPoint
# named traefik is not configured, it will be automatically created on
# port 8080.
insecure = true
[providers]
# Connection to docker host system (docker.sock)
# Attach labels to your containers and let Traefik do the rest!
# Traefik works with both Docker (standalone) Engine and Docker Swarm Mode.
# See: https://docs.traefik.io/providers/docker/
[providers.docker]
# Traefik requires access to the docker socket to get its dynamic
# configuration.
endpoint = "unix:///var/run/docker.sock"
[providers.file]
filename = "/traefik-provider.toml"
# EntryPoints are the network entry points into Traefik. They define
# the port which will receive the packets, and whether to listen for
# TCP or UDP.
# See: https://docs.traefik.io/routing/entrypoints/
# NOTE: If a TLS section (i.e. any of its fields) is defined in your docker-compose.yml file,
# then the default configuration does not apply at all.
[entryPoints]
# Standard HTTP redirects to HTTPS
[entryPoints.http]
address = ":80"
[entryPoints.http.http]
[entryPoints.http.http.redirections]
[entryPoints.http.http.redirections.entrypoint]
to = "https"
scheme = "https"
# Standard HTTPS
[entryPoints.https]
address = ":443"
[entryPoints.https.http.tls]
certResolver = "leresolver"
[[entryPoints.https.http.tls.domains]]
main = "HOST_NAME.DOMAIN_NAME"
# SANS are any other hostnames which Traefik should obtain a certificate for.
# If you are using DNS for LetsEncrypt, you can set a wildcard.
# Include all possible hostnames of this server.
#sans = ["*.DOMAIN_NAME"]
# Alternate HTTPS Port (for services - accepts both HTTP and HTTP by not defining a TLS configuration here)
[entryPoints.secure]
address = ":9999"
# Enable ACME (Let's Encrypt): automatic SSL.
[certificatesresolvers.leresolver.acme]
email = "YOU@DOMAIN_NAME"
storage = "acme.json"
# Use HTTP-01 ACME challenge
#[certificateresolvers.leresolver.acme.httpChallenge]
# entryPoint = "http"
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Mandatory for wildcard certificate generation.
[certificatesresolvers.leresolver.acme.dnsChallenge]
# Update this to your provider of choice and then ensure necessary variables are in the .env file to support it.
provider = "rfc2136"
delayBeforeCheck = 0
# A DNS server used to check whether the DNS is set up correctly before
# making the ACME request. Ideally a DNS server that isn't going to cache an old entry.
resolvers = ["8.8.8.8:53"]
[retry]
Door een eigenaardigheid in Traefik kun je niet dynamisch doorverwijzen naar containers wanneer network_mode=host is ingesteld. Daarom hebben we een statische route naar de Docker-host (192.168.1.xx:8096) gemaakt in traefik-provider.toml. Het gebruik van host-netwerken (zoals in dit document) of macvlan is vereist voor DLNA of een HdHomeRun, zodat deze het multicast-netwerk kunnen gebruiken. traefik-provider.toml definieert de jellyfin-svc@file-service waarnaar we de router doorverwijzen in het docker-compose.yml-bestand. Je kunt geen URL instellen in docker-compose.yml, daarom hebben we deze service extern ingesteld. Vergeet niet het IP-adres hieronder bij te werken naar het IP-adres van de host op het lokale netwerk (in dit geval 192.168.1.xx).
traefik-provider.toml
[http]
[http.services]
[http.services.jellyfin-svc]
[[http.services.jellyfin-svc.loadBalancer.servers]]
url = "http://192.168.1.xx:8096"
# Set secure options by disabling insecure older TLS/SSL versions
# and insecure ciphers. SNIStrict disabled leaves TLS1.0 open.
# If you have problems with older clients, you can may need to relax
# these minimums. This configuration will give you an A+ SSL security
# score supporting TLS1.2 and TLS1.3
[tls.options]
[tls.options.default]
sniStrict = true
minVersion = "VersionTLS12"
curvePreferences = [
"secp521r1",
"secp384r1"
]
cipherSuites = [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
]
[tls.options.mintls13]
minVersion = "VersionTLS13"
.env
RFC2136_NAMESERVER=...
RFC2136_TSIG_ALGORITHM=hmac-sha512.
RFC2136_TSIG_KEY=...
RFC2136_TSIG_SECRET=...
Maak ten slotte een leeg acme.json-bestand en traefik.log-bestand aan om het certificaat en logbestand voor eventuele logging af te handelen.
touch acme.json traefik.log
chmod 600 acme.json traefik.log
Deze configuraties gebruiken DOMAIN_NAME (bijv.: example.com) en HOST_NAME (bijv.: servername) door het hele bestand heen. Vervang deze door de naam van je server. HOST_NAME.DOMAIN_NAME verwijst naar de machine zelf (bijv.: servername.example.com). Vergeet niet om YOU@DOMAIN_NAME in traefik.toml bij te werken met je e-mailadres. Let's Encrypt vereist geen geldig e-mailadres, maar ongeldige e-mails kunnen als nep worden gemarkeerd.
Start de Traefik- en Jellyfin-services.
docker compose up -d
Als je een PathPrefix hebt ingesteld (bijv. /jellyfin), moet je Jellyfin configureren om dit te verwachten. Start na het opstarten van de service Jellyfin rechtstreeks (via het IP-adres van de host op poort 8096) en wijzig de 'Basis-URL' in Dashboard / Geavanceerd / Netwerken zodat deze overeenkomt met het '/jellyfin'-pad (als je er een hebt gebruikt in deze configuratie). Daarna kun je een firewallregel maken om rechtstreekse toegang tot Jellyfin op poort 8096 van de host te voorkomen, of simpelweg zorgen dat de poort niet toegankelijk is via internet.
Gefeliciteerd, je stack met Traefik 2.x en Jellyfin draait (hopelijk)! Controleer het logbestand of voer zonder de '-d'-parameter uit om eventuele fouten te bekijken, met name met betrekking tot de LetsEncrypt-configuratie.