Chuyên mục
Network

Cấu hình NPM làm Reverse Proxy cho Docker container trên cùng máy chủ

NPM (Nginx Proxy Manager) hiện đang là ứng dụng Reverse Proxy mình sử dụng cho các dịch vụ mạng đang cài đặt trong nhà.

Các bước cài đặt Reverse Proxy thông thường khi dùng NPM sẽ như sau:

  1. Tạo Proxy Host mới
  2. Chọn tên miền trong mục Domain Names
  3. Trỏ về địa chỉ IP và Port của máy chủ đang cài đặt dịch vụ.
  4. Cài đặt chứng chỉ SSL.
  5. Xong! Reverse Proxy đã sẵn sàng phục vụ.

Ví dụ như dưới đây là cách tạo Reversey Proxy cho Portainer.

Trong thực tế, đa số các dịch vụ mạng mình sử dụng đều được cài đặt bằng Docker và đều nằm chung trên 1 máy chủ đang chạy Nginx Proxy Manager.

Để tối ưu bảo mật, mình sẽ tận dụng tính năng mạng riêng của Docker để tạo Reverse Proxy cho dịch vụ mà không cần phải mở port kết nối ra bên ngoài. Nhờ đó chặn được hết các kết nối trực tiếp vào dịch vụ thông qua địa chỉ http://<IP-Address>:<Port>. Chỉ có các kết nối bằng tên miền thông qua NPM mới được chuyển hướng đến dịch vụ.

Mình đã từng hướng dẫn phương pháp này trong hướng dẫn cấu hình NPM làm Reverse Proxy cho OpenLiteSpeed + MariaDB + Docker. Bài viết hôm nay sẽ tóm tắt gọn lại để có thể áp dụng cho mọi Docker container khác.

1. Tạo Docker network

Đầu tiên, mình sẽ tạo 1 mạng Docker ảo. Tất cả các dịch vụ mạng được kích hoạt bằng Docker trên cùng máy chủ sẽ được kết nối vào mạng ảo này.

Bằng các thiết lập mạng riêng, chúng ta không cần publish các cổng mạng của dịch vụ ra ngoài. Chỉ duy nhất cổng 80 và 443 của NPM được truy cập từ bên ngoài.

docker network create thuanbuidepchai

2. Cập nhật thông số

Mình sẽ ví dụ bằng cách tạo Reverse Proxy cho Paperless-ngx.

Truy cập vào thư mục cài đặt dịch vụ mạng cần được tạo Reverse Proxy và thay đổi file cấu hình docker-compose.yml.

  • Thêm dấu # vào trước các phần cấu hình port để vô hiệu hoá.
  • Thêm thông số mạng vào dưới cùng như sau
networks:
  default:
    external:
      name: thuanbuidepchai

Sau khi thay đổi, file docker-compose.yml của mình sẽ như dưới đây

version: "2.1"
services:
  paperless-ngx:
    image: lscr.io/linuxserver/paperless-ngx:latest
    container_name: paperless-ngx
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Ho_Chi_Minh
      - PAPERLESS_URL=https://paperless.thuanbui.me
      #- REDIS_URL= #optional
    volumes:
      - ./config:/config
      - ./data:/data
    #ports:
    #  - 8000:8000
    restart: unless-stopped
networks:
  default:
    external:
      name: thuanbuidepchai

Chú ý dòng 5: container_name (paperless-ngx). Chúng ta sẽ cần thông số này cho bước tạo Proxy Host.

3. Cập nhật cấu hình NPM

Truy cập vào thư mục cài NPM và chỉnh lại docker-compose.yml: thêm vào thông số network tương tự như ở trên

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
    volumes:
      - ./data/mysql:/var/lib/mysql

networks:
  default:
    external:
      name: thuanbuidepchai

Kích hoạt lại NPM

docker-compose up -d

Mở trình duyệt web, truy cập vào địa chỉ IP của máy chủ, nếu hiện ra trang web như sau nghĩa là bạn đang đi đúng hướng: NPM đang đóng vai trò làm Reverse Proxy cho máy chủ.

Kiểm tra lại network thuanbuidepchai bằng lệnh docker network inspect thuanbuidepchai, sẽ thấy Nginx Proxy Manager và Paperless-ngx đang cùng kết nối vào mạng này.

 "Containers": {
            "2fd5b65ce7302cf1fce6c68bb7fc78183a31885eab862fc861ce26bc21f94ffc": {
                "Name": "paperless-ngx",
                "EndpointID": "bd6bcfe5c4c426a304e7b16ac1d5fd8a56a004ad7171d28596caae689aefd9e8",
                "MacAddress": "02:42:ac:14:00:05",
                "IPv4Address": "172.20.0.5/16",
                "IPv6Address": ""
            },
            "750a3bbc428746ab647b32af96d5d207db5cb38c8faa312011fb56ae57c9300c": {
                "Name": "nginxproxymanager_app_1",
                "EndpointID": "8fda668e72e00a151a999a40b9cca1e7eb7b93e6ebe2b796715948f5c7cabb8b",
                "MacAddress": "02:42:ac:14:00:04",
                "IPv4Address": "172.20.0.4/16",
                "IPv6Address": ""
            },
            "cce31506dca30c10f2a26926b0e676cc44134a02cd5db5b3c7625708235aee03": {
                "Name": "nginxproxymanager_db_1",
                "EndpointID": "60a1ce468bb72b820da6b030c6dcb1c50ca488f1f381597ba3d9501f8da0143b",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            }
        },

4. Tạo Proxy Host

Mình sẽ cấu hình tên miền document.thuanbui.me để sử dụng cho Paperless-ngx.

Truy cập vào NPM, tạo Proxy Host mới với thông số như sau

  • Domain Names: nhập vào tên miền document.thuanbui.me
  • Scheme: chọn http
  • Forward Hostname / IP: nhập vào paperless-ngx là tên của container đang chạy Paperless-ngx.
  • Forward Port: 8000
Cấu hình Proxy Host cho Paperless-ngx

Do cả NPM và Paparless-ngx đang cùng nằm trong mạng Docker thuanbuidepchai nên có thể kết nối trực tiếp với nhau bằng Hostname và Port. Nhờ vậy chúng ta không cần phải nhập địa chỉ IP của máy chủ vào mục Forward Hostname / IP và cũng không cần phải mở truy cập port 8000 của Paperless-ngx ra bên ngoài.

Bấm tiếp vào tab SSL để tạo chứng chỉ bảo mật nếu cần thiết. Sau đó bấm Save để hoàn tất.

Vậy là xong. Nếu muốn tăng bảo mật, mình có thể chỉnh thêm tính năng Access List để hạn chế truy cập hoặc yêu cầu nhập tài khoản / mật khẩu mỗi khi truy cập vào tên miền.

Chúc bạn thực hiện thành công!

Nếu bài viết của mình mang đến thông tin, kiến thức hữu ích cho bạn, đừng ngại mời mình ly bia để có thêm động lực chia sẻ nhiều hơn nữa. Cám ơn bạn!

Lưu ý: Nếu bạn cần hỗ trợ kỹ thuật, vui lòng gửi câu hỏi trực tiếp ở phần Thảo luận bên dưới, mình sẽ trả lời sớm. Đừng mò vào hỏi trong fanpage Yêu Chạy Bộ, sẽ không có phản hồi đâu!

Bởi Thuận Bùi

Runner at Yêu Chạy Bộ. Blogger at Ba Lô & Dép Lào. Web Developer at TB's Blog.
Follow me: Facebook / Instagram

6 trả lời trong “Cấu hình NPM làm Reverse Proxy cho Docker container trên cùng máy chủ”

Mình đang cài npm lên Rasberypi ở nhà để dùng như bài hướng dẫn này nhưng đang bị một vấn đề là. Router của nhà mạng (trường hợp của mình là Viettel) không cho mở port 80 và 443. Nên khi truy cập domain đã tạo trong npm sẽ không được vì khi truy cập vào domain thì mặc định là domain đó đang chạy trên cổng 80 hoặc 443.
Không biết bạn có cách nào để khắc phục vấn đề này không nhỉ?

Bạn kiểm tra xem Public IP (check ở https://ifconfig.me) và WAN IP trong Router nhà mạng có giống nhau không?

  • Nếu khác nhau nghĩa là mạng nhà bạn đang bị dính CGNAT, phải liên hệ tổng đài Viettel, than phiền rằng bạn không kiểm tra được IP Camera ở nhà, nó sẽ cấu hình lại để mạng ở nhà có Public IP. Hoặc bạn có thể dùng Cloudlfare Tunnel để làm proxy.
  • Nếu giống nhau nghĩa là mạng ở nhà không bị dính CGNAT, bạn cần kiểm tra lại cấu hình trong router.

Trả lời