How to Install and Configure Traefik Reverse Proxy on RHEL 7
Traefik is a modern, cloud-native reverse proxy and load balancer that differentiates itself from Nginx and HAProxy through its dynamic configuration model — routing rules can be updated at runtime without restarting the proxy. Originally designed for microservices and Docker environments, Traefik works equally well on bare-metal and VM deployments using file-based dynamic configuration. On RHEL 7, Traefik is distributed as a single statically-linked binary, making installation straightforward without any package repository dependencies. This guide covers downloading and installing Traefik, configuring it as a systemd service, setting up HTTP and HTTPS entrypoints with automatic Let’s Encrypt certificates, defining routers and services via file provider configuration, enabling the dashboard, and applying common middleware such as HTTP-to-HTTPS redirects, basic authentication, and security headers.
Prerequisites
- RHEL 7 server with root access
- A public domain name pointing to the server’s IP (required for Let’s Encrypt TLS certificates)
- Ports 80 and 443 open in the firewall and accessible from the internet
- One or more backend services already running on localhost ports (e.g., a web application on port 8080)
- The
curlandtarutilities installed (available by default on RHEL 7)
Step 1: Downloading the Traefik Binary
Traefik releases are published as pre-built binaries on GitHub. Check the latest stable v2.x release at https://github.com/traefik/traefik/releases and download the Linux AMD64 build:
# Set the version to install (check GitHub releases for the latest)
TRAEFIK_VERSION="v2.11.0"
cd /tmp
curl -LO "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_linux_amd64.tar.gz"
# Verify the checksum (recommended)
curl -LO "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_checksums.txt"
sha256sum -c traefik_${TRAEFIK_VERSION}_checksums.txt --ignore-missing
Extract and install the binary:
tar xzf traefik_${TRAEFIK_VERSION}_linux_amd64.tar.gz
install -m 755 traefik /usr/local/bin/traefik
# Verify
traefik version
Step 2: Creating the Directory Structure and User
Create a dedicated unprivileged system user and the required directories:
# Create system user with no login shell
useradd -r -s /sbin/nologin -d /etc/traefik traefik
# Create config directories
mkdir -p /etc/traefik/conf.d
mkdir -p /var/log/traefik
mkdir -p /etc/traefik/acme
# Set ownership
chown -R traefik:traefik /etc/traefik
chown -R traefik:traefik /var/log/traefik
# ACME storage must be private — Let's Encrypt requires 0600
touch /etc/traefik/acme/acme.json
chmod 600 /etc/traefik/acme/acme.json
chown traefik:traefik /etc/traefik/acme/acme.json
Grant the binary capability to bind to privileged ports (80, 443) without running as root:
yum install -y libcap
setcap 'cap_net_bind_service=+ep' /usr/local/bin/traefik
Step 3: Creating the Static Configuration (traefik.yml)
Traefik uses a two-tier configuration model. The static configuration (traefik.yml) defines entrypoints, providers, logging, and certificate resolvers. The dynamic configuration (files in /etc/traefik/conf.d/) defines routers, services, and middleware and can be reloaded without restarting Traefik.
vi /etc/traefik/traefik.yml
# Traefik v2 Static Configuration
# /etc/traefik/traefik.yml
log:
level: INFO
filePath: /var/log/traefik/traefik.log
accessLog:
filePath: /var/log/traefik/access.log
bufferingSize: 100
api:
dashboard: true
insecure: false # dashboard served via a secure router defined in dynamic config
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /etc/traefik/acme/acme.json
httpChallenge:
entryPoint: web
providers:
file:
directory: /etc/traefik/conf.d
watch: true # reload dynamic config automatically when files change
The watch: true directive causes Traefik to monitor /etc/traefik/conf.d/ for changes and apply new routing rules without a restart — this is Traefik’s key operational advantage.
Step 4: Creating the systemd Service Unit
vi /etc/systemd/system/traefik.service
[Unit]
Description=Traefik Reverse Proxy
Documentation=https://doc.traefik.io/traefik/
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=traefik
Group=traefik
ExecStart=/usr/local/bin/traefik --configFile=/etc/traefik/traefik.yml
Restart=on-failure
RestartSec=5s
# Security hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=/etc/traefik/acme /var/log/traefik
# Resource limits
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable traefik --now
systemctl status traefik
Check the log for startup errors:
journalctl -u traefik -n 50 --no-pager
Step 5: Configuring Routers and Services in Dynamic Config
Create the first dynamic configuration file to route traffic to a backend application running on port 8080:
vi /etc/traefik/conf.d/myapp.yml
http:
routers:
myapp:
rule: "Host(`app.example.com`)"
entryPoints:
- websecure
service: myapp-backend
tls:
certResolver: letsencrypt
middlewares:
- security-headers
services:
myapp-backend:
loadBalancer:
servers:
- url: "http://127.0.0.1:8080"
healthCheck:
path: /health
interval: 10s
timeout: 5s
scheme: http
Traefik will detect this file immediately (due to watch: true) and begin routing requests for app.example.com to the backend. TLS certificates will be issued automatically via Let’s Encrypt’s HTTP-01 challenge.
Step 6: Configuring Middleware
Middleware in Traefik transforms requests or responses before they reach a service. Create a shared middleware file:
vi /etc/traefik/conf.d/middleware.yml
http:
middlewares:
# Redirect HTTP to HTTPS (also defined at entrypoint level for global redirect)
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
# Basic authentication for protected endpoints
# Generate password hash: htpasswd -nb admin 'MyPassword'
basicauth-admin:
basicAuth:
users:
- "admin:$2y$10$abcdefghijklmnopqrstuvXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
realm: "Traefik Dashboard"
removeHeader: true
# Security response headers
security-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
contentTypeNosniff: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
frameDeny: true
customResponseHeaders:
X-Powered-By: ""
Server: ""
# Rate limiting (100 requests/second average, burst 200)
rate-limit:
rateLimit:
average: 100
burst: 200
Generate a bcrypt password hash for basic auth (install httpd-tools for htpasswd):
yum install -y httpd-tools
htpasswd -nb admin 'MySecurePassword'
# Output: admin:$apr1$xxxx$yyyyyyyyyyyyyyyyyyyyyyyyyyy
Step 7: Exposing the Traefik Dashboard Securely
The dashboard is a built-in web UI showing active routers, services, and middleware. Expose it on a dedicated subdomain with basic auth:
vi /etc/traefik/conf.d/dashboard.yml
http:
routers:
dashboard:
rule: "Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
entryPoints:
- websecure
service: api@internal
tls:
certResolver: letsencrypt
middlewares:
- basicauth-admin
- security-headers
Browse to https://traefik.example.com/dashboard/ (note the trailing slash) and log in with the credentials defined in your basicauth middleware. The dashboard shows real-time routing topology, health check status, and certificate details.
Step 8: Opening Firewall Ports
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-services
Step 9: Testing the Configuration
Verify the HTTP-to-HTTPS redirect works:
curl -v http://app.example.com/ 2>&1 | grep -E 'Location|HTTP/'
# Expect: HTTP/1.1 301 Moved Permanently
# Expect: Location: https://app.example.com/
Test HTTPS and check certificate:
curl -v https://app.example.com/ 2>&1 | grep -E 'subject|issuer|HTTP/'
# Check response headers include security headers
curl -I https://app.example.com/ | grep -E 'Strict-Transport|X-Frame|X-Content'
Verify the Traefik API is responding:
curl -sk -u admin:MySecurePassword https://traefik.example.com/api/rawdata | python -m json.tool | head -50
Watch the access log in real time:
tail -f /var/log/traefik/access.log
Conclusion
Traefik on RHEL 7 combines the simplicity of a single binary deployment with powerful dynamic routing capabilities that would otherwise require complex Nginx reload scripts or HAProxy hot-reload mechanisms. By structuring configuration into a static traefik.yml for infrastructure-level settings and watched drop-in files under /etc/traefik/conf.d/ for application routing, you can add, modify, or remove routes for new services without any service interruption. Automatic Let’s Encrypt certificate issuance and renewal, combined with the security headers middleware and basic auth protection on the dashboard, gives you a production-ready reverse proxy setup that scales from a single application on one server to dozens of services as your infrastructure grows.