Bạn chỉ muốn reverse proxy trên VPS truy cập một container web, nhưng Compose đang ghi 8080:80. Khi host có địa chỉ public, cấu hình đó có thể mở dịch vụ ra ngoài thay vì chỉ phục vụ tiến trình trên host.
Bài đối chiếu tài liệu Docker ngày 01/11/2026, trong phạm vi port publishing của bridge network với cấu hình NAT thông thường. Chưa chạy Docker daemon hoặc thử kết nối thật; YAML và cú pháp shell đã được kiểm tra riêng. Không suy rộng mẫu sang host network, Swarm hay mạng có direct routing tùy biến.
1. Tách ba phần của mapping
Trong short syntax, mapping có thể ghi host IP, host port và container port. Với 127.0.0.1:8080:80, ứng dụng trên host kết nối tới 127.0.0.1 cổng 8080, còn tiến trình trong container cần phục vụ ở cổng 80.
Nếu bỏ host IP và chỉ ghi 8080:80, mặc định mapping không còn bị giới hạn vào loopback. Không dùng việc trình duyệt local mở được trang để kết luận máy khác không truy cập được; phép thử đó chỉ kiểm tra một đường kết nối.
2. Sửa phần ports của service đã có
Fragment sau dành cho service web đã có image hoặc build trong project. Nó không phải file Compose hoàn chỉnh và không yêu cầu tải một image minh họa mới.
services:
web:
ports:
- "127.0.0.1:8080:80"
Giữ chuỗi mapping trong dấu nháy để parser YAML không diễn giải các số và dấu hai chấm theo cách khác. Nếu ứng dụng trong container lắng nghe ở cổng khác, thay cổng cuối theo cấu hình thực tế; đổi cổng host không sửa cổng ứng dụng bên trong.
Sửa file không tự thay đổi container đang chạy. Khi triển khai cấu hình mới, dùng quy trình cập nhật service của project và kiểm tra lại mapping thực tế. Bài không thực hiện recreate container hoặc thay đổi một VPS đang chạy.
3. Kiểm tra mapping, rồi kiểm tra đường truy cập
Trong đúng thư mục project, có thể dùng lệnh đọc thông tin sau. web là service name của ví dụ, cần thay bằng service tương ứng nếu project đặt tên khác.
docker compose version
docker version
docker compose port web 80
Đối chiếu host IP và port được báo với mục tiêu cấu hình, không chỉ nhìn số 8080. Đây là lệnh để bạn kiểm tra môi trường thật; bài không có output Docker giả định được gắn nhãn là đã chạy.
Sau khi xác nhận mapping, thử từ host và từ một máy khác theo chính sách truy cập mong muốn. Nếu có reverse proxy public ở trước, truy cập qua proxy vẫn có thể thành công dù port backend bind loopback. Cần phân biệt cổng backend với endpoint do proxy công khai.
4. Expose không đồng nghĩa publish lên host
expose mô tả cổng nội bộ trong cấu hình service; nó không thay thế một host port mapping. Các container cùng network còn có thể giao tiếp qua cổng nội bộ theo cấu hình mạng, nên cũng không nên coi việc bỏ expose là một cơ chế phân quyền giữa chúng.
Nếu chỉ cần service khác trong cùng network truy cập, hãy xem liệu có cần host mapping hay không. Ngược lại, nếu client nằm trên host, cần hiểu cách kết nối tới container trong môi trường đang dùng; không dùng một URL localhost của container khác như thể đó là localhost của host.
Phiên bản và giới hạn cần ghi rõ
Tài liệu Docker lưu ý các bản Engine cũ hơn 28.0.0 có trường hợp host cùng L2 segment truy cập được port publish vào localhost. Đó là lý do cần ghi lại phiên bản thật và kiểm thử đường mạng, thay vì chỉ đọc một dòng YAML rồi khẳng định đã cô lập hoàn toàn.
Loopback mapping cũng không thay thế authentication của ứng dụng. Tiến trình trên host, tunnel, proxy và cấu hình routing có thể tạo các đường truy cập khác. Nếu triển khai có IPv6 hoặc gateway mode đặc biệt, đối chiếu tài liệu đúng chế độ đó và kiểm tra cả đường tương ứng.
Lỗi thường gặp
Nếu host không kết nối được, kiểm tra container có chạy, đúng cổng nội bộ và ứng dụng có lắng nghe trên interface phù hợp bên trong container. Nếu máy ngoài vẫn truy cập được, xác định nó đang tới port nào, qua proxy nào và container nào; đừng chỉ sửa thêm một lớp firewall ngẫu nhiên để che mapping cũ.
Mục tiêu của mẫu là diễn đạt rõ nơi host port được bind. Kết quả cần xác nhận bằng mapping đang chạy và phép thử truy cập thực tế của môi trường, không phải chỉ bằng việc file Compose parse thành công.

