Traefik Reverse Proxy บน VPS Docker Compose

เมื่อรัน Docker Container หลายตัวบน VPS เดียว คำถามที่พบบ่อยคือ "จะ Route traffic ไปยัง Container ถูกตัวได้อย่างไร?" Traefik คือ Modern Reverse Proxy ที่อ่าน Docker label แล้วตั้งค่า Routing อัตโนมัติ พร้อม SSL จาก Let's Encrypt โดยไม่ต้องแตะ config เมื่อเพิ่ม Service ใหม่

ทำไมต้องใช้ Traefik แทน Nginx

Nginx Reverse Proxy ที่ใช้กันทั่วไปต้องแก้ไข config file และ reload ทุกครั้งที่เพิ่ม subdomain หรือ service ใหม่ Traefik แก้ปัญหานี้ด้วยการอ่าน Docker label จาก Container โดยตรง ทำให้ระบบ self-configure ได้เองโดยอัตโนมัติ

สิ่งที่ต้องมีก่อนเริ่ม

โครงสร้างโฟลเดอร์

~/traefik/
├── docker-compose.yml
├── traefik.yml          # Static config
└── acme.json            # SSL certificates (สร้างทีหลัง)

ขั้นที่ 1 — สร้าง Docker Network

Traefik ต้องการ Docker network เดียวกันกับ Container ที่ต้องการ route

docker network create traefik-net

ขั้นที่ 2 — สร้าง Traefik Static Config

mkdir -p ~/traefik && cd ~/traefik
nano traefik.yml
# traefik.yml — Static Configuration
api:
  dashboard: true
  insecure: false   # ปิด insecure dashboard

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]   # แก้เป็น email จริง
      storage: /acme.json
      httpChallenge:
        entryPoint: web

providers:
  docker:
    exposedByDefault: false    # ต้องใส่ label "traefik.enable=true" ก่อนจึงจะ expose
    network: traefik-net

log:
  level: INFO

ขั้นที่ 3 — สร้าง docker-compose.yml

nano docker-compose.yml
version: "3.8"

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - ./acme.json:/acme.json
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      # Dashboard — ป้องกันด้วย Basic Auth
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hashedpassword"

networks:
  traefik-net:
    external: true

สร้าง Basic Auth Password

# ติดตั้ง htpasswd
sudo apt install apache2-utils -y

# สร้าง password hash (แทนที่ yourpassword)
htpasswd -nb admin yourpassword
# Output: admin:$apr1$...
# ใส่ใน label โดยเพิ่ม $ อีกตัวก่อนทุก $ (escape ใน compose)
# admin:$apr1$... → admin:$$apr1$$...

ขั้นที่ 4 — ตั้งค่า acme.json

touch acme.json
chmod 600 acme.json   # บังคับ permission 600 Traefik จะ refuse ถ้าไม่ถูก

ขั้นที่ 5 — เริ่มต้น Traefik

docker compose up -d
docker logs traefik -f   # ดู log

ตรวจสอบ SSL: หลังเริ่มต้น Traefik จะขอ SSL จาก Let's Encrypt อัตโนมัติ ใช้เวลา 1-2 นาที ดู log บรรทัด msg="Obtaining certificate" เพื่อยืนยัน

เพิ่ม Web Application ใหม่ด้วย Labels

ตัวอย่าง deploy WordPress Container ด้วย Traefik routing:

# docker-compose.yml ของ WordPress
version: "3.8"

services:
  wordpress:
    image: wordpress:latest
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_PASSWORD: secret
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wp.rule=Host(`blog.example.com`)"
      - "traefik.http.routers.wp.entrypoints=websecure"
      - "traefik.http.routers.wp.tls.certresolver=letsencrypt"
      - "traefik.http.services.wp.loadbalancer.server.port=80"

networks:
  traefik-net:
    external: true

Traefik รับรู้ Container ใหม่ทันทีโดยไม่ต้อง restart Traefik หรือแก้ config ไฟล์ใดๆ

Middleware ที่ใช้บ่อย

Rate Limiting

labels:
  - "traefik.http.middlewares.ratelimit.ratelimit.average=100"
  - "traefik.http.middlewares.ratelimit.ratelimit.burst=50"
  - "traefik.http.routers.myapp.middlewares=ratelimit"

IP Whitelist

labels:
  - "traefik.http.middlewares.ipwhitelist.ipallowlist.sourcerange=203.0.113.0/24,10.0.0.0/8"
  - "traefik.http.routers.admin.middlewares=ipwhitelist"

Redirect www → non-www

labels:
  - "traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www\\.(.+)"
  - "traefik.http.middlewares.www-redirect.redirectregex.replacement=https://$${1}"
  - "traefik.http.middlewares.www-redirect.redirectregex.permanent=true"

เปรียบเทียบ Traefik กับ Nginx Proxy Manager

ฟีเจอร์ Traefik Nginx Proxy Manager
Auto-discovery✅ Docker label❌ Manual
SSL Auto-renew✅ Built-in✅ Built-in
UIDashboard (read-only)Web UI ครบ
Middleware✅ ครบมากจำกัด
Kubernetes✅ Native Ingress❌
เหมาะกับDevOps/DeveloperBeginner ที่ต้องการ UI

Troubleshooting

SSL ไม่ออก — ตรวจสอบ

# ดู log Traefik
docker logs traefik 2>&1 | grep -i "error\|acme\|certificate"

# ตรวจ acme.json ว่ามีข้อมูล
cat acme.json | python3 -m json.tool | head -20

Container ไม่ถูก Route

# ตรวจว่า Container อยู่บน network เดียวกัน
docker inspect container_name | grep -A5 "Networks"

# ตรวจ label
docker inspect container_name | grep -i traefik

ต้องการ VPS สำหรับรัน Traefik + Docker?

AsiaGB มี VPS Linux พร้อม Full Root Access เหมาะสำหรับ Containerized Application เริ่มต้น 500 บาท/เดือน

ดู VPS Plans