Traefik is een reverse proxy. Dit wil zeggen dat je heel gemakkelijk verschillende services kunt bereiken vanaf het internet zonder elke keer een port open te zetten.
De enigeste poort die je moet openzetten is 443. En verwijzen naar het toest (IP) waar Traefik op draait.
In dit voorbeeld gebruiken we een firewall van het met Unifi. Dit kan je ook perfect in de router(modem) van uw provider doen.
Bij je DNS provider verwijs je een A record door naar je Publiek IP (dit kan ook automatisch gebeuren door DDNS).
Voor alle services gebruik je een CNAME record die verwijst naar @ (@ = jouw domein).
Als je dat eenmaal gedaan hebt kan je beginnen aan de configuratie van Traefik.
Info
Onze Traefik gebruikt een dynamische file. Dat wilt zeggen dat je als je de configuratie aanpast dat je niet elke keer de docker opnieuw moet genereren.
services:# Traefik 3 - Reverse Proxytraefik:container_name:traefikimage:traefik:latestsecurity_opt:-no-new-privileges:truerestart:unless-stopped# depends_on:# - socket-proxynetworks:-socket_proxy#- swarm-traefikcommand:# CLI arguments---global.checkNewVersion=true---global.sendAnonymousUsage=false---entrypoints.web-external.address=:80---entrypoints.web-internal.address=:81---entrypoints.websecure-external.address=:444---entrypoints.websecure-internal.address=:443# - --entrypoints.traefik.address=:8080---entrypoints.web-external.http.redirections.entrypoint.to=websecure-external---entrypoints.web-external.http.redirections.entrypoint.scheme=https---entrypoints.web-external.http.redirections.entrypoint.permanent=true---entrypoints.web-internal.http.redirections.entrypoint.to=websecure-internal---entrypoints.web-internal.http.redirections.entrypoint.scheme=https---entrypoints.web-internal.http.redirections.entrypoint.permanent=true---api=true---api.dashboard=true# - --api.insecure=true# - --serversTransport.insecureSkipVerify=true# Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/---entrypoints.websecure-external.forwardedHeaders.trustedIPs=$CLOUDFLARE_IPS,$LOCAL_IPS---entrypoints.websecure-internal.forwardedHeaders.trustedIPs=$CLOUDFLARE_IPS,$LOCAL_IPS---log=true---log.filePath=/logs/traefik.log---log.level=INFO# (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC---accessLog=true---accessLog.filePath=/logs/access.log---accessLog.bufferingSize=100# Configuring a buffer of 100 lines---accessLog.filters.statusCodes=204-299,400-499,500-599---providers.docker=true# --providers.docker.endpoint=unix:///var/run/docker.sock # Disable for Socket Proxy. Enable otherwise.---providers.docker.endpoint=tcp://socket-proxy:2375# Enable for Socket Proxy. Disable otherwise.---providers.docker.exposedByDefault=false---providers.docker.network=t3_proxy# - --providers.docker.swarmMode=true # Traefik v2 Swarm# - --providers.swarm.endpoint=tcp://127.0.0.1:2377 # Traefik v3 Swarm---entrypoints.websecure-external.http.tls=true---entrypoints.websecure-external.http.tls.options=tls-opts@file---entrypoints.websecure-internal.http.tls=true---entrypoints.websecure-internal.http.tls.options=tls-opts@file# Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual services---entrypoints.websecure-external.http.tls.certresolver=dns-cloudflare---entrypoints.websecure-external.http.tls.domains[0].main=$DOMAINNAME_1---entrypoints.websecure-external.http.tls.domains[0].sans=*.$DOMAINNAME_1---entrypoints.websecure-internal.http.tls.certresolver=dns-cloudflare---entrypoints.websecure-internal.http.tls.domains[1].main=$DOMAINNAME_2---entrypoints.websecure-internal.http.tls.domains[1].sans=*.$DOMAINNAME_2# - DOMAINS-PLACEHOLDER-DO-NOT-DELETE---providers.file.directory=/rules# Load dynamic configuration from one or more .toml or .yml files in a directory---providers.file.watch=true# Only works on top level files in the rules folder# - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing---certificatesResolvers.dns-cloudflare.acme.storage=/acme.json---certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare---certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53---certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=120# To delay DNS check and reduce LE hitrate#- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.disablePropagationCheck=true# - METRICS-PLACEHOLDER-DO-NOT-DELETEports:-"80:80"-"81:81"-"443:443"-"444:444"# - "8080:8080"volumes:-$APPDATADIR/traefik/rules:/rules# - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security-$APPDATADIR/traefik/acme/acme.json:/acme.json-$LOGDIR/traefik:/logsenvironment:-TZ=$TZ-CF_DNS_API_TOKEN_FILE=/run/secrets/cf_dns_api_token-HTPASSWD_FILE=/run/secrets/basic_auth_credentials# HTTP Basic Auth Credentials-DOMAINNAME_1# Passing the domain name to traefik container to be able to use the variable in rules.-DOMAINNAME_2# - TRAEFIK_AUTH_BYPASS_KEYsecrets:-cf_dns_api_token-basic_auth_credentialslabels:-"traefik.enable=true"# HTTP Routers-"traefik.http.routers.traefik-rtr.entrypoints=websecure-internal,websecure-external"-"traefik.http.routers.traefik-rtr.rule=Host(`traefik-dashboard.$DOMAINNAME_1`)"# Services - API-"traefik.http.routers.traefik-rtr.service=api@internal"# Middlewares-"traefik.http.routers.traefik-rtr.middlewares=chain-basic-auth@file"# For Basic HTTP Authentication# Traefik Error Log (traefik.log) for Dozzletraefik-error-log:container_name:traefik-error-logimage:alpinevolumes:-$LOGDIR/traefik/traefik.log:/var/log/stream.logcommand:-tail--f-/var/log/stream.lognetwork_mode:nonerestart:unless-stopped# Traefik Access Log (access.log) for Dozzletraefik-access-log:container_name:traefik-access-logimage:alpinevolumes:-$LOGDIR/traefik/access.log:/var/log/stream.logcommand:-tail--f-/var/log/stream.lognetwork_mode:nonerestart:unless-stopped# Traefik Certs Dumper - Extract LetsEncrypt Certificates - Traefik2 Compatibletraefik-certs-dumper:container_name:traefik-certs-dumperimage:humenius/traefik-certs-dumper:latestsecurity_opt:-no-new-privileges:truerestart:unless-stoppednetwork_mode:none# command: --restart-containers container1,container2,container3volumes:-$APPDATADIR/traefik/acme:/traefik:ro-$APPDATADIR/traefik-certs/$DOMAINNAME_1:/output:rw# - /var/run/docker.sock:/var/run/docker.sock:ro # Only needed if restarting containers (use Docker Socket Proxy instead)environment:DOMAIN:$DOMAINNAME_1# Cloudflare Companioncloudflare-companion:image:tiredofit/traefik-cloudflare-companioncontainer_name:cloudflare-companionvolumes:-$LOGDIR:/logs# - /var/run/docker.sock:/var/run/docker.socksecrets:-cf_dns_api_tokenenvironment:-TIMEZONE=$TZ-LOG_TYPE=BOTH-LOG_LEVEL=INFO-TRAEFIK_VERSION=2-CF_EMAIL=$CF_EMAIL-CF_TOKEN=$CF_GLOBAL_TOKEN-RC_TYPE=CNAME-DOMAIN1_PROXIED=TRUE-TARGET_DOMAIN=$DOMAINNAME_1-DOMAIN1=$DOMAINNAME_1-DOMAIN1_ZONE_ID=$DOMAIN1_ZONE_ID-DOCKER_HOST=tcp://socket-proxy:2375-REFRESH_ENTRIES=TRUE#- DOCKER_CERT_PATH=/docker-certs#- DOCKER_TLS_VERIFY=1-TRAEFIK_FILTER_LABEL=traefik.constraint-TRAEFIK_FILTER=proxy-public# depends_on:# - socket-proxynetworks:-socket_proxyrestart:always# labels:# Add hosts specified in rules here to force cf-companion to create the CNAMEs# Since cf-companion creates CNAMEs based on host rules, this a workaround for non-docker/external apps# - "traefik.http.routers.cf-companion-rtr.rule=HostHeader(`vault.$DOMAINNAME_1`) || HostHeader(`ha.$DOMAINNAME_1`) || HostHeader(`overseerr.$DOMAINNAME_1`) || HostHeader(`nas.$DOMAINNAME_1`) || HostHeader(`todo.$DOMAINNAME_1`) || HostHeader(`auth.$DOMAINNAME_1`)"# - traefik.http.routers.example.rule=Host(`ha.$DOMAINNAME_1`) || Host(`overseerr.$DOMAINNAME_1`)networks:socket_proxy:external:trueswarm-traefik:external:truesecrets:cf_dns_api_token:file:$SECRETDIR/cf_dns_api_tokenbasic_auth_credentials:file:$SECRETDIR/basic_auth_credentials
Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
To create a user:password pair, the following command can be used:
http:middlewares:middlewares-secure-headers:headers:accessControlAllowMethods:-GET-OPTIONS-PUTaccessControlMaxAge:100hostsProxyHeaders:-"X-Forwarded-Host"stsSeconds:63072000stsIncludeSubdomains:truestsPreload:trueforceSTSHeader:true# This is a good thing but it can be tricky. Enable after everything works.customFrameOptionsValue:SAMEORIGIN# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-OptionscontentTypeNosniff:truebrowserXssFilter:truereferrerPolicy:"same-origin"permissionsPolicy:"camera=(),microphone=(),geolocation=(),payment=(),usb=()"customResponseHeaders:X-Robots-Tag:"none,noindex,nofollow,noarchive,nosnippet,notranslate,noimageindex"# disable search engines from indexing home serverserver:""# hide server info from visitorscustomRequestHeaders:X-Forwarded-Proto:https
tls:options:tls-opts:minVersion:VersionTLS12cipherSuites:-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256-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_AES_128_GCM_SHA256-TLS_AES_256_GCM_SHA384-TLS_CHACHA20_POLY1305_SHA256-TLS_FALLBACK_SCSV# Client is doing version fallback. See RFC 7507curvePreferences:-CurveP521-CurveP384sniStrict:true
routers:sub:entryPoints:-"https"rule:"Host(`sub.domain.be`)"middlewares:# Desable This if you having troubles -default-headers# Learn more about Middlewares-https-redirectscheme#tls:{}service:subsub2:entryPoints:-"https"rule:"Host(`sub2.domain.be`)"middlewares:-default-headers-https-redirectschemetls:{}service:sub2#endregion#region servicesservices:sub:loadBalancer:servers:-url:"http://172.30.0.50:5042"passHostHeader:truesub2:loadBalancer:servers:-url:"http://172.30.0.51:5042"passHostHeader:true
U Kunt ook traefik zijn configuratie automatisch laten verlopen door middel van labels op je docker containers te zetten.
De configuratie bij uw DNS provider zal nog steeds handmatig moeten gebeuren.
labels:# if you are not using traefik, comment out labels-"traefik.enable=true"-"traefik.http.routers.portainer.entrypoints=http"-"traefik.http.routers.portainer.rule=Host(`pihole.domain.be`)"-"traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"-"traefik.http.routers.portainer.middlewares=portainer-https-redirect"-"traefik.http.routers.portainer-secure.entrypoints=https"-"traefik.http.routers.portainer-secure.rule=Host(`pihole.domain.be`)"-"traefik.http.routers.portainer-secure.tls=true"-"traefik.http.routers.portainer-secure.service=portainer"-"traefik.http.services.portainer.loadbalancer.server.port=9000"-"traefik.docker.network=proxy"