Skip to main content

Documentation Index

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

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

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 PointPortProtocolPurpose
web80TCPHTTP traffic
websecure443TCPHTTPS traffic
websecure443UDPHTTP/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:
middlewares:
  security-headers:
    headers:
      customResponseHeaders:
        X-Frame-Options: "DENY"
        X-Content-Type-Options: "nosniff"

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
1

Certificate Request

When a new domain is routed, Traefik requests a certificate from Let’s Encrypt.
2

HTTP Challenge

Let’s Encrypt verifies domain ownership via HTTP-01 challenge on port 80.
3

Certificate Storage

Valid certificates are stored in acme.json with automatic renewal.
4

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`)"

Header-Based Routing

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
  • Enable compression for text responses
  • Use HTTP/3 for modern clients
  • Configure appropriate timeouts
  • Implement health checks for backends
  • Use sticky sessions when needed
  • Monitor Traefik metrics
  • 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

1

Check Permissions

ls -l /etc/dokploy/traefik/dynamic/acme.json
# Should show: -rw------- (600)
2

Verify HTTP Challenge

Ensure port 80 is accessible from the internet for Let’s Encrypt validation.
3

Review Logs

docker logs dokploy-traefik
4

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