Chuyên mục
Network Self Hosting

Nginx Proxy Manager – Quản lý Reverse Proxy trực quan bằng giao diện Web UI

Khi thiết lập các dịch vụ web trong homelab, một rắc rối mình phải giải quyết là “Làm sao có thể truy cập được các dịch vụ này từ Internet tối ưu nhất?

Ví dụ: Homelab của mình đang có 1 website WordPress trên máy ảo với địa chỉ IP 192.168.0.60 và 1 website Odoo trên máy ảo với địa chỉ 192.168.0.70.

Mình muốn truy cập đến hai dịch vụ này từ bên ngoài thông qua 2 tên miền sau:

  • WordPress: truy cập qua tên miền https://test1.thuanbui.me
  • Odoo: truy cập qua tên miền https://test2.thuanbui.me

Cả hai tên miền đều yêu cầu kết nối qua giao thức HTTPS, sử dụng cổng 443 trên 2 IP LAN khác nhau. Trong khi đó Router mạng chỉ có thể cấu hình NAT port 443 từ WAN vào 1 địa chỉ IP nội bộ trong mạng LAN. Giờ phải làm sao?

Cách duy nhất để giải quyết vấn đề này là sử dụng Reverse Proxy để làm trung gian nhận kết nối từ máy khách (client) và chuyển tiếp đến máy chủ tương ứng.

Reverse Proxy là gì?
Trong hệ thống mạng thông tin, reverse proxy là một loại proxy server trung gian giữa một máy chủ và các clients gửi tới các yêu cầu. Nó kiểm soát yêu cầu của các clients, nếu hợp lệ, sẽ luân chuyển đến các servers thích ứng. (Wikipedia)

Mình đã thử qua nhiều giải pháp Reverse Proxy khác nhau: Apache, Nginx, HAProxy, Treafik,… nhưng đa số đều phức tạp và khó sử dụng. Chỉ đến khi tìm ra Nginx Proxy Manager, việc quản lý Reverse Proxy trong Homelab của mình mới trở nên đơn giản và tiện lợi hơn hẳn.

Bài viết này sẽ hướng dẫn bạn cách cài đặt và cấu hình Nginx Proxy Manager để quản lý các dịch vụ mạng trong Homelab tiện lợi hơn.

Dưới đây là sơ đồ kết nối hệ thống mạng LAN mình sử dụng cho bài viết này.

I. Giới thiệu Nginx Proxy Manager

Nginx Proxy Manager (NPM) là một ứng dụng chạy trên nền Docker giúp bạn dễ dàng cấu hình Reverse Proxy cho các dịch vụ mạng cài đặt trong homelab hoặc VPS. Nó còn được tích hợp công cụ tạo chứng chỉ SSL miễn phí từ Let’s Encrypt.

Tính năng

  • Giao diện quản lý bảo mật và thân thiện dựa trên Tabler
  • Dễ dàng cấu hình chuyển tiếp, chuyển hướng tên miền mà không cần biết gì về cách cấu hình Nginx.
  • Tạo chứng chỉ SSL miễn phí từ Let’s Encrypt
  • Tạo danh sách truy cập và thiết lập xác thực HTTP bảo mật cho máy chủ
  • Cấu hình Nginx nâng cao tuỳ theo nhu cầu sử dụng
  • Quản lý tài khoản, phân quyền và lịch sử làm việc.

II. Chuẩn bị hệ thống

Để sử dụng Nginx Proxy Manager, bạn cần phải chuẩn bị các bước sau

  1. Truy cập vào Router mạng chính trong nhà và tìm đến khu vực thiết lập NAT / Port Forwarding
  2. Cấu hình NAT Port Forwarding trên Router cho hai cổng 80 (HTTP) và 443 (HTTPS) chuyển hướng đến máy tính / máy ảo cài Nginx Proxy Manager.
  3. Thiết lập Dynamic DNS cho những tên miền bạn cần sử dụng để truy cập vào mạng nội bộ ở nhà.
  4. Nginx Proxy Manager sẽ làm trung gian chuyển tiếp các yêu cầu từ client đến các dịch vụ web trong mạng nội bộ.

III. Cài đặt Nginx Proxy Manager

1. Cài đặt Docker và Docker-Compose

Tham khảo lại bài viết sau để biết cách cài đặt Docker & Docker-Compose lên máy

2. Tạo file docker-compose.yml

Đăng nhập SSH vào máy và tạo file docker-compose.yml cho Nginx Proxy Manager

mkdir nginxproxymanager
cd nginxproxymanager
nano docker-compose.ymlCode language: Bash (bash)

Nhập vào nội dung sau và lưu lại.

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP

    # Uncomment the next line if you uncomment anything in the section
    # environment:
      # Uncomment this if you want to change the location of
      # the SQLite DB file within the container
      # DB_SQLITE_FILE: "/data/database.sqlite"

      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencryptCode language: YAML (yaml)

Nếu bạn muốn sử dụng Mysql thay cho Sqlite, sử dụng nội dung sau

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
    environment:
      # Mysql/Maria connection parameters:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
    volumes:
      - ./mysql:/var/lib/mysqlCode language: YAML (yaml)

3. Kích hoạt Nginx Proxy Manager

docker-compose up -d

Nếu không quen làm việc trên giao diện dùng lệnh, bạn có thể sử dụng chức năng Stack của Portainer để thay thế cho bước 2 và 3.

4. Truy cập WebUI

Truy cập vào giao diện Web UI của Nginx Proxy Manager theo địa chỉ

http://127.0.0.1:81Code language: JavaScript (javascript)

Nếu bạn cài đặt trên máy ảo, hãy truy cập Web UI theo địa chỉ IP của máy

http://<IP-Address>:81Code language: JavaScript (javascript)

Đăng nhập bằng tài khoản Admin mặc định dưới đây

Email:    admin@example.com
Password: changemeCode language: CSS (css)
Khi đăng nhập lần đầu tiên, Nginx Proxy Manager sẽ yêu cầu bạn cập nhật thông tin Admin: Tên, Nickname, Email và Password.

IV. Tạo Proxy Host

Mình sẽ tạo 2 Proxy Host cho 2 dịch vụ web WordPress và Odoo như đã đề cập ở đầu bài viết

  • Tên miền https://test1.thuanbui.me chuyển tiếp vào WordPress trên IP LAN 192.168.0.60
  • Tên miền https://test2.thuaunbui.me chuyển tiếp vào Odoo trên IP LAN 192.168.0.70

1. Tạo Proxy Host cho WordPress kèm chứng chỉ SSL

Bấm vào Proxy Hosts
Bấm vào Add Proxy Host để tạo mới
Tab Details: nhập vào thông tin tương ứng rồi chuyển qua tab SSL để cấu hình tiếp
Mục SSL Certificate: chọn Request a new SSL Certificate, chọn thêm Force SSL, HTTP/2 Support, Điền email, chọn I Agree to … và bấm Save

Chờ vài phút để hệ thống xác thực và tạo chứng chỉ SSL cho tên miền. Nếu bị báo lỗi Internal Error, bạn cần kiểm tra lại các thông số sau:

  • Tên miền đã trỏ về đúng Public IP của mạng nhà chưa?
  • Trên Router đã chỉnh NAT Port 80 và 443 về IP LAN của Nginx Proxy Manager chưa?
Tên miền được chỉnh CNAME trỏ về DDNS của Mikrotik

Nếu xác thực SSL thành công, bạn sẽ thấy cột SSL có ghi thêm chữ Let’s Encrypt.

Tạo Proxy Host kèm chứng chỉ SSL thành công

Mình đã có thể truy cập thành công vào WordPress từ địa chỉ https://test1.thuanbui.me

Truy cập vào WordPress thành công theo tên miền

Chú ý: Hãy thử truy cập vào tên miền bằng 4G trên điện thoại để kiểm tra dịch vụ có hoạt động ổn chưa. Nếu bạn dùng mạng ở nhà truy cập vào dịch vụ thông qua tên miền đã dùng để thiết lập Proxy Host, nhiều khả năng sẽ bị báo lỗi không truy cập được. Lý do: Router chưa được cấu hình Hairpin NAT.

Để có thể truy cập vào tên miền khi dùng mạng ở nhà, bạn cần thiết lập thêm Hairpin NAT như hướng dẫn dưới đây:

2. Tạo Proxy Host cho Odoo kèm chứng chỉ SSL (DNS Challenge)

Mình sẽ tạo thêm 1 Proxy Host nữa cho Odoo. Nhưng lần này sẽ chuyển qua xác thực SSL bằng cách sử dụng DNS Challenge, thay vì phải trỏ tên miền về IP của máy.

Với cách xác thực SSL bằng DNS Challenge, mình chưa cần phải trỏ tên miền về Public IP ngay lập tức. Thay vào đó, Let’s Encrypt sẽ xác thực tên miền thông qua bản ghi TXT Record được thiết lập trên DNS.

Tạo Proxy Host mới cho tên miền test.thuanbui.me

Do Odoo hoạt động trên cổng 8069 nên mình sẽ nhập 8069 vào ô Forward Port.

Bấm tiếp vào tab SSL để tạo chứng chỉ SSL cho tên miền test2.thuanbui.me.

  • Bấm chọn Use a DNS Challenge để sử dụng cách xác nhận tên miền thông qua DNS.
  • DNS Provider: chọn Cloudflare
  • Credentials File Content: nhập vào API Token của Cloudflare.

Bạn cần tạo API Token mới trên Cloudflare để điền vào ô Credentials File Content: xem hướng dẫn ở đây.

Xác thực SSL bằng DNS Challenge

Bấm Save. Chờ khoảng 1-2 phút để NPM xác thực tên miền thông qua Cloudflare và tạo Proxy Host.

Tạo thành công Proxy Host mới cho tên miền https://test2.thuanbui.me

Sau khi đã tạo Proxy Host thành công, bạn cần điều chỉnh lại cho tên miền trỏ về đúng địa chỉ Public IP ở nhà. Odoo đã có thể truy cập thông qua tên miền mới https://test2.thuanbui.me, không cần phải gõ dài dòng https://192.168.0.70:8069 nữa.

Truy cập vào Odoo bằng địa chỉ https://test2.thuanbui.me

V. Tổng kết

Mình vừa mới giới thiệu về Nginx Proxy Manager – ứng dụng giúp quản lý Reverse Proxy đơn giản và hiệu quả dành cho các ứng dụng web trong Homelab. Bên cạnh tính năng tạo Proxy Host mình đã chia sẻ ở trên, NPM còn nhiều chức năng khác như tạo Redirection Hosts, Stream, 404 Hosts,… dành cho bạn khám phá.

Chúc bạn cài đặt và cấu hình Nginx Proxy Manager thành công và quản lý Homelab hiệu quả hơn!

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

40 trả lời trong “Nginx Proxy Manager – Quản lý Reverse Proxy trực quan bằng giao diện Web UI”

Hello, Mình cài nginx proxy manager lên docker nhưng không tài nào add domain và subdomain vào như hướng dẫn của bạn, mình cũng search nhiều diễn đàn khác nhưng ko fix dc.
Lỗi khi add proxy host là internal error (làm như hướng dẫn của bạn, đã trỏ domain về public ip, đã port foward cho port 80 với 443), sau đó mình thử add ssl cert trước rồi mới dùng cert đó để add proxy nhưng trong khi test ssl thì nó hiện lên là domain của mình chưa trỏ vào ip mà NPM đang chạy (mặc dù mình đã trỏ rồi).
Một số info và nguyên nhân mà mình nghĩ có thể dẫn đến lỗi này:
1. Mình chuyển port mặc định để login router từ 80 sang 8080, cài này để chạy v2ray nên mình đổi từ khá lâu. Ko biết như vậy thì có xung độ gì với NPM ko?
2. Mình cài NPM trên armbian box ở local IP 192.168.1.12, khi trỏ domain về public ip, mình có cần phải làm thêm bước nào nữa không để dùng domain đó cho ip 192.168.1.12.
3. Domain mình dùng là của Freenom, nhưng đã chuyển về cho cloudflare quản lý (Đã chuyển name server).
4.Cũng domain đó mình trỏ về vps ip thì dùng hoàn toàn bình thường, có thể cấp subdomain cho ip và nhiều port khác nhau. Giống như mục số 2, có khi nào NPM phải cài ở cấp router (192.168.1.1) mới dc hay sao ta?
Nhờ mang xem xem có cách nào giải quyết vụ này không nha.
Mình cảm ơn.

Theo như những gì bạn chia sẻ thì nhiều khả năng là bạn chưa thiết lập forward port trên router đúng để nó chuyển hướng cổng 80 và 443 về IP của Armbian Box (192.168.1.12). Bạn nên kiểm tra lại từng bước như sau
1. Tạo A Record trên Cloudflare trỏ Domain về địa chỉ Public IP của Router. Sau đó vô https://ping.eu/nslookup/ nhập domain vô xem nó có hiện ra đúng IP ở nhà không.
2. Trên Router, thiết lập NAT (Port Forwarding) cho 2 cổng 80 và 443 về IP 192.168.1.12 của Armbian Box.
3. Add SSL Cert trên NPM. Nếu vẫn bị dính lỗi domain chưa trỏ vào IP thì xem lại bước 1 và 2
4. Add Proxy Host sử dụng SSL Cert đã tạo.

Có một chú ý là lúc add subdomain phải đợi 1 vài phút để nó update thông tin. Nhiều trường hợp mới add xong thì vào test trên NPM liền và thấy lỗi lại tưởng cấu hình sai nên quay ra cấu hình lại…. Làm làm một hồi tự nhiên nó chạy được lại chả hiểu tại sao lúc nãy cũng làm vậy mà nó ko chạy.

À, một số app mình đã cài trên box và vps để bạn check xem có xung đột gì ko mà vps dc, trong khi box ko được giúp mình:
1. Box:
– Openwrt: login theo local ip do mình set, chưa dùng vào việc gì (mình đang nghiên cứu dùng openwrt này quay pppoe để dùng làm router chính cấp internet kiểu như rasperry pi4 chạy openwrt, tiết kiệm được kha khá chi phí).
– Watchtower.
– mstream: 3030.
– Wireguard-easy:51821.
– NPN+maria
2. VPS: Chỉ có Wirehole-ui, NPM+maria.
Thanks bạn.

Cám ơn bạn vì bài viết rất hay. Mình đã áp dụng okie. Cho mình hỏi có cách nào theo dõi các thông số, starts trên npm không ta, dạng như số lượt truy cập vào proxy, redirect, 404, còn hiện tại trên npm hình như chỉ add host rồi để đó thôi chứ ko follow dc thông số thì phải

Mình đang dùng vps của oracle, đã cài đặt thành công NPM, portainer và Wireguard theo hướng dẫn của bạn, dùng rất ok. Mình có 1 domain và đã điều hướng thành công subdomain cho portainer và wireguard rồi nhưng wordpress thì lại không được. page wordpress của mình vào qua ip thì đc nhưng dùng tên miền thì báo lỗi ERR_SSL_PROTOCOL_ERROR, address bar hiển thị dạng tên miền : port. Mong bạn giúp đỡ

Bạn cài đặt WordPress bằng cách nào? Đã thiết lập Reverse Proxy trong NPM cho WordPress chưa?
Không biết chính xác cách cấu hình thì không biết sao để giúp hết.

Bác cho em hỏi chút. Nếu trường hợp 2 địa chỉ IP cùng sử dụng cổng 80 có được không ạ, nếu được thì mở port trên mikrotik và cấu hình nginx-proxy-manager thế nào?.
Trường hợp không được thì có cách nào giải quyết không ạ. Cảm ơn bác

Mikrotik bạn mở cổng 80 và 443 trỏ đến máy ảo đang chạy Nginx Proxy Manager. Sau đó cấu hình trong Nginx Proxy Manager để trỏ tên miền về từng IP tương ứng.

Nếu trước đó em đã chạy 1 web WordPress trong hướng dẫn của anh bằng portainer và giờ thì làm sao em có thể chạy nginx proxy này thêm được nữa.
Hiện tại thì em chỉ chạy 1 trong 2 wordpress hoặc ngix nếu bật cái này thì ko start cái kia được.
và làm sao giờ em có thể chạy nhiều web wordpress (em muốn thông qua portainer hoặc dạng vậy để dễ quản lý)

Nếu cần chạy Nginx Proxy Manager (NPM) chung với WordPress thì bạn cần ưu tiên port 80 và 443 cho NPM, còn bên WordPress thì cần đổi thông số ports “80:80” thành port khác, ví dụ “8888:80”. Sau đó vô NPM tạo Proxy Host cho nó chuyển hướng tên miền về port 8888 để truy cập vào WordPress.
Còn nếu muốn chạy nhiều web WordPress thì nên dẹp NPM, và cài đặt theo hướng dẫn này https://thuanbui.me/wordpress-mariadb-openlitespeed-phpmyadmin-docker-compose/

Cảm ơn a rất nhiều ạ. E sẽ dùng cái OLS của a, đúng là cái đó xịn hơn nhiều.
Em hỏi a thêm 1 chút, em muốn:
“kết hợp v2ray xui vào server của em để xài 4G”
hiện tại em đã cài portainer và chạy web, treafik, NPM ok hết, nhưng mà cái v2ray xui nó lại ko được, phải tắt hết những cái nào đã chạy mà liên quan port 80.
E xài bản docker v2ray x-ui này: https://hub.docker.com/r/enwaiax/x-ui
Rất mong a giúp đỡ và xin hậu tạ bia 🙂
(lý do em cần đưa v2ray vào sv hiện tại thay vì dùng 1 server riêng là: 1. nếu chỉ chạy v2ray x-ui ko thì phí, mà sv hiện tại sv VN rất mạnh nên em muôn kết hợp vào chút)

Mình cũng đang vướng quả này. Con TVBOX đang cài NPM, và Docker V2ray.

Forward từ Internet -> 80 -> NPM -> V2ray:1000 mà k nối được.

Không biết có ae nào setup forward từ NPM sang V2ray OK chưa

Em chào anh, Em đang có website chạy php trên xampp chạy window. Theo hướng dẫn của anh em mới tạo vps ubuntu trên oracle cloud, cài nginx proxy manager. Bây giờ có cách nào chuyển đổi không ạ. Em xin chân thành cảm ơn.

Bên mình cũng có mấy website đang chạy bình thường trên xampp trên window, nhưng giờ do nhu cầu sử dụng nhiều dịch vụ trên 1 IP Public nên mình cài NMP trên 1 máy ubuntu khác và cũng đã tạo proxyhost nhưng nó không thể chạy, bạn có thể hướng dẫn được không

Mình không dùng Xampp và cũng không biết rõ cách bạn cấu hình ra sao, cũng như lỗi bị gì nên không thể hướng dẫn chính xác được.
Néu bạn đã chọn dùng NPM làm Reverse Proxy thì cần chỉnh lại port 80/443 chuyển hướng về IP của Ubuntu đang chạy NPM. Sau đó tạo proxy host cho từng domain, trỏ về IP của Windows đang chạy Xampp.

NPM hỗ trợ Cache Assets, nhưng mình không rõ cách nó hoạt động, và cũng không biết cấu hình chi tiết nó ra sao. Nếu không chắc thì bạn không nên dùng.

Chào bác. Mình theo dõi blog của bác thường xuyên để xây dựng homelab cho mình. Mình có sử dụng đồng thời 2 tên miền test1.com (DDNS của Google) và test2.com (DDNS của Cloudflare).
Trên Google DDNS thì IP là: 113.x.x.x
Trên Cloudflare thì hiện 2 IP: 172.x.x.x và 104.x.x.x nhưng trong A Records của Cloudflare thì dạng IP là 113.x.x.x.

Chào anh.
Em có 1 cái home server cài jellyfin để xem phim từ bên ngoài.
Em làm theo hướng dẫn của post, thực hiện mở cổng 80, 443 trên router và đã thành công.
Anh cho em hỏi cổng 80, 443 có bị tấn công không và có cách nào phòng ngừa?
Em đang dùng router nhà mạng và chỉ có firewall trên router.
Cám ơn anh

Mở cổng nào trên router cũng có khả năng bị tấn công nhé. Cách phòng ngừa tốt nhất là chỉ mở port cho WireGuard VPN và truy cập thông qua VPN.
Còn nếu bắt buộc phải mở cổng thì có thể cải thiện bảo mật theo hướng dẫn ở đây: https://thuanbui.me/toi-uu-bao-mat-cho-nginx-proxy-manager-su-dung-access-lists/ , tuy nhiên không có gì bảo đảm 100% an toàn nhé.

Mình có thay đổi cấu hình chút do port:80 đang bị chiếm bởi Heidall, nhưng có vẻ đổi như vậy thì Nginx chỉ chạy giao diện web thôi chứ thực ra k có tác dụng gì cả.

– ’82:82′ # Public HTTP Port
– ‘445:445′ # Public HTTPS Port
– ’81:81’ # Admin Web Por

Bạn chỉnh port sai rồi. Nếu muốn chỉnh thỉ chỉnh cái port ở phía trước, cái phía sau giữ nguyên vì nó là port internal của container.
– ’82:80′ # Public HTTP Port
– ‘445:443′ # Public HTTPS Port
– ’81:81’ # Admin Web Por

Mình đã cài đặt thành công theo hướng dẫn của bạn. Mình có 1 thắc mắc muốn hỏi. Khi cấu hình new proxy host và add ssl để truy cập https trên sever nginx rồi thì có cần cài thêm ssl trên sever backend không nhỉ? Hiện sever backend của mình đang dùng webpanel aapanel. nếu chỉ để http trên sever backend thì truy cập từ ngoài vào với https có được không nhi? Mong được bạn trả lời. cảm ơn bạn

1

Mình không rành vụ chia front end, backend này nên không rõ. Nếu cấu hình SSL được cho backend thì tốt nhất nên làm cho mọi thứ đồng bộ với nhau nhé.

Mình đang gặp vấn đề này với NPM, ko biết có bác nào từng gặp ko. Mình có chạy Synology qua NPM mọi thứ đều bình thường, nhưng khi upload những file nặng tầm 6GB trở lên thì báo lỗi Connection fail (trường hợp Synology NAT port thì bình thường, nhưng chạy qua NPM thì bị vấn đề như trên).
Ko biết có bác nào từng gặp vấn đề này chưa. Cám ơn

Trả lời kopi Hủy

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *