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.
Nomad Provider
A Story of Tags, Services & Nomads
Attach tags to your Nomad services and let Traefik automatically discover and route traffic. The Nomad provider integrates with HashiCorp Nomad’s native service discovery for seamless routing in your Nomad cluster.
Quick Start
Enable Nomad Provider
traefik.yml
traefik.toml
CLI
providers :
nomad :
endpoint :
address : "http://127.0.0.1:4646"
exposedByDefault : true
prefix : "traefik"
Add Tags to Nomad Job
job "web" {
group "app" {
service {
name = "web"
port = "http"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.web.rule=Host(`example.com`)" ,
"traefik.http.routers.web.entrypoints=websecure" ,
]
}
task "server" {
driver = "docker"
config {
image = "myapp:latest"
ports = [ "http" ]
}
}
network {
port "http" {
to = 8080
}
}
}
}
Deploy Job
Traefik automatically discovers the service!
How It Works
The Nomad provider:
Queries Nomad API for registered services
Watches for changes (optional) in real-time
Extracts routing config from service tags
Discovers allocation IPs and ports
Creates routes dynamically
Updates on events when allocations start/stop
Provider Configuration
endpoint
Nomad server connection settings.
address
Default: http://127.0.0.1:4646
providers :
nomad :
endpoint :
address : "http://nomad.example.com:4646"
token
Optional, Default: ""
Nomad ACL token:
providers :
nomad :
endpoint :
token : "${NOMAD_TOKEN}"
endpointWaitTime
Optional, Default: ""
Watch block duration:
providers :
nomad :
endpoint :
endpointWaitTime : "15s"
tls
TLS configuration:
providers :
nomad :
endpoint :
address : "https://nomad.example.com:4646"
tls :
ca : "/path/to/ca.crt"
cert : "/path/to/client.crt"
key : "/path/to/client.key"
insecureSkipVerify : false
prefix
Default: traefik
Tag prefix for configuration:
providers :
nomad :
prefix : "lb"
Use tags like: lb.http.routers.app.rule=...
refreshInterval
Default: 15s
Polling interval:
providers :
nomad :
refreshInterval : "30s"
Ignored when watch: true is enabled.
watch
Default: false
Enable real-time event watching:
providers :
nomad :
watch : true
throttleDuration
Default: 0s
Throttle event handling:
providers :
nomad :
watch : true
throttleDuration : "2s"
Only works with watch: true.
exposedByDefault
Default: true
providers :
nomad :
exposedByDefault : false # Require traefik.enable=true tag
stale
Default: false
Allow stale reads for better performance:
providers :
nomad :
stale : true
defaultRule
Default: Host(`{{ normalize .Name }}`)
providers :
nomad :
defaultRule : "Host(`{{ .Name }}.nomad.example.com`)"
constraints
Optional, Default: ""
Filter services by tags:
providers :
nomad :
constraints : "Tag(`production`)"
namespaces (Enterprise)
Optional, Default: ""
Watch specific namespaces:
providers :
nomad :
namespaces :
- "production"
- "staging"
allowEmptyServices
Default: false
Create load balancers even with no healthy allocations:
providers :
nomad :
allowEmptyServices : true
Nomad Job Examples
Basic Web Service
job "webapp" {
datacenters = [ "dc1" ]
group "web" {
count = 3
network {
port "http" {
to = 8080
}
}
service {
name = "webapp"
port = "http"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.webapp.rule=Host(`app.example.com`)" ,
"traefik.http.routers.webapp.entrypoints=websecure" ,
"traefik.http.routers.webapp.tls.certresolver=letsencrypt" ,
]
check {
type = "http"
path = "/health"
interval = "10s"
timeout = "2s"
}
}
task "app" {
driver = "docker"
config {
image = "myapp:v1.0"
ports = [ "http" ]
}
resources {
cpu = 500
memory = 256
}
}
}
}
Service with Middleware
job "secure-api" {
group "api" {
service {
name = "secure-api"
port = "http"
tags = [
"traefik.enable=true" ,
# Router
"traefik.http.routers.api.rule=Host(`api.example.com`) && PathPrefix(`/v1`)" ,
"traefik.http.routers.api.entrypoints=websecure" ,
"traefik.http.routers.api.middlewares=auth,ratelimit,cors" ,
# Middleware
"traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..." ,
"traefik.http.middlewares.ratelimit.ratelimit.average=100" ,
"traefik.http.middlewares.ratelimit.ratelimit.burst=50" ,
"traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,POST,PUT" ,
"traefik.http.middlewares.cors.headers.accesscontrolalloworigin=*" ,
# Service
"traefik.http.services.api.loadbalancer.healthcheck.path=/health" ,
"traefik.http.services.api.loadbalancer.healthcheck.interval=10s" ,
]
}
# ... task definition
}
}
Multi-Service Job
job "microservices" {
group "app" {
network {
port "web" { to = 3000 }
port "api" { to = 8080 }
}
# Frontend service
service {
name = "frontend"
port = "web"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.frontend.rule=Host(`app.example.com`)" ,
]
}
# API service
service {
name = "api"
port = "api"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.api.rule=Host(`api.example.com`)" ,
]
}
task "web" {
driver = "docker"
config {
image = "frontend:latest"
ports = [ "web" ]
}
}
task "api" {
driver = "docker"
config {
image = "api:latest"
ports = [ "api" ]
}
}
}
}
Canary Deployment
job "app" {
group "stable" {
count = 9
service {
name = "app"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.app.rule=Host(`app.example.com`)" ,
"traefik.http.services.app.loadbalancer.weight=90" ,
]
}
task "app" {
driver = "docker"
config {
image = "app:v1.0"
}
}
}
group "canary" {
count = 1
service {
name = "app-canary"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.app.rule=Host(`app.example.com`)" ,
"traefik.http.services.app-canary.loadbalancer.weight=10" ,
]
}
task "app" {
driver = "docker"
config {
image = "app:v2.0-beta"
}
}
}
}
Complete Traefik Deployment
job "traefik" {
datacenters = [ "dc1" ]
type = "system" # Run on all nodes
group "traefik" {
network {
port "http" {
static = 80
}
port "https" {
static = 443
}
port "admin" {
static = 8080
}
}
service {
name = "traefik"
port = "http"
tags = [
"traefik.enable=true" ,
"traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)" ,
"traefik.http.routers.dashboard.service=api@internal" ,
]
}
task "traefik" {
driver = "docker"
config {
image = "traefik:v3.6"
network_mode = "host"
volumes = [
"local/traefik.yml:/etc/traefik/traefik.yml" ,
]
}
template {
data = << EOF
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
nomad:
endpoint:
address: "http://{{ env "NOMAD_IP_admin" }}:4646"
watch: true
exposedByDefault: false
api:
dashboard: true
EOF
destination = "local/traefik.yml"
}
resources {
cpu = 500
memory = 512
}
}
}
}
Network Modes
Bridge Mode (Default)
network {
mode = "bridge"
port "http" {
to = 8080
}
}
Traefik connects to allocation’s private IP.
Host Mode
network {
mode = "host"
port "http" {
static = 8080
}
}
Direct node IP access.
CNI Plugins
network {
mode = "bridge"
port "http" {}
}
With Consul Connect or other CNI plugins.
Tag Syntax
All Traefik labels work as Nomad tags:
traefik.http.routers.app.rule=Host(`example.com`)
traefik.http.routers.app.middlewares=auth
tags = [
"traefik.http.routers.app.rule=Host(`example.com`)" ,
"traefik.http.routers.app.middlewares=auth" ,
]
Troubleshooting
Services Not Discovered
Check Nomad Connection
curl http://127.0.0.1:4646/v1/services
Verify Service Registration
nomad service list
nomad service info webapp
Check ACL Token
Ensure read-job policy is attached.
Review Traefik Logs
nomad alloc logs -f < traefik-alloc-i d >
Health Check Issues
Ensure service has health checks:
service {
check {
type = "http"
path = "/health"
interval = "10s"
timeout = "2s"
}
}
ACL Configuration
Create policy for Traefik:
# traefik-policy.hcl
namespace "*" {
policy = "read"
capabilities = [ "read-job" ]
}
Apply policy:
nomad acl policy apply traefik-policy traefik-policy.hcl
nomad acl token create -name= "traefik" -policy=traefik-policy
Best Practices
Enable Watch Mode
Use watch: true for real-time updates instead of polling.
Use Health Checks
Always configure Nomad service health checks.
Tag Consistently
Develop a tagging strategy (environment, version, team).
Secure ACL Tokens
Use minimum required permissions and rotate tokens regularly.
Set Stale Reads
Enable stale: true for better performance in large clusters.
Next Steps
Nomad Routing Detailed tag configuration reference
Nomad Documentation Official HashiCorp Nomad documentation