Traefik is a modern cloud-native reverse proxy and load balancer that can automatically discover services, obtain and renew TLS certificates via Let’s Encrypt, and expose a real-time dashboard — all without restarting when configuration changes. Unlike Nginx or HAProxy, Traefik reads its routing rules from provider backends such as Docker labels, Kubernetes annotations, or plain YAML files, making it well-suited for dynamic environments. On RHEL 8, Traefik runs as a single statically linked binary managed by systemd, requiring no external runtime or package manager beyond the initial download. This tutorial installs Traefik, configures HTTP and HTTPS entrypoints, sets up automatic certificate renewal with ACME, defines a dynamic router and service, and enables the dashboard.
Prerequisites
- A RHEL 8 server with root or
sudoaccess - A public domain name pointing to the server’s IP (required for Let’s Encrypt certificate issuance)
- Ports 80, 443, and 8080 open in the firewall
- At least one backend service listening on a local port (examples use port 3000)
curlandtaravailable on the system
Step 1 — Download and Install the Traefik Binary
Traefik publishes pre-compiled binaries for Linux amd64 on GitHub Releases. Download the binary, verify its checksum, and place it in /usr/local/bin.
# Set the desired Traefik version
TRAEFIK_VERSION="v3.3.6"
# Download the binary and checksum file
curl -fsSL "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_linux_amd64.tar.gz"
-o /tmp/traefik.tar.gz
curl -fsSL "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_checksums.txt"
-o /tmp/traefik_checksums.txt
# Verify checksum
cd /tmp && grep "linux_amd64.tar.gz" traefik_checksums.txt | sha256sum -c -
# Extract and install
tar -xzf /tmp/traefik.tar.gz -C /tmp
sudo mv /tmp/traefik /usr/local/bin/traefik
sudo chmod +x /usr/local/bin/traefik
# Verify
traefik version
Step 2 — Create Directory Structure and Static Configuration
Traefik configuration is split into static configuration (entrypoints, providers, certificate resolvers — loaded once at startup) and dynamic configuration (routers, services, middlewares — reloaded without restart). Create the directory layout and write the static config.
sudo mkdir -p /etc/traefik/dynamic /etc/traefik/certs
sudo chown -R root:root /etc/traefik
sudo chmod 700 /etc/traefik/certs
sudo tee /etc/traefik/traefik.yml > /dev/null <<'EOF'
global:
checkNewVersion: false
sendAnonymousUsage: false
log:
level: INFO
filePath: /var/log/traefik/traefik.log
accessLog:
filePath: /var/log/traefik/access.log
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
dashboard:
address: ":8080"
providers:
file:
directory: /etc/traefik/dynamic
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /etc/traefik/certs/acme.json
httpChallenge:
entryPoint: web
EOF
sudo mkdir -p /var/log/traefik
# acme.json must be mode 600 or Traefik refuses to use it
sudo touch /etc/traefik/certs/acme.json
sudo chmod 600 /etc/traefik/certs/acme.json
Step 3 — Create the systemd Service Unit
A dedicated system user and a systemd unit file keep Traefik isolated and ensure it restarts automatically on failure.
sudo useradd --system --no-create-home --shell /sbin/nologin traefik
sudo chown -R traefik:traefik /etc/traefik /var/log/traefik
sudo tee /etc/systemd/system/traefik.service > /dev/null <<'EOF'
[Unit]
Description=Traefik Reverse Proxy
Documentation=https://doc.traefik.io/traefik/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=traefik
Group=traefik
ExecStart=/usr/local/bin/traefik --configFile=/etc/traefik/traefik.yml
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576
# Harden the service
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/etc/traefik /var/log/traefik
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now traefik
sudo systemctl status traefik
Because Traefik needs to bind to ports 80 and 443, and it runs as a non-root user, grant the binary the net_bind_service capability.
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/traefik
sudo systemctl restart traefik
Step 4 — Define Dynamic Routes, Services, and Middlewares
Create a dynamic configuration file inside /etc/traefik/dynamic/. Traefik watches this directory and applies changes without restarting. This example routes app.example.com to a local backend on port 3000, applies an HTTPS redirect middleware, and terminates TLS with a Let’s Encrypt certificate.
sudo tee /etc/traefik/dynamic/apps.yml > /dev/null <<'EOF'
http:
routers:
myapp:
rule: "Host(`app.example.com`)"
entryPoints:
- websecure
service: myapp-backend
tls:
certResolver: letsencrypt
middlewares:
- secure-headers
dashboard-router:
rule: "Host(`traefik.example.com`)"
entryPoints:
- websecure
service: api@internal
tls:
certResolver: letsencrypt
middlewares:
- auth
services:
myapp-backend:
loadBalancer:
servers:
- url: "http://127.0.0.1:3000"
healthCheck:
path: /health
interval: 10s
timeout: 3s
middlewares:
secure-headers:
headers:
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
stsSeconds: 31536000
stsIncludeSubdomains: true
forceSTSHeader: true
auth:
basicAuth:
users:
- "admin:$apr1$xyz$hashedpasswordhere"
EOF
# Reload is automatic because watch: true is set
# Verify the dynamic config is valid
traefik healthcheck --configFile=/etc/traefik/traefik.yml
Step 5 — Open Firewall Ports and Test
Allow HTTP, HTTPS, and the dashboard port through the RHEL 8 firewall, then verify that Traefik is routing correctly.
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# Test HTTP-to-HTTPS redirect
curl -I http://app.example.com
# Test HTTPS (certificate issued by Let's Encrypt)
curl -I https://app.example.com
# Check Traefik API for registered routers
curl -s http://localhost:8080/api/http/routers | python3 -m json.tool
# View live logs
sudo journalctl -u traefik -f
Step 6 — Enable Docker Provider for Automatic Service Discovery
If you run Docker on the same host, Traefik can read container labels and automatically register routes without any changes to apps.yml.
# Add the Docker provider to traefik.yml
sudo tee -a /etc/traefik/traefik.yml > /dev/null <<'EOF'
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
watch: true
EOF
# Add traefik user to the docker group
sudo usermod -aG docker traefik
sudo systemctl restart traefik
# Example: start a container with Traefik labels
docker run -d
--label "traefik.enable=true"
--label "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
--label "traefik.http.routers.whoami.entrypoints=websecure"
--label "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
--name whoami
traefik/whoami
Conclusion
You have installed Traefik on RHEL 8 as a systemd service running under a dedicated non-root user, configured static entrypoints for HTTP and HTTPS with automatic Let’s Encrypt certificate issuance, defined dynamic routing rules with security headers middleware, and enabled optional Docker-based auto-discovery. Traefik’s file provider watches the /etc/traefik/dynamic/ directory and applies changes instantly, making it straightforward to add new services without downtime. For production use, store the acme.json file on persistent storage, monitor certificate expiry via Traefik’s metrics endpoint, and protect the dashboard with strong authentication.
Next steps: How to Set Up a Highly Available Web Stack with Keepalived on RHEL 8, How to Configure HAProxy for TCP and HTTP Load Balancing on RHEL 8, and How to Secure Traefik with OAuth2 Proxy and OpenID Connect on RHEL 8.