From Nginx to Traefik

Traefik คืออะไร

จากคนที่เคยใช้ Nginx มาก่อนก็จะรู้ว่า Nginx เป็น Reverse Proxy ที่ทำหน้าที่เป็นฉากหน้าหรือสื่อกลางระหว่างเซอร์เวอร์และผู้ใช้งาน โดย Reverse Proxy จะรับ request เข้ามา และทำการตัดสินใจเพื่อส่งต่อไปยังเซอร์เวอร์ที่ถูกต้อง เช่นเดียวกัน Traefik เองก็เป็น Reverse Proxy เหมือนกับ Nginx นั้นเอง

Traefik

Why need to switch?

ต้องบอกเลยว่าเดี๋ยวนี้การติดตั้งบริการใดๆ บน server ด้วย container มันง่ายกว่าการติดตั้งแบบ manual ทีละตัว ไหนจะมาจัดการ config ของ ngix อีกทั้งในเรื่อง routing หรือ SSL

การเปลี่ยนมาใช้ Traefik ที่มี dynamic service discovery ผ่าน docker socket ทำให้การติดตั้งเว็บหรือบริการใหม่ๆ ง่ายขึ้น เพิ่มเติม config อีกเล็กน้อยเพื่อกำหนด domain ที่จะเข้าถึงและ SSL เพียงเท่านี้เว็บหรือบริการก็พร้อมใช้งานทันที

Migration

ก่อนอื่นเริ่มติดตั้ง Traefik กันก่อน โดยเราจะรันผ่าน docker compose

mkdir traefik
vim traefik/docker-compose.yml
services:
  traefik:
    image: traefik:v3.2
    container_name: traefik
    restart: unless-stopped
    networks:
      - traefik
    ports:
      - 443:443 # HTTPS entryPoints
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - traefik-certs:/certs
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.karn.work`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.tls.certresolver=letencrypt"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"

volumes:
  traefik-certs

networks:
  traefik:
    external: true
api:
  dashboard: true
  insecure: false
  debug: false
entrypoints:
  websecure:
    address: ":443"
http:
  middlewares:
    auth:
      basicAuth:
        users:
          - "user:$$2y$05$zIVlMoMvERrq/jOJA4xujO/Ptd3pjanTDbN/firxdq23MahQU7U02" # command to generate an encrypted password is shown below.
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
certificatesResolvers:
  letencrypt:
    acme:
      email: karn@hey.com
      storage: /certs/acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      httpChallenge:
        entryPoint: web

สำหรับการสร้าง user และ encrypted password สามารถทำได้ผ่านคำสั่ง

$ echo $(htpasswd -nbB user "test") | sed -e s/\\$/\\$\\$/
# user:$$2y$05$zIVlMoMvERrq/jOJA4xujO/Ptd3pjanTDbN/firxdq23MahQU7U02

อย่าลืมเปลี่ยนโดเมนที่จะใช้งานใน traefik.http.routers.dashboard.rule ให้ถูกต้องด้วยหละ จากนั้นก็มาเริ่ม start เจ้า Traefik กันเลย

docker compose up -d

ทดลองเข้าไปยัง Dashboard ผ่านโดเมนที่กำหนด สำหรับของผมเองจะเข้าผ่าน https://traefik.karn.work จะเห็นได้ว่าหน้า Dashboard ของ Traefik จะถูกแสดง prompt ขึ้นมาถาม username/password อีกทั้งยังวิ่งผ่าน HTTPS แล้วด้วย

Basic Authentication

Traefik Dashboard

ต่อไปเรามาเพิ่ม blog เข้าไปให้ Traefik รู้จักกัน โดยผมจะใช้ blog ของตัวเองนี่แหละ ที่สร้างด้วย Brigdetown มาทำเป็น container และทำการระบุ Labels ใน docker-compose.yaml ให้ Traefik รู้จัก

service:
  web:
    build:
      context: .
    ports:
      - 4000:4000
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.web.rule=Host(`karn.work`)"
      - "traefik.http.routers.web.entrypoints=websecure"
      - "traefik.http.routers.web.tls=true"
      - "traefik.http.rotuers.web.tls=certresolver=letcencrypt"
      - "traefik.http.services.web.loadbalancer.server.port=4000"
    networks:
      - traefik

networks:
  traefik:
    external: true

จากนั้นก็รัน service และลองเข้าเว็บไซด์ดู

Blog

References