Traefik
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Traefik es un proxy inverso HTTP moderno y balanceador de cargas que facilita el despliegue de microservicios. Se integra con componentes de infraestructura existentes (como Docker) y generalmente se configura dinámicamente a medida que se añaden o eliminan servicios.
Este documento proporciona una configuración completa de Traefik v2.x con Jellyfin. Utiliza varios archivos: docker-compose.yml, traefik.toml (configuración estática de Traefik), traefik-provider.toml (proveedor basado en archivos para Traefik), traefik.log (archivo de registro opcional), .env (entorno necesario para proveedores ACME/LetsEncrypt) y acme.json (datos de estado para certificados ACME/LetsEncrypt). Todos los archivos deben crearse en el mismo directorio. Alternativamente, modifique las rutas en la sección de volúmenes del servicio traefik en docker-compose.yml. Opcionalmente puede incluir parte de traefik.toml en etiquetas del servicio traefik en docker-compose.yml, aunque este método es más claro y fácil de comentar.
Asegúrese de habilitar protección básica de firewall o autenticación para Traefik, o desactive su panel de control. De lo contrario, su panel podría ser accesible desde Internet. Preste atención a la accesibilidad IPv6, ya que incluso sistemas en redes domésticas internas pueden ser accesibles directamente mediante IPv6. Consulte api-insegura para más detalles sobre cómo proteger el panel.
Traefik ofrece múltiples opciones para configurar LetsEncrypt mediante diferentes desafíos. Si su servidor es accesible desde Internet por los puertos 80 o 443, puede usar desafíos HTTP-01 o TLS-ALPN-01. En ese caso, certificatesresolvers.leresolver.acme.httpchallenge.entrypoint debe ser accesible por Let's Encrypt a través de los puertos 80/443. También puede usar desafíos DNS-01 mediante los proveedores disponibles. La configuración excede el alcance de esta guía. Esta guía permite usar HTTP-01 y DNS-01 comentando/descomentando bloques. Probablemente usará HTTP-01 a menos que tenga acceso completo a su configuración DNS. La configuración inferior usa RFC2136 (definido en certificatesresolvers.leresolver.acme.dnsChallenge de traefik.toml) y las variables para ese proveedor se muestran en .env como guía de formato. Consulte la documentación del proveedor y los comentarios para configurar su proveedor ACME preferido, o cambie la configuración a HTTP-01 en los comentarios de traefik.toml.
La configuración inferior crea una instalación de Traefik v2.x accesible en puertos de entrada 80 (etiquetado 'http'), 443 (etiquetado 'https') y 9999 (etiquetado 'secure'). Independientemente de Jellyfin, redirige todo tráfico de http (puerto 80) a https (puerto 443) para cifrar los datos. Para Jellyfin, hace el servicio accesible sin ruta en el punto de entrada seguro. Esta configuración sirve como punto de partida y probablemente necesite adaptaciones. Si desea acceder a Jellyfin sin puerto (usando el puerto https predeterminado), cambie 'secure' por 'https' en docker-compose.yml donde se indique y elimine ':9999' del parámetro SSLHost. Si desea acceder mediante ruta, añada PathPrefix (ej. '/jellyfin') y vea la nota al final sobre configuración de Jellyfin.
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'
Los archivos TOML no admiten variables de entorno, así que todos los valores deben codificarse directamente.
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]
Debido a una particularidad en Traefik, no se puede enrutar dinámicamente contenedores cuando se usa network_mode=host. Hemos creado una ruta estática al host de Docker (192.168.1.xx:8096) en traefik-provider.toml. El uso de red en modo host (como en este documento) o macvlan es necesario para utilizar DLNA o un HdHomeRun, ya que requiere acceso a la red de multidifusión. traefik-provider.toml define el servicio jellyfin-svc@file al que apuntamos desde el enrutador en el archivo docker-compose.yml. No se puede establecer una URL en docker-compose.yml, por eso configuramos este servicio externamente. Asegúrate de actualizar la dirección IP a la dirección IP del host en tu red local (en este caso, 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=...
Finalmente, crea un archivo acme.json vacío y un archivo traefik.log para manejar el certificado y el archivo de registro para cualquier registro.
touch acme.json traefik.log
chmod 600 acme.json traefik.log
Estas configuraciones utilizan DOMAIN_NAME (ej: example.com) y HOST_NAME (ej: servername) en todo el sistema. Debes reemplazarlos con el nombre de tu servidor. HOST_NAME.DOMAIN_NAME se refiere a la máquina misma (ej: servername.example.com). No olvides actualizar YOU@DOMAIN_NAME en traefik.toml con tu dirección de correo electrónico. Let's Encrypt no requiere un correo válido, pero los correos inválidos pueden marcarse como falsos.
Inicia los servicios de Traefik y Jellyfin.
docker compose up -d
Si configuraste un PathPrefix (ej: /jellyfin), necesitas configurar Jellyfin para que lo espere. Tras iniciar el servicio, accede a Jellyfin directamente (vía la IP del host en el puerto 8096) y cambia la 'URL Base' en Dashboard / Advanced / Networking para que coincida con la ruta '/jellyfin' (si la usaste en esta configuración). Luego, puedes crear una regla de firewall para evitar el acceso directo a Jellyfin en el puerto 8096, o asegurarte que el puerto no sea accesible desde Internet.
¡Felicidades! Tu stack con Traefik 2.x y Jellyfin está (ojalá) funcionando. Revisa el archivo de registro o ejecuta sin el parámetro '-d' para verificar errores, especialmente en la configuración de LetsEncrypt.