Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
traefik【部署与运维】Route traffic and manage TLS with Traefik reverse proxy. Use when a user asks to set up a reverse proxy, route traffic to Docker containers, auto-provision SSL certificates with Let's Encrypt, set up load balancing, configure HTTPS for multiple services, use a modern alternative to nginx for Docker, set up path-based or host-based routing, add middle…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Traefik is a modern reverse proxy and load balancer designed for containerized environments. Unlike nginx, Traefik auto-discovers services from Docker labels, Kubernetes ingress, and other providers — no manual config file updates when you add or remove services. It handles Let's Encrypt TLS certificates automatically, supports path-based and host-based routing, and offers middleware for rate limiting, authentication, headers, and more.
# docker-compose.yml — Traefik with auto-discovery and Let's Encrypt
# Traefik watches Docker events and configures routing from container labels
services:
traefik:
image: traefik:v3.2
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false" # only route labeled containers
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Let's Encrypt auto-TLS
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
# HTTP → HTTPS redirect
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Docker auto-discovery
- letsencrypt:/letsencrypt # TLS certificate storage
labels:
# Dashboard at traefik.example.com (protected by basicauth)
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$apr1$xyz$hashedpassword"
volumes:
letsencrypt:
# docker-compose.yml — Application services with Traefik routing labels
# Each service declares its own routing rules via labels — no Traefik config changes needed
services:
traefik:
# ... (from Step 1)
webapp:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
- "traefik.http.services.webapp.loadbalancer.server.port=3000"
api:
image: myapi:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=8000"
blog:
image: ghost:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
- "traefik.http.routers.blog.tls.certresolver=letsencrypt"
- "traefik.http.services.blog.loadbalancer.server.port=2368"
Adding a new service is just adding labels — Traefik detects the container automatically and starts routing. No restart, no config reload.
# Route different paths to different services on the same domain
services:
frontend:
image: frontend:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`example.com`)"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
api:
image: api:latest
labels:
- "traefik.enable=true"
# PathPrefix routes /api/* to this service
- "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=8000"
# Strip /api prefix before forwarding (so /api/users → /users)
- "traefik.http.routers.api.middlewares=strip-api"
- "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api"
# Rate limiting
labels:
- "traefik.http.middlewares.rate-limit.ratelimit.average=100" # 100 req/s average
- "traefik.http.middlewares.rate-limit.ratelimit.burst=200"
- "traefik.http.routers.api.middlewares=rate-limit"
# Security headers
labels:
- "traefik.http.middlewares.security.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security.headers.frameDeny=true"
- "traefik.http.routers.webapp.middlewares=security"
# IP whitelist (admin panel)
labels:
- "traefik.http.middlewares.admin-ip.ipallowlist.sourcerange=10.0.0.0/8,192.168.1.0/24"
- "traefik.http.routers.admin.middlewares=admin-ip"
# Basic auth
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$2y$05$hashhere"
- "traefik.http.routers.protected.middlewares=auth"
# Compress responses
labels:
- "traefik.http.middlewares.compress.compress=true"
- "traefik.http.routers.webapp.middlewares=compress"
# Chain multiple middlewares
labels:
- "traefik.http.routers.api.middlewares=rate-limit,security,compress"
# Scale services and Traefik auto-load-balances
services:
webapp:
image: myapp:latest
deploy:
replicas: 3 # 3 instances
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
- "traefik.http.services.webapp.loadbalancer.server.port=3000"
# Health check
- "traefik.http.services.webapp.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.webapp.loadbalancer.healthcheck.interval=10s"
# Sticky sessions (if needed)
- "traefik.http.services.webapp.loadbalancer.sticky.cookie.name=server_id"
For services outside Docker (bare metal, VMs), use file configuration:
# /etc/traefik/dynamic/services.yml — Route to external services
http:
routers:
legacy-app:
rule: "Host(`legacy.example.com`)"
service: legacy-backend
tls:
certResolver: letsencrypt
services:
legacy-backend:
loadBalancer:
servers:
- url: "http://192.168.1.50:8080"
- url: "http://192.168.1.51:8080"
healthCheck:
path: /health
interval: "15s"
# traefik.yml (static config) — Enable file provider
providers:
docker:
exposedByDefault: false
file:
directory: /etc/traefik/dynamic/
watch: true # auto-reload on file changes
User prompt: "I have 4 Docker services (app, API, admin panel, blog) that each need their own subdomain with automatic HTTPS."
The agent will:
User prompt: "Set up Traefik so I can deploy new versions without downtime. Old containers should keep serving until new ones are healthy."
The agent will:
:ro) — Traefik only needs to read container labels, not manage containers.exposedByDefault=false to prevent accidentally routing internal services (databases, Redis) to the internet. Only containers with traefik.enable=true get routes.