Dokploy uses Traefik as its reverse proxy and load balancer, providing automatic routing, SSL certificates, and HTTP/3 support.
Overview
Traefik automatically discovers your services and configures routing based on labels and file-based configuration.
Auto-Discovery
Automatically detects Docker containers and Swarm services
SSL/TLS
Let’s Encrypt integration for automatic HTTPS certificates
HTTP/3
Modern protocol support with QUIC for improved performance
Installation
Traefik is automatically installed during server setup in two modes:
Standalone Mode
For single-server deployments:
docker run -d \
--name dokploy-traefik \
--restart always \
-v /etc/dokploy/traefik/traefik.yml:/etc/traefik/traefik.yml \
-v /etc/dokploy/traefik/dynamic:/etc/dokploy/traefik/dynamic \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 443:443 \
-p 80:80 \
-p 443:443/udp \
traefik:v3.6.7
Swarm Service Mode
For cluster deployments:
const settings: CreateServiceOptions = {
Name: "dokploy-traefik",
TaskTemplate: {
ContainerSpec: {
Image: "traefik:v3.6.7",
Mounts: [
{
Type: "bind",
Source: "/etc/dokploy/traefik/traefik.yml",
Target: "/etc/traefik/traefik.yml"
},
{
Type: "bind",
Source: "/etc/dokploy/traefik/dynamic",
Target: "/etc/dokploy/traefik/dynamic"
},
{
Type: "bind",
Source: "/var/run/docker.sock",
Target: "/var/run/docker.sock"
}
]
},
Networks: [{ Target: "dokploy-network" }],
Placement: {
Constraints: ["node.role==manager"]
}
}
};
Configuration
Main Configuration
Traefik uses a main traefik.yml configuration file:
global:
sendAnonymousUsage: false
providers:
swarm:
exposedByDefault: false
watch: true
docker:
exposedByDefault: false
watch: true
network: dokploy-network
file:
directory: /etc/dokploy/traefik/dynamic
watch: true
entryPoints:
web:
address: :80
websecure:
address: :443
http3:
advertisedPort: 443
http:
tls:
certResolver: letsencrypt
api:
insecure: true
certificatesResolvers:
letsencrypt:
acme:
email: test@localhost.com
storage: /etc/dokploy/traefik/dynamic/acme.json
httpChallenge:
entryPoint: web
The acme.json file must have 600 permissions to store SSL certificates securely.
Entry Points
Dokploy configures three entry points by default:
| Entry Point | Port | Protocol | Purpose |
|---|
| web | 80 | TCP | HTTP traffic |
| websecure | 443 | TCP | HTTPS traffic |
| websecure | 443 | UDP | HTTP/3 (QUIC) |
Port Configuration
Customize Traefik ports via environment variables:
TRAEFIK_PORT=80 # HTTP port
TRAEFIK_SSL_PORT=443 # HTTPS port
TRAEFIK_HTTP3_PORT=443 # HTTP/3 port
TRAEFIK_VERSION=3.6.7 # Traefik version
Service Discovery
Docker Provider
Traefik watches Docker containers and Swarm services:
providers:
docker:
exposedByDefault: false # Require explicit opt-in
watch: true # Auto-detect changes
network: dokploy-network # Default network
Services must explicitly opt-in to Traefik exposure using labels or configuration.
Swarm Provider
For Docker Swarm services:
providers:
swarm:
exposedByDefault: false
watch: true
File Provider
Dynamic configuration via YAML files:
providers:
file:
directory: /etc/dokploy/traefik/dynamic
watch: true # Hot-reload on file changes
Dynamic Configuration
File-Based Routing
Create routing rules in /etc/dokploy/traefik/dynamic/*.yml:
http:
routers:
my-app-router:
rule: "Host(`app.example.com`)"
service: my-app-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
my-app-service:
loadBalancer:
servers:
- url: "http://my-app:3000"
passHostHeader: true
Default Dokploy Configuration
Dokploy creates a default configuration for itself:
const config: FileConfig = {
http: {
routers: {
"dokploy-router-app": {
rule: "Host(`dokploy.docker.localhost`) && PathPrefix(`/`)",
service: "dokploy-service-app",
entryPoints: ["web"]
}
},
services: {
"dokploy-service-app": {
loadBalancer: {
servers: [{ url: "http://dokploy:3000" }],
passHostHeader: true
}
}
}
}
};
Middlewares
Traefik middlewares modify requests and responses:
HTTPS Redirect
Dokploy creates a default redirect middleware:
http:
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
Apply to routes:
routers:
my-app:
middlewares:
- redirect-to-https
Custom Middlewares
Add custom middlewares for:
SSL/TLS Certificates
Let’s Encrypt Integration
Traefik automatically obtains SSL certificates:
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /etc/dokploy/traefik/dynamic/acme.json
httpChallenge:
entryPoint: web
Certificate Request
When a new domain is routed, Traefik requests a certificate from Let’s Encrypt.
HTTP Challenge
Let’s Encrypt verifies domain ownership via HTTP-01 challenge on port 80.
Certificate Storage
Valid certificates are stored in acme.json with automatic renewal.
Certificate Deployment
Traefik automatically uses the certificate for HTTPS traffic.
Certificate Storage
Ensure proper permissions:
chmod 600 /etc/dokploy/traefik/dynamic/acme.json
If acme.json has incorrect permissions, Traefik will refuse to start for security reasons.
Load Balancing
Round Robin
Default load balancing strategy:
services:
my-app:
loadBalancer:
servers:
- url: "http://app1:3000"
- url: "http://app2:3000"
- url: "http://app3:3000"
Health Checks
Enable health checking:
services:
my-app:
loadBalancer:
healthCheck:
path: /health
interval: 10s
timeout: 3s
Sticky Sessions
Maintain session affinity:
services:
my-app:
loadBalancer:
sticky:
cookie:
name: dokploy_session
secure: true
httpOnly: true
HTTP/3 Support
Dokploy enables HTTP/3 (QUIC) on the websecure entry point:
entryPoints:
websecure:
address: :443
http3:
advertisedPort: 443
HTTP/3 uses UDP on port 443. Ensure your firewall allows UDP traffic on this port.
Benefits of HTTP/3:
- Faster connection establishment
- Better performance on lossy networks
- Improved mobile performance
- Built-in encryption
Dashboard
Traefik includes a built-in dashboard:
api:
insecure: true # Enable dashboard on port 8080
Access at: http://server-ip:8080/dashboard/
The dashboard is insecure by default. Secure it with authentication or restrict access via firewall rules in production.
Enabling Dashboard Port
Add port 8080 to Traefik container:
additionalPorts: [{
targetPort: 8080,
publishedPort: 8080,
protocol: "tcp"
}]
Advanced Configuration
Custom Entry Points
Add custom ports for specific services:
const options: TraefikOptions = {
additionalPorts: [
{
targetPort: 8080,
publishedPort: 8080,
protocol: "tcp"
},
{
targetPort: 9000,
publishedPort: 9000,
protocol: "udp"
}
]
};
Service Updates
Update Traefik configuration:
// For Swarm mode
const service = docker.getService("dokploy-traefik");
const inspect = await service.inspect();
await service.update({
version: parseInt(inspect.Version.Index),
...newSettings,
TaskTemplate: {
...newSettings.TaskTemplate,
ForceUpdate: inspect.Spec.TaskTemplate.ForceUpdate + 1
}
});
Routing Rules
Host-Based Routing
routers:
app1:
rule: "Host(`app1.example.com`)"
app2:
rule: "Host(`app2.example.com`)"
Path-Based Routing
routers:
api:
rule: "Host(`example.com`) && PathPrefix(`/api`)"
web:
rule: "Host(`example.com`) && PathPrefix(`/`)"
Combined Rules
routers:
complex:
rule: "Host(`api.example.com`) && PathPrefix(`/v2`) && Method(`POST`)"
routers:
mobile:
rule: "Host(`example.com`) && Headers(`User-Agent`, `.*Mobile.*`)"
Best Practices
- Always use HTTPS in production
- Secure the dashboard with authentication
- Set proper CORS headers
- Implement rate limiting for public APIs
- Use security headers middleware
- Restrict dashboard access by IP
- Use valid email for Let’s Encrypt
- Backup acme.json regularly
- Monitor certificate expiration
- Test certificate renewal
- Use staging environment for testing
- Use file provider for static configs
- Keep dynamic configs in version control
- Document custom middlewares
- Test routing rules before deployment
- Use meaningful router/service names
Troubleshooting
Certificate Issues
Check Permissions
ls -l /etc/dokploy/traefik/dynamic/acme.json
# Should show: -rw------- (600)
Verify HTTP Challenge
Ensure port 80 is accessible from the internet for Let’s Encrypt validation.
Review Logs
docker logs dokploy-traefik
Test Manually
Use Let’s Encrypt staging for testing to avoid rate limits.
Routing Not Working
Problem: Service not accessible via domain
Solutions:
- Check DNS points to server IP
- Verify router configuration is loaded
- Ensure service is on dokploy-network
- Check Traefik logs for errors
- Validate rule syntax
- Test with curl:
curl -H "Host: example.com" http://localhost
Service Discovery Failures
Problem: Traefik not detecting containers
Solutions:
- Verify Docker socket is mounted
- Check container is on correct network
- Ensure
watch: true is enabled
- Restart Traefik container
- Check provider configuration
High Latency
Problem: Slow response times through Traefik
Solutions:
- Enable HTTP/3 for modern clients
- Configure compression middleware
- Check backend service health
- Review timeout settings
- Monitor Traefik resource usage
- Consider using sticky sessions
Dashboard Not Accessible
Problem: Cannot access Traefik dashboard
Solutions:
- Verify port 8080 is published
- Check
api.insecure: true is set
- Ensure firewall allows port 8080
- Access via
http://ip:8080/dashboard/ (trailing slash required)
- Review Traefik startup logs