Skip to content
Back to skills

Dokploy Traefik Routing

ASecurity

Configure Traefik labels for routing, SSL/TLS with LetsEncrypt, and advanced routing patterns including Cloudflare DNS challenge. Use when adding web access to Dokploy services.

  • 4 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 12, 2026
devopspythonrustgojavanodedjangoflaskspringdockergit

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 12, 2026

npx -y skills add aibot88/sec_skill_store --skill dokploy-traefik-routing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dokploy Traefik Routing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dokploy Traefik Routing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aibot88-dokploy-traefik-routing/badge)](https://www.skillsdirectory.com/skills/aibot88-dokploy-traefik-routing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dokploy-traefik-routing
description: "Configure Traefik labels for routing, SSL/TLS with LetsEncrypt, and advanced routing patterns including Cloudflare DNS challenge. Use when adding web access to Dokploy services."
version: 1.0.0
author: Home Lab Infrastructure Team
---

# Dokploy Traefik Routing

## When to Use This Skill

- When adding web-accessible services to Dokploy templates
- When configuring SSL/TLS certificates via LetsEncrypt
- When setting up custom routing rules (path-based, subdomain)
- When enabling Cloudflare DNS challenge for wildcard certs
- When user asks about "traefik routing" or "SSL setup"

## When NOT to Use This Skill

- For non-HTTP services (raw TCP/UDP ports) - use port mapping instead
- For internal-only services (databases, caches) - no Traefik needed
- For services behind Cloudflare Tunnel - different configuration

## Prerequisites

- Service must connect to `dokploy-network`
- Domain name configured in environment variables
- LetsEncrypt resolver configured in Traefik (standard in Dokploy)

---

## Core Patterns

### Pattern 1: Standard HTTPS Routing (Most Common)

Every web-facing service needs these 6 labels:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.${service}.rule=Host(`${DOMAIN}`)"
  - "traefik.http.routers.${service}.entrypoints=websecure"
  - "traefik.http.routers.${service}.tls.certresolver=letsencrypt"
  - "traefik.http.services.${service}.loadbalancer.server.port=${port}"
  - "traefik.docker.network=dokploy-network"
```

**Explanation:**
1. `traefik.enable=true` - Enable Traefik routing for this service
2. `rule=Host(...)` - Match requests to this domain
3. `entrypoints=websecure` - Use HTTPS (port 443)
4. `tls.certresolver=letsencrypt` - Auto-provision SSL certificate
5. `loadbalancer.server.port` - Internal container port
6. `docker.network` - Which network Traefik uses to reach service

### Pattern 2: Cloudflare DNS Challenge

For wildcard certificates or when HTTP challenge isn't possible:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.${service}.rule=Host(`${DOMAIN}`)"
  - "traefik.http.routers.${service}.entrypoints=websecure"
  - "traefik.http.routers.${service}.tls.certresolver=cloudflare"
  - "traefik.http.routers.${service}.tls.domains[0].main=${BASE_DOMAIN}"
  - "traefik.http.routers.${service}.tls.domains[0].sans=*.${BASE_DOMAIN}"
  - "traefik.http.services.${service}.loadbalancer.server.port=${port}"
  - "traefik.docker.network=dokploy-network"
```

**Note**: Requires Cloudflare API credentials in Traefik configuration.

### Pattern 3: Path-Based Routing

Route different paths to different services:

```yaml
# Main app
labels:
  - "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
  # ...

# API service
labels:
  - "traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`)"
  - "traefik.http.routers.api.entrypoints=websecure"
  - "traefik.http.routers.api.tls.certresolver=letsencrypt"
  - "traefik.http.services.api.loadbalancer.server.port=8080"
  - "traefik.docker.network=dokploy-network"
```

### Pattern 4: Subdomain Routing

Route subdomains to different services:

```yaml
# Main app at example.com
labels:
  - "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
  # ...

# Admin at admin.example.com
labels:
  - "traefik.http.routers.admin.rule=Host(`admin.${DOMAIN}`)"
  - "traefik.http.routers.admin.entrypoints=websecure"
  - "traefik.http.routers.admin.tls.certresolver=letsencrypt"
  - "traefik.http.services.admin.loadbalancer.server.port=9000"
  - "traefik.docker.network=dokploy-network"
```

### Pattern 5: Multiple Routers per Service

When a service needs different ports exposed:

```yaml
labels:
  # Web UI
  - "traefik.http.routers.service-web.rule=Host(`${DOMAIN}`)"
  - "traefik.http.routers.service-web.entrypoints=websecure"
  - "traefik.http.routers.service-web.tls.certresolver=letsencrypt"
  - "traefik.http.services.service-web.loadbalancer.server.port=3000"
  # API endpoint
  - "traefik.http.routers.service-api.rule=Host(`api.${DOMAIN}`)"
  - "traefik.http.routers.service-api.entrypoints=websecure"
  - "traefik.http.routers.service-api.tls.certresolver=letsencrypt"
  - "traefik.http.services.service-api.loadbalancer.server.port=8080"
  - "traefik.docker.network=dokploy-network"
```

### Pattern 6: Middleware for Security Headers

Add security headers or other middleware:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
  - "traefik.http.routers.app.entrypoints=websecure"
  - "traefik.http.routers.app.tls.certresolver=letsencrypt"
  - "traefik.http.routers.app.middlewares=security-headers@docker"
  # Define middleware
  - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security-headers.headers.frameDeny=true"
  - "traefik.http.services.app.loadbalancer.server.port=3000"
  - "traefik.docker.network=dokploy-network"
```

### Pattern 7: CORS Middleware (for APIs)

Enable CORS for API services:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.api.rule=Host(`api.${DOMAIN}`)"
  - "traefik.http.routers.api.entrypoints=websecure"
  - "traefik.http.routers.api.tls.certresolver=letsencrypt"
  - "traefik.http.routers.api.middlewares=cors@docker"
  # CORS middleware
  - "traefik.http.middlewares.cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE,OPTIONS"
  - "traefik.http.middlewares.cors.headers.accessControlAllowHeaders=Content-Type,Authorization"
  - "traefik.http.middlewares.cors.headers.accessControlAllowOriginList=https://${DOMAIN}"
  - "traefik.http.middlewares.cors.headers.accessControlMaxAge=100"
  - "traefik.http.services.api.loadbalancer.server.port=8080"
  - "traefik.docker.network=dokploy-network"
```

---

## Complete Examples

### Example 1: Basic HTTPS Service (Paaster)

```yaml
services:
  paaster:
    image: wardpearce/paaster:3.1.7
    networks:
      - paaster-net
      - dokploy-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.paaster.rule=Host(`${PAASTER_DOMAIN}`)"
      - "traefik.http.routers.paaster.entrypoints=websecure"
      - "traefik.http.routers.paaster.tls.certresolver=letsencrypt"
      - "traefik.http.services.paaster.loadbalancer.server.port=3000"
      - "traefik.docker.network=dokploy-network"
```

### Example 2: Git Service with SSH (Forgejo)

```yaml
services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:9
    ports:
      - "${SSH_PORT:-2222}:22"  # SSH access (raw port, not Traefik)
    networks:
      - forgejo-net
      - dokploy-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.forgejo.rule=Host(`${FORGEJO_DOMAIN}`)"
      - "traefik.http.routers.forgejo.entrypoints=websecure"
      - "traefik.http.routers.forgejo.tls.certresolver=letsencrypt"
      - "traefik.http.services.forgejo.loadbalancer.server.port=3000"
      - "traefik.docker.network=dokploy-network"
```

### Example 3: Service with Admin Subdomain

```yaml
services:
  app:
    image: myapp:1.0.0
    networks:
      - app-net
      - dokploy-network
    labels:
      # Main application
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
      - "traefik.http.services.app.loadbalancer.server.port=8080"
      # Admin panel on subdomain
      - "traefik.http.routers.app-admin.rule=Host(`admin.${DOMAIN}`)"
      - "traefik.http.routers.app-admin.entrypoints=websecure"
      - "traefik.http.routers.app-admin.tls.certresolver=letsencrypt"
      - "traefik.http.services.app-admin.loadbalancer.server.port=9000"
      - "traefik.docker.network=dokploy-network"
```

---

## Service Port Reference

Common service ports to use in loadbalancer configuration:

| Service Type | Typical Port | Example |
|-------------|--------------|---------|
| Nginx/Apache | 80 | AnonUpload |
| Node.js apps | 3000 | Paaster, Forgejo |
| Python/Flask | 5000 | Flask apps |
| Django/Gunicorn | 8000 | Paperless-ngx |
| Java/Spring | 8080 | Spring Boot |
| Go apps | 8080 | Various |
| Admin panels | 9000-9999 | Admin UIs |

---

## Quality Standards

### Mandatory Labels
- [ ] `traefik.enable=true`
- [ ] `traefik.http.routers.${name}.rule` - Domain matching
- [ ] `traefik.http.routers.${name}.entrypoints=websecure`
- [ ] `traefik.http.routers.${name}.tls.certresolver=letsencrypt`
- [ ] `traefik.http.services.${name}.loadbalancer.server.port`
- [ ] `traefik.docker.network=dokploy-network`

### Naming Conventions
- Router names must be unique across all services
- Use service name as router name (e.g., `paaster`, `forgejo`)
- For multiple routers on one service, append suffix (e.g., `app-web`, `app-api`)

### Security Requirements
- Always use `websecure` entrypoint (HTTPS)
- Always use `letsencrypt` or `cloudflare` certresolver
- Consider adding security headers middleware for sensitive apps

---

## Common Pitfalls

### Pitfall 1: Missing dokploy-network label
**Issue**: Traefik can't reach service
**Solution**: Always include `traefik.docker.network=dokploy-network`

### Pitfall 2: Duplicate router names
**Issue**: Routing conflicts, unpredictable behavior
**Solution**: Ensure each router name is unique across all compose files

### Pitfall 3: Wrong port in loadbalancer
**Issue**: 502 Bad Gateway errors
**Solution**: Use the internal container port, not the exposed port

### Pitfall 4: Service not on dokploy-network
**Issue**: Traefik can't route to service
**Solution**: Service must be connected to `dokploy-network`

### Pitfall 5: Using HTTP entrypoint
**Issue**: Unencrypted traffic
**Solution**: Always use `websecure`, never `web` for production

---

## Integration

### Skills-First Approach (v2.0+)

This skill is part of the **skills-first architecture** - loaded during Generation phase to add Traefik routing labels after base compose structure is created.

### Related Skills
- `dokploy-compose-structure`: Network setup
- `dokploy-cloudflare-integration`: Cloudflare DNS challenge, Zero Trust
- `dokploy-security-hardening`: Security headers

### Invoked By
- `/dokploy-create` command: Phase 3 (Generation) - Step 2

### Order in Workflow (Progressive Loading)
1. `dokploy-compose-structure`: Create base structure
2. **This skill**: Add Traefik routing labels (Step 2)
3. `dokploy-health-patterns`: Add health checks
4. `dokploy-cloudflare-integration`: Add CF integration (if applicable)
5. `dokploy-environment-config`: Configure environment
6. `dokploy-template-toml`: Create template.toml

See: `.claude/commands/dokploy-create.md` for full workflow

Files in this skill

  • SKILL.md10.6 KB
  • source.json724 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.