Ngiêm cấm sử đụng PROXY và VPS vào mục đích trái pháp luật bạn sẽ phải chịu toàn bộ trách nhiệm trước pháp luật khi sử dụng dịch vụ của chúng tôi tks!
Traefik reverse proxy: router, service, middleware cho 2 app

Traefik reverse proxy: router, service, middleware cho 2 app

Chuyên viên Kỹ thuật ProxyVN 09-03-2026 Đang tính... phút đọc

Traefik reverse proxy là lớp đứng trước ứng dụng của anh em, nhận mọi yêu cầu ở một cổng rồi chia về đúng container theo tên miền và đường dẫn. ProxyVN viết bài này theo tài liệu chính thức Traefik 3.7, kèm lab hai ứng dụng, một bẫy độ ưu tiên và công cụ kiểm tra cấu hình đã chạy thật.

Traefik reverse proxy là gì và khác proxy IP thuê ở điểm nào

Traefik là phần mềm mã nguồn mở viết bằng Go, làm việc ở vai trò reverse proxy và bộ cân bằng tải. Nó đứng ở rìa hệ thống của anh em. Người dùng gõ một địa chỉ, yêu cầu chạm vào Traefik trước, rồi Traefik quyết định ứng dụng nào trả lời.

Điểm khác nổi bật so với Nginx hay Caddy là cách nó biết cấu hình. Traefik có thể đọc nhãn (label) gắn trên container Docker và tự dựng đường đi khi container lên hoặc xuống. Anh em không phải sửa một tệp trung tâm mỗi lần thêm ứng dụng.

Khác proxy HTTP hoặc SOCKS5 mà anh em thuê

Trên Proxy.vn, phần lớn bài viết nói về forward proxy: máy của anh em đi ra Internet qua một địa chỉ IP khác. Website đích chỉ thấy IP của proxy. Mục đích là đổi vị trí, chia IP cho nhiều tài khoản, hay thu thập dữ liệu.

Traefik làm ngược lại. Nó đứng phía máy chủ, che các ứng dụng phía sau và nhận yêu cầu từ người ngoài đi vào. Nó không đổi IP của anh em khi vào website khác và không thay được một gói proxy dân cư. Bài forward proxy và reverse proxy so sánh hai hướng này kỹ hơn.

Nếu anh em đã đọc reverse proxy là gì thì phần khái niệm đã đủ. Bài này đi thẳng vào cách Traefik chia việc.

Bài này khác bài Caddy và bài Nginx ở chỗ nào

Trang Proxy.vn đã có bài Caddy reverse proxy về HTTPS tự động và bài cấu hình Nginx làm reverse proxy về khối server và location. Mình không lặp lại hai hướng đó.

Bài này tập trung vào mô hình riêng của Traefik: entrypoint, router, middleware, service, và hai nguồn cấu hình là Docker provider với file provider. Phần lab xoay quanh một câu hỏi mà người mới hay vấp: vì sao router trông đúng mà yêu cầu vẫn rơi vào chỗ khác.

Phạm vi đã thử và chưa thử

Máy mình dùng để soạn bài không có Docker và không có bản phân phối WSL. Mình tải gói Traefik 3.7.16 cho Windows từ trang phát hành chính thức trên GitHub, so mã SHA256 với tệp checksums và hai giá trị khớp nhau. Sau đó môi trường chặn việc chạy tệp thực thi tải về, nên mình xóa gói và không chạy Traefik.

Vì vậy mọi lệnh curl trong phần kiểm tra là kết quả mong đợi theo tài liệu, không phải thứ mình đã thấy trên màn hình. Phần mình chạy thật là bộ kiểm tra cấu hình bằng Python, được mô tả ở mục độ ưu tiên. Mình ghi rõ ranh giới này trong từng đoạn cần thiết.

Router, service, middleware trong Traefik reverse proxy

Trước khi gõ cấu hình, anh em cần nắm năm khái niệm. Ba khái niệm đầu quyết định mọi thứ.

Entrypoint, router, middleware, service nối với nhau thế nào

Provider, entrypoint và upstream khác nhau

Provider, entrypoint và upstream khác nhau

Entrypoint là cổng Traefik lắng nghe, ví dụ cổng 80. Tài liệu entrypoint mô tả tùy chọn address là cổng, và có thể kèm tên máy, theo dạng `[host]:port[/tcp|/udp]`, mặc định là TCP.

Router đọc yêu cầu đến và so với một rule. Trang Router ghi: nếu rule khớp, router được kích hoạt, gọi các middleware rồi chuyển yêu cầu cho service. Middleware là các bước xử lý chen giữa, chạy theo đúng thứ tự khai báo.

Service mô tả nơi gửi yêu cầu tới, thường là danh sách máy chủ phía sau. Với loại loadBalancer, chiến lược mặc định là wrr (luân phiên có trọng số). Chiến lược thứ hai là p2c, tức chọn hai máy ngẫu nhiên rồi lấy máy có ít kết nối đang mở hơn.

Chuỗi đầy đủ là: yêu cầu vào entrypoint, router khớp rule, middleware chạy, service chọn máy chủ.

Provider là gì và nó không phải upstream

Provider là nguồn cấu hình, không phải nơi nhận lưu lượng. Docker provider đọc nhãn container. File provider đọc tệp YAML hoặc TOML. Hai loại này đứng cạnh Kubernetes, Consul, etcd, Redis và nhiều loại khác.

Nhiều người nhầm provider với upstream vì cả hai đều xuất hiện khi nói về Docker. Hãy tách ra như sau. Provider trả lời câu hỏi "Traefik biết cấu hình ở đâu". Upstream, hay server trong service, trả lời câu hỏi "yêu cầu đi tới địa chỉ nào".

Tên có đuôi @provider

Mỗi router, service, middleware sinh ra từ một provider mang đuôi tên provider. Tài liệu có ví dụ `api@internal` cho dashboard của Traefik và `apps-opt@kubernetescrd` cho tùy chọn TLS ở Kubernetes. Với bài này, một middleware khai báo trong tệp sẽ có tên dạng `ten-middleware@file`.

Đuôi này giải quyết một việc thực tế: anh em có thể để middleware dùng chung trong tệp, còn router nằm trên nhãn container, và router gọi middleware bằng tên đầy đủ. Tài liệu file provider cũng gợi ý dùng nó cho phần tái sử dụng như allowlist hay xác thực cơ bản.

Tên router không được chứa ký tự `@`, vì ký tự này dành cho đuôi provider.

Chuẩn bị lab Traefik reverse proxy cho hai ứng dụng

Lab gồm bốn container: Traefik, hai ứng dụng thử và một ứng dụng dự phòng. Ba ứng dụng đều dùng ảnh `traefik/whoami`, một dịch vụ nhỏ trả về thông tin yêu cầu nó nhận được, rất tiện để xem Traefik đã sửa gì trên đường đi.

Yêu cầu và phiên bản

Anh em cần Docker và Docker Compose. Mình chọn Traefik 3.7 vì đây là nhánh có tài liệu hiện hành trên trang chính thức, với bản 3.7.16 phát hành ngày 20/10/2026 trên GitHub. Khi triển khai thật, hãy khóa tag sát phiên bản đã thử thay vì để `latest`.

Ví dụ trong tài liệu hướng dẫn Docker dùng tag cũ hơn là `traefik:v3.4`. Cú pháp router và label mình dùng ở dưới khớp với trang tham chiếu của nhánh 3.7. Nếu anh em đang ở một bản khác, hãy mở trang tham chiếu tương ứng và so từng tùy chọn.

Sơ đồ lab

Traefik lắng nghe ở cổng 80 trong container, ánh xạ ra cổng 8088 trên máy. Hai tên miền thử là `a.lab.localhost` và `b.lab.localhost`. Tên miền đuôi `.localhost` không cần sửa tệp hosts nếu anh em gửi tiêu đề Host bằng curl.

  • `a.lab.localhost` đi về ứng dụng A. Đường dẫn bắt đầu bằng `/api` đi qua middleware cắt tiền tố.
  • `b.lab.localhost` đi về ứng dụng B và bắt buộc đăng nhập cơ bản.
  • Mọi tên con khác của `lab.localhost` rơi vào ứng dụng dự phòng.

Lưu ý khi máy đang bật proxy hệ thống

Nếu máy anh em đang đặt biến `HTTP_PROXY` hoặc proxy hệ thống, curl tới `127.0.0.1` có thể bị đẩy qua proxy đó rồi báo lỗi lạ. Đặt `NO_PROXY=127.0.0.1,localhost` cho phiên làm việc. Cách viết và phạm vi khớp của biến này khác nhau theo công cụ, bài No_proxy là gì đi chi tiết.

Đó cũng là lý do mình gửi tiêu đề Host tới `127.0.0.1` thay vì để máy tự phân giải tên con của `localhost`.

Cấu hình Traefik reverse proxy: entrypoint, provider và quy tắc

Đây là phần cấu hình chính. Mình chia thành tệp Compose và tệp middleware.

Tệp docker-compose.yml

services:
  traefik:
    image: traefik:v3.7
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=lab
      - --providers.file.directory=/etc/traefik/dynamic
      - --entryPoints.web.address=:80
      - --accesslog=true
      - --log.level=INFO
    ports:
      - "8088:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./dynamic:/etc/traefik/dynamic:ro
    networks: [lab]
 
  app-a:
    image: traefik/whoami
    environment:
      - WHOAMI_NAME=App A
    networks: [lab]
    labels:
      - traefik.enable=true
      - traefik.http.services.app-a.loadbalancer.server.port=80
      - traefik.http.routers.a-root.rule=Host(`a.lab.localhost`)
      - traefik.http.routers.a-root.entrypoints=web
      - traefik.http.routers.a-root.service=app-a
      - traefik.http.routers.a-api.rule=Host(`a.lab.localhost`) && PathPrefix(`/api`)
      - traefik.http.routers.a-api.entrypoints=web
      - traefik.http.routers.a-api.middlewares=cat-api@file
      - traefik.http.routers.a-api.service=app-a
 
  app-b:
    image: traefik/whoami
    environment:
      - WHOAMI_NAME=App B
    networks: [lab]
    labels:
      - traefik.enable=true
      - traefik.http.services.app-b.loadbalancer.server.port=80
      - traefik.http.routers.b-root.rule=Host(`b.lab.localhost`)
      - traefik.http.routers.b-root.entrypoints=web
      - traefik.http.routers.b-root.middlewares=auth-lab@file
      - traefik.http.routers.b-root.service=app-b
 
  fallback:
    image: traefik/whoami
    environment:
      - WHOAMI_NAME=Fallback
    networks: [lab]
    labels:
      - traefik.enable=true
      - traefik.http.services.fallback.loadbalancer.server.port=80
      - traefik.http.routers.fallback.rule=HostRegexp(`^.+[.]lab[.]localhost$`)
      - traefik.http.routers.fallback.entrypoints=web
      - traefik.http.routers.fallback.service=fallback
      - traefik.http.routers.fallback.priority=1
 
networks:
  lab: {}

Tệp dynamic/middlewares.yml

http:
  middlewares:
    cat-api:
      stripPrefix:
        prefixes:
          - "/api"
    auth-lab:
      basicAuth:
        users:
          - "lab:$2y$05$THAY_BANG_HASH_TU_HTPASSWD_-nB"

Anh em tạo giá trị thật cho dòng `users` bằng lệnh `htpasswd -nB lab`. Tài liệu BasicAuth yêu cầu mật khẩu băm bằng MD5, SHA1 hoặc BCrypt, và mình chọn BCrypt.

Đọc từng dòng trong lệnh khởi động của Traefik

`--providers.docker=true` bật Docker provider. `--providers.docker.exposedbydefault=false` đổi mặc định. Tài liệu Docker provider ghi rõ: khi đặt false, container không có nhãn `traefik.enable=true` bị bỏ qua. Giá trị mặc định là true, tức là nếu anh em quên dòng này, mọi container trên máy đều có thể bị phơi ra.

`--providers.docker.network=lab` nói mạng nào Traefik dùng để nối tới container. Tùy chọn này có thể bị ghi đè cho từng container bằng nhãn `traefik.docker.network`. Khi container nằm trên nhiều mạng, quên bước này là nguyên nhân thường gặp của lỗi gateway.

`--providers.file.directory=/etc/traefik/dynamic` bật file provider theo thư mục. Tài liệu file provider khuyên dùng `directory` thay cho `filename`, và hai tùy chọn không dùng chung được.

`--entryPoints.web.address=:80` tạo entrypoint tên `web` ở cổng 80 với giao thức TCP mặc định. Tên `web` do anh em đặt, Traefik không cố định tên nào.

Đọc từng nhãn của ứng dụng A

Nhãn `traefik.http.services.app-a.loadbalancer.server.port=80` khai báo service tên `app-a` và cổng bên trong container. Mình ghi rõ cổng thay vì để Traefik tự suy luận, nhất là với ảnh có nhiều cổng.

Router `a-root` khớp mọi yêu cầu có Host bằng `a.lab.localhost`. Router `a-api` khớp cùng Host nhưng chỉ khi đường dẫn bắt đầu bằng `/api`. Hai router cùng trỏ về service `app-a`, khác nhau ở middleware.

Tiêu đề `entrypoints=web` gắn router vào cổng 80. Tài liệu ghi nếu bỏ qua, router HTTP được gắn vào mọi entrypoint. Với lab chỉ có một cổng thì không sao, nhưng khi sau này thêm cổng 443, một router quên dòng này sẽ lộ ra cả HTTP lẫn HTTPS.

Middleware cắt tiền tố và xác thực cơ bản

Middleware stripPrefix bỏ tiền tố khỏi đường dẫn rồi lưu phần đã bỏ vào tiêu đề `X-Forwarded-Prefix`. Tài liệu gợi ý dùng khi ứng dụng phía sau chạy ở đường dẫn gốc nhưng muốn phơi ra dưới một tiền tố. Ở lab, `/api/ping` đi vào ứng dụng A thành `/ping`.

Thứ tự middleware có ý nghĩa. Tài liệu router ghi middleware được áp dụng theo đúng thứ tự khai báo trong danh sách. Nếu anh em xếp xác thực sau một bước ghi lại thông tin, bước ghi sẽ chạy trước khi xác thực chặn yêu cầu. Hãy đặt middleware chặn ở đầu danh sách khi muốn loại yêu cầu xấu sớm.

Middleware basicAuth bắt buộc đăng nhập. Tùy chọn `realm` mặc định là `traefik`, và `removeHeader` mặc định false, nghĩa là tiêu đề Authorization vẫn được chuyển tiếp cho ứng dụng trừ khi anh em đổi.

Vì sao băm mật khẩu để trong tệp, không để trong nhãn

Nếu đặt chuỗi băm vào nhãn Compose, mọi ký tự `$` phải viết đôi thành `$$`, vì Compose đọc `$` như biến. Tài liệu BasicAuth có ghi chú riêng về chuyện này. Để băm trong tệp của file provider thì không cần nhân đôi, ít lỗi hơn.

Tài liệu cũng chỉ ra rằng nếu cả `users` và `usersFile` cùng tồn tại thì chúng được gộp lại, và giá trị trong `users` ưu tiên hơn.

Độ ưu tiên rule trong Traefik reverse proxy và cái bẫy catch-all

Phần này mất nhiều giờ nhất của người mới, và là thứ khiến bài khác với một bản chép tài liệu.

Quy tắc: rule dài hơn thắng

Rule dài hơn thắng: bẫy router dự phòng

Rule dài hơn thắng: bẫy router dự phòng

Trang Rules & Priority viết rõ: để tránh trùng đường dẫn, các tuyến được sắp theo thứ tự giảm dần của độ dài rule. Độ ưu tiên bằng đúng độ dài chuỗi rule. Rule dài nhất có ưu tiên cao nhất. Giá trị `priority: 0` bị bỏ qua và quay về cách sắp theo độ dài. Giá trị âm được hỗ trợ.

Tài liệu minh họa bằng hai router. Router-1 dùng `HostRegexp(`[a-z]+\.traefik\.com`)` và Router-2 dùng `Host(`foobar.traefik.com`)`. Bảng trong tài liệu ghi độ ưu tiên lần lượt 34 và 26, nên Router-1 thắng và mọi yêu cầu tới `foobar.traefik.com` đi nhầm vào Router-1.

Mình đếm lại bằng Python, tính cả dấu huyền và ngoặc: chuỗi thứ nhất dài 34 ký tự, chuỗi thứ hai dài 26. Hai con số trùng với bảng trong tài liệu.

Bẫy trong lab: router dự phòng nuốt các router đúng

Hãy nhìn router `fallback` với rule `HostRegexp(`^.+[.]lab[.]localhost$`)`. Rule này khớp mọi tên con của `lab.localhost`, trong đó có `a.lab.localhost` và `b.lab.localhost`. Nếu anh em không đặt `priority`, độ ưu tiên của nó bằng độ dài rule, là 36 ký tự.

Còn `Host(`a.lab.localhost`)` chỉ dài 23 ký tự. Theo quy tắc trên, router dự phòng dài hơn nên thắng, và ứng dụng A, B không bao giờ nhận được yêu cầu của chúng. Mọi thứ trông đúng trên tệp cấu hình, nhưng kết quả sai.

Cách sửa là đặt `priority=1` cho router dự phòng, đúng như tệp Compose ở trên. Router có độ ưu tiên thấp nhất sẽ chỉ nhận những gì các router khác không nhận.

Bộ kiểm tra tĩnh mình viết và chạy thật

Vì không chạy được Traefik, mình viết một script Python đọc `docker-compose.yml` và các tệp trong `dynamic/`. Script dựng lại danh sách router từ nhãn. Với mỗi router, nó kiểm tra entrypoint, service và middleware có tồn tại không. Sau đó nó tính độ ưu tiên theo độ dài rule và cảnh báo khi một router có `HostRegexp` hay `Host(`*`)` vượt lên trên router `Host` cụ thể mà không đặt priority tay.

Mình chạy script trên hai bản cấu hình. Bản đúng là tệp ở trên. Bản sai có ba lỗi cố ý: middleware `auth-lap` gõ nhầm, entrypoint `websecure` chưa khai báo, và router dự phòng thiếu priority.

Bảng: Bộ kiểm tra tĩnh mình viết và chạy thật

Bản

Router (độ ưu tiên tính ra)

Kết quả script

Đúng

a-api 45, b-root 23, a-root 23, fallback 1 (đặt tay)

Không có vấn đề

Sai

a-api 45, fallback 36, b-root 23, a-root 23

4 cảnh báo, thoát mã 1

Bốn cảnh báo của bản sai là: middleware `auth-lap@file` không tồn tại; entrypoint `websecure` không được khai báo; router `fallback` chèn lên `a-root`; router `fallback` chèn lên `b-root`.

Cần nói rõ giới hạn. Script này phản ánh quy tắc trong tài liệu, nó không phải Traefik và không chứng minh Traefik 3.7 nhận cấu hình mà không lỗi. Giá trị của nó là bắt lỗi tham chiếu và bẫy độ ưu tiên trước khi anh em khởi động container.

Khi hai router cùng độ dài

Trong lab, `a-root` và `b-root` cùng dài 23 ký tự nhưng khác Host nên không bao giờ cùng khớp một yêu cầu. Nếu hai rule cùng dài và cùng khớp, tài liệu chỉ nêu một trường hợp: hai route cùng độ ưu tiên đến từ hai provider khác nhau thì tùy chọn `providers.precedence` quyết định, provider nào đứng trước thì thắng. Trường hợp cùng provider, mình không có tài liệu để nói chắc nên khuyên đặt priority tay.

Kiểm tra Traefik reverse proxy bằng curl, log và bộ kiểm tra tĩnh

Phần này là kịch bản để anh em chạy khi đã có Docker. Cột "mong đợi" dựa vào tài liệu, mình chưa thấy tận mắt.

Bước khởi động

Chạy `docker compose up -d` trong thư mục có tệp Compose và thư mục `dynamic`. Xem log bằng `docker compose logs traefik`. Nếu một router tham chiếu middleware không tồn tại hoặc entrypoint lạ, log là nơi đầu tiên báo lỗi.

Tài liệu API và dashboard mô tả dashboard hiển thị các tuyến đang chạy, nhưng cũng cảnh báo bật API và dashboard trong sản xuất là không nên vì nó phơi toàn bộ cấu hình. Với lab này mình không bật, và dùng log cùng curl.

Bộ ca thử

Sáu ca thử curl và router tương ứng

Sáu ca thử curl và router tương ứng

export NO_PROXY=127.0.0.1,localhost
curl -s -H "Host: a.lab.localhost" http://127.0.0.1:8088/
curl -s -H "Host: a.lab.localhost" http://127.0.0.1:8088/api/ping
curl -s -o /dev/null -w "%{http_code}\n" -H "Host: b.lab.localhost" http://127.0.0.1:8088/
curl -s -o /dev/null -w "%{http_code}\n" -u lab:MAT_KHAU -H "Host: b.lab.localhost" http://127.0.0.1:8088/
curl -s -H "Host: c.lab.localhost" http://127.0.0.1:8088/
curl -s -o /dev/null -w "%{http_code}\n" -H "Host: khac.example" http://127.0.0.1:8088/
Bảng: Bộ ca thử

Ca

Router mong đợi

Kết quả mong đợi

A, đường dẫn `/`

a-root

Phản hồi từ ứng dụng A

A, đường dẫn `/api/ping`

a-api

Ứng dụng A thấy đường dẫn `/ping`, có tiêu đề X-Forwarded-Prefix: /api

B, không đăng nhập

b-root

401 từ middleware xác thực

B, có đăng nhập

b-root

200 từ ứng dụng B

c.lab.localhost

fallback

Phản hồi từ ứng dụng dự phòng

Host lạ

không có

Không router nào khớp

Ca cuối là ca âm. Theo cách hoạt động thường gặp, khi không router nào khớp thì Traefik trả 404, còn khi router khớp nhưng máy chủ phía sau không trả lời thì anh em thường thấy 502 hoặc 504. Mình chưa kiểm chứng điều này trên máy, nên anh em ghi lại mã thật ở lần chạy đầu. Hai bài 502 Bad Gateway và 504 Gateway Timeout giúp phân biệt hai mã này.

Đọc phản hồi của whoami

Ứng dụng `traefik/whoami` trả về tên máy, các địa chỉ IP, dòng yêu cầu và toàn bộ tiêu đề nó nhận được. Ví dụ trong hướng dẫn mở dịch vụ bằng Docker của Traefik cho thấy các tiêu đề `X-Forwarded-For`, `X-Forwarded-Host`, `X-Forwarded-Port`, `X-Forwarded-Proto`, `X-Forwarded-Server` và `X-Real-Ip` do Traefik thêm vào.

Đó là lý do ứng dụng phía sau không thấy IP của người dùng mà thấy IP của Traefik trong `RemoteAddr`. Muốn lấy IP thật, ứng dụng phải đọc tiêu đề. Bài X-Forwarded-For là gì giải thích tiêu đề này, và bài Proxy Protocol là cách khác khi đi qua lớp TCP.

Khi tiêu đề chuyển tiếp không đáng tin

Entrypoint có nhóm tùy chọn `forwardedHeaders`, trong đó có `trustedIPs` và `insecure`. Tài liệu dùng chúng để quyết định Traefik có tin tiêu đề X-Forwarded-* do phía trước gửi tới hay không. Nếu Traefik đứng sau một lớp proxy khác, hãy khai IP của lớp đó, đừng bật `insecure`.

Ghi log riêng cho từng router

Router có nhóm tùy chọn `observability` cho phép bật hay tắt metrics, access log và tracing riêng cho từng tuyến, mặc định kế thừa từ entrypoint. Với lab, mình để mặc định. Khi hệ thống lớn dần, anh em có thể tắt access log của tuyến kiểm tra sức khỏe để log đỡ nhiễu, và giữ đầy đủ ở các tuyến người dùng.

Chứng minh hành vi bằng log

Bật `--accesslog=true` như trong tệp Compose. Tài liệu cho phép chọn định dạng `json` và đường dẫn tệp qua `filePath`. Khi chạy các ca ở trên, hãy đối chiếu mỗi dòng log với router mà anh em mong đợi. Nếu ca c.lab.localhost không ra router dự phòng, hãy kiểm tra lại độ ưu tiên trước khi nghi ngờ Docker.

Đưa Traefik reverse proxy vào hệ thống thật: hoàn nguyên, giới hạn, bảo mật

Checklist trước khi đưa Traefik vào hệ thống thật

Checklist trước khi đưa Traefik vào hệ thống thật

Lab chạy được chưa đủ để đưa vào sản xuất. Phần này gom các điều cần cân nhắc từ chính tài liệu.

Hoàn nguyên sau khi thử

Chạy `docker compose down` để gỡ container và mạng. Nếu anh em chỉ muốn quay lại cấu hình trước, sửa lại tệp trong `dynamic/`. File provider có tùy chọn `watch` mặc định true, nên Traefik tự nạp lại khi tệp đổi, và tùy chọn `providersThrottleDuration` mặc định 2 giây nên các thay đổi dồn dập chỉ có thay đổi cuối được tính.

Nhãn Docker thì đổi bằng cách sửa Compose và chạy lại `docker compose up -d`. Container có nhãn mới được Traefik nhận lại.

Bẫy của file provider khi mount thư mục

Tài liệu file provider cảnh báo: Traefik dựa vào thông báo hệ thống tệp (fsnotify). Khi dùng bind mount trong Docker mà đổi tên tệp trên máy chủ, liên kết có thể đứt và Traefik không nhận thay đổi. Khuyến nghị là gắn cả thư mục cha và đặt `directory` trỏ vào thư mục đó, đúng cách lab này làm.

Quyền đọc socket Docker

Lab mount `/var/run/docker.sock` ở chế độ chỉ đọc, giống ví dụ trong tài liệu. Cờ chỉ đọc không biến socket thành vô hại, vì từ socket Docker có thể suy ra rất nhiều thông tin về máy. Nếu máy chủ chạy nhiều dịch vụ nhạy cảm, hãy tìm hiểu cách giới hạn quyền của Traefik với Docker trước khi triển khai.

Bài proxy cho Docker nói về hướng ngược lại: đặt proxy cho chính Docker daemon, một việc khác.

Giới hạn tài nguyên

Mình không đo mức dùng bộ nhớ hay CPU của Traefik nên không đưa con số nào. Khi triển khai thật, hãy đặt giới hạn bộ nhớ trong Compose rồi đo bằng tải thật của anh em. Phần nhật ký truy cập cũng ăn ổ đĩa theo lưu lượng, nên cần xoay vòng tệp log.

TLS và HTTPS

Lab dừng ở HTTP. Hướng dẫn Docker nói trên chỉ cách thêm entrypoint `websecure`, bật `tls=true` trên router và dùng chứng chỉ tự ký cho thử nghiệm cục bộ. Router có thể dùng `certResolver` để xin chứng chỉ tự động. Nếu truy cập nhầm cổng HTTP bằng `https://`, trình duyệt sẽ báo lỗi mô tả ở bài SSL_ERROR_RX_RECORD_TOO_LONG.

Một điểm tài liệu nhấn mạnh: tùy chọn TLS gắn theo tên máy trong rule, không theo router. Mọi router phục vụ cùng một tên máy trên cùng entrypoint phải dùng cùng một tùy chọn TLS.

Khi nào Traefik chưa phải lựa chọn tốt

Nếu anh em chỉ có một ứng dụng và một tên miền, Traefik không mang lại lợi ích rõ so với Caddy hoặc Nginx. Lợi thế của nó lộ ra khi có nhiều container thay đổi liên tục. Với một cổng cho nhiều dịch vụ có xác thực, giới hạn tốc độ và định tuyến theo khóa API, bài API gateway là gì giúp phân biệt vai trò gateway với reverse proxy thuần.

Khi cần giữ phiên người dùng trên cùng một máy phía sau, xem thêm bài sticky session, vì service loadBalancer của Traefik có cơ chế riêng cho việc này.

Câu hỏi thường gặp về Traefik reverse proxy

Traefik reverse proxy có cần Docker không. Không. File provider đọc tệp YAML hoặc TOML, nên Traefik làm việc được với các dịch vụ chạy trực tiếp trên máy. Trang phát hành có sẵn gói cho Windows. Docker chỉ là một provider, không phải điều kiện.

Traefik có đổi IP ra ngoài như proxy thuê không. Không. Nó chỉ nhận yêu cầu từ ngoài vào ứng dụng của anh em. Muốn đổi IP khi truy cập website khác, anh em cần forward proxy.

Rule Host phân biệt chữ hoa chữ thường không. Tài liệu ghi các bộ khớp Host so với tên máy đã chuyển sang chữ thường. Nếu dùng regexp, hãy thêm `(?i)` khi cần không phân biệt.

Tên miền có dấu tiếng Việt thì sao. Tài liệu nói bộ khớp Host không hỗ trợ ký tự ngoài ASCII, nên phải dùng dạng punycode theo RFC 3492.

Wildcard của Host khớp bao nhiêu cấp. Dấu sao ở đầu như `*.example.com` khớp đúng một cấp tên con, ví dụ `foo.example.com`, và không khớp `foo.bar.example.com` hay chính `example.com`. Trường hợp riêng, `Host(`*`)` khớp mọi yêu cầu.

Tôi nên đặt priority bằng số nào. Chỉ cần đủ để xếp đúng thứ tự tương đối. Router dự phòng nên có số thấp nhất, như 1. Router quản trị cần ép lên trước thì mới đặt số cao. Giá trị tối đa cho người dùng nhỏ hơn MaxInt64 trừ 1000 trên nền 64 bit.

Vì sao router có đủ rule mà vẫn không chạy. Ba lý do hay gặp: container thiếu nhãn `traefik.enable=true` khi `exposedbydefault=false`, container nằm ở mạng khác với mạng Traefik dùng, và tên middleware thiếu đuôi `@file`. Bộ kiểm tra tĩnh ở trên bắt được lỗi tên middleware và entrypoint.

Có dùng Traefik thay Nginx Proxy Manager được không. Hai công cụ giải cùng bài toán theo hai cách. Bài Nginx Proxy Manager dùng giao diện web. Traefik thiên về khai báo bằng nhãn và tệp, không cần bấm chuột.

Cần thêm IP cho máy khách, anh em có thể mua proxy tại ProxyVN, có proxy dân cư tĩnh Viettel, VNPT, FPT, datacenter Việt Nam và proxy xoay, hỗ trợ HTTP và SOCKS5 với tài khoản user và mật khẩu.

Traefik reverse proxy: những điều cần nhớ

Traefik reverse proxy chia yêu cầu qua chuỗi entrypoint, router, middleware, service, và rule dài hơn thắng nếu không đặt priority. Router dự phòng phải có priority thấp, tên middleware cần đuôi provider. Cần proxy IP ổn định cho việc khác, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam cho Traefik reverse proxy.

TIN TỨC LIÊN QUAN