Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/traefik/traefik/llms.txt

Use this file to discover all available pages before exploring further.

Routers

Routers connect incoming requests to services based on matching rules.

What is a Router?

A router analyzes incoming requests and determines which service should handle them based on configured rules. Routers can also apply middleware before forwarding requests.
Routers are configured in dynamic configuration and can be updated without restarting Traefik.

HTTP Routers

HTTP routers match requests using powerful rule matchers.

Basic Router Configuration

http:
  routers:
    my-router:
      rule: "Host(`example.com`)"
      service: my-service
      entryPoints:
        - web

Router Configuration Options

rule
string
required
The matching rule that determines if this router handles a request. See Routing Rules below.
rule: "Host(`example.com`) && PathPrefix(`/api`)"
service
string
required
The name of the service to forward matched requests to.
service: "my-backend-service"
entryPoints
array
List of entry points to listen on. If not specified, router listens on all default entry points.
entryPoints:
  - web
  - websecure
middlewares
array
List of middleware to apply before forwarding to the service.
middlewares:
  - auth
  - ratelimit
priority
integer
Router priority. Higher values take precedence. Default is rule length.
priority: 100
tls
object
TLS configuration for HTTPS routers.
tls:
  certResolver: letsencrypt

Routing Rules

Rules determine which requests match a router. Traefik provides multiple matchers that can be combined with logical operators.

Available Matchers

Traefik implements these matchers in pkg/muxer/http/matcher.go:16-28:
MatcherDescriptionExample
Host()Match request hostHost(example.com)
HostRegexp()Match host with regexHostRegexp(^.+.example.com$)
Path()Match exact pathPath(/api)
PathPrefix()Match path prefixPathPrefix(/api)
PathRegexp()Match path with regexPathRegexp(^/api/v[0-9]+)
Method()Match HTTP methodMethod(POST)
Header()Match header valueHeader(Content-Type, application/json)
HeaderRegexp()Match header with regexHeaderRegexp(Content-Type, ^application/(json|yaml)$)
Query()Match query parameterQuery(mobile, true)
QueryRegexp()Match query with regexQueryRegexp(version, ^v[0-9]+$)
ClientIP()Match client IP/CIDRClientIP(192.168.1.0/24)

Host Matching

Match a specific domain:
rule: "Host(`api.example.com`)"
Host matching is case-insensitive and automatically handles trailing periods.

Path Matching

Match an exact path:
# Matches /api only, not /api/ or /api/users
rule: "Path(`/api`)"

Header Matching

# Match Content-Type header
rule: "Header(`Content-Type`, `application/json`)"

Query Parameter Matching

# Match ?mobile=true
rule: "Query(`mobile`, `true`)"

# Match presence of parameter (any value)
rule: "Query(`debug`)"

Method Matching

# Match POST requests
rule: "Method(`POST`)"

# Match multiple methods
rule: "Method(`PUT`) || Method(`PATCH`)"

# Combine with path for REST API
rule: "Method(`POST`) && PathPrefix(`/api`)"

Client IP Matching

# Match specific client IP
rule: "ClientIP(`192.168.1.100`)"

# IPv6 address
rule: "ClientIP(`2001:db8::1`)"
ClientIP() matches the actual client IP, not X-Forwarded-For headers. Configure forwardedHeaders on EntryPoints to trust proxy headers.

Combining Rules

Use logical operators to create complex routing rules:
Both conditions must match:
# API subdomain AND /v2 path
rule: "Host(`api.example.com`) && PathPrefix(`/v2`)"

# Internal IP AND admin path
rule: "ClientIP(`10.0.0.0/8`) && PathPrefix(`/admin`)"

# POST method AND JSON content
rule: "Method(`POST`) && Header(`Content-Type`, `application/json`)"

Router Priority

When multiple routers match a request, priority determines which router handles it.
http:
  routers:
    # Priority: 42 (rule length)
    specific:
      rule: "Host(`api.example.com`) && PathPrefix(`/v2/users`)"
      service: users-v2
    
    # Priority: 36 (rule length)
    general:
      rule: "Host(`api.example.com`) && PathPrefix(`/v2`)"
      service: api-v2
Higher priority values are evaluated first. Default priority is the character length of the rule string.

Middleware Integration

Routers can apply middleware before forwarding to services:
http:
  routers:
    api-router:
      rule: "Host(`api.example.com`)"
      service: api-service
      middlewares:
        - api-auth       # Applied first
        - api-ratelimit  # Applied second
        - api-compress   # Applied third
  
  middlewares:
    api-auth:
      basicAuth:
        users:
          - "admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
    
    api-ratelimit:
      rateLimit:
        average: 100
        burst: 50
    
    api-compress:
      compress: {}
See the Middleware documentation for available middleware options.

TLS Configuration

Enable HTTPS and automatic certificate management:
Use Let’s Encrypt for automatic certificates:
http:
  routers:
    secure-router:
      rule: "Host(`example.com`)"
      service: my-service
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

TCP Routers

TCP routers have limited rule matching compared to HTTP:
tcp:
  routers:
    database-router:
      rule: "HostSNI(`db.example.com`)"
      service: postgres-service
      entryPoints:
        - database
      tls:
        certResolver: letsencrypt
  
  services:
    postgres-service:
      loadBalancer:
        servers:
          - address: "10.0.1.20:5432"
TCP routers only support HostSNI() matching for TLS connections. Non-TLS TCP uses HostSNI(*) to match all traffic.

UDP Routers

UDP routers don’t use rules - all traffic on an entry point goes to the service:
udp:
  routers:
    dns-router:
      service: dns-service
      entryPoints:
        - dns
  
  services:
    dns-service:
      loadBalancer:
        servers:
          - address: "10.0.1.30:53"

Real-World Examples

Route different tenants to different services:
http:
  routers:
    tenant-a:
      rule: "Host(`tenant-a.api.example.com`)"
      service: tenant-a-service
      priority: 100
    
    tenant-b:
      rule: "Host(`tenant-b.api.example.com`)"
      service: tenant-b-service
      priority: 100
    
    default-tenant:
      rule: "HostRegexp(`^.+\\.api\\.example\\.com$`)"
      service: default-service
      priority: 50
Route API versions to different services:
http:
  routers:
    api-v2:
      rule: "Host(`api.example.com`) && PathPrefix(`/v2`)"
      service: api-v2-service
      priority: 200
    
    api-v1:
      rule: "Host(`api.example.com`) && PathPrefix(`/v1`)"
      service: api-v1-service
      priority: 150
    
    api-default:
      rule: "Host(`api.example.com`)"
      service: api-v2-service  # Default to latest
      priority: 100
Route traffic based on headers for testing:
http:
  routers:
    green-deployment:
      rule: "Host(`app.example.com`) && Header(`X-Version`, `green`)"
      service: green-service
      priority: 200
    
    blue-deployment:
      rule: "Host(`app.example.com`)"
      service: blue-service
      priority: 100
Route based on client IP ranges:
http:
  routers:
    eu-region:
      rule: "Host(`app.example.com`) && ClientIP(`10.1.0.0/16`)"
      service: eu-service
      priority: 200
    
    us-region:
      rule: "Host(`app.example.com`) && ClientIP(`10.2.0.0/16`)"
      service: us-service
      priority: 200
    
    default-region:
      rule: "Host(`app.example.com`)"
      service: us-service
      priority: 100

Next Steps

Configure Services

Set up load balancing and health checks for your backends

Add Middleware

Transform requests with authentication, rate limiting, and more