====== Nginx Proxy Manager(NPM) 當 Revers Proxy Server(Docker) ======
* 環境 : [[tech/alpine_docker]]
* 安裝的主機 IP : 192.168.11.231
===== 編輯與啟動 ====
* 編輯 yml 檔案
vi docker-compose.yml
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: always
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
goaccess:
image: xavierh/goaccess-for-nginxproxymanager:latest
container_name: goaccess
restart: always
ports:
- '7880:7880'
environment:
- TZ=Asia/Taipei
- SKIP_ARCHIVED_LOGS=False #optional
- DEBUG=False #optional
- BASIC_AUTH=False #optional
- BASIC_AUTH_USERNAME=user #optional
- BASIC_AUTH_PASSWORD=pass #optional
- EXCLUDE_IPS=127.0.0.1 #optional - comma delimited
- LOG_TYPE=NPM #optional - more information below
- ENABLE_BROWSERS_LIST=True #optional - more information below
- CUSTOM_BROWSERS=Kuma:Uptime,TestBrowser:Crawler #optional - comma delimited, more information below
- HTML_REFRESH=5 #optional - Refresh the HTML report every X seconds. https://goaccess.io/man
- KEEP_LAST=30 #optional - Keep the last specified number of days in storage. https://goaccess.io/man
volumes:
- ./data/logs:/opt/log
watchtower:
image: nickfedor/watchtower
container_name: watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Taipei
- WATCHTOWER_SCHEDULE=0 0 4 * * *
- WATCHTOWER_CLEANUP=true
labels:
- "com.centurylinklabs.watchtower.enable=true"
restart: unless-stopped
* 啟動服務
docker compose up -d
===== 進入網頁設定 =====
* http://192.168.11.231:81 (預設帳號密碼 : admin@example.com / changeme)
* 登入後會要求更改與設定 Administrator 的帳號密碼 \\ {{:tech:2022-09-03_19_28_43.png?600|}} \\ {{:tech:2022-09-03_19_29_15.png?600|}}
* 新增一個 Proxy Host :
* Hosts -> Porxy Hosts -> Add Proxy Host -> Exp. www.ichiayi.com ichiayi.com
* Detail -> Exp. 內部實際主機的 IP 是 https://192.168.11.233 \\ {{:tech:2022-09-03_21_08_01.png?1024|}}
* Custom locations -> Add location -> Exp. 將之前的 /wiki 導到現在的沒有 /wiki 的網址 \\ {{:tech:2022-09-03_21_09_35.png?1024|}}
* SSL -> Exp. 設定由 Let's Encrypt 簽發 SSL 憑證, 並透過 Cloudflare DNS 進行驗證 \\ {{:tech:2022-09-03_21_11_56.png?1024|}}
* 需要至 Cloudflare 的管理介面產生一個可以修改 Domain Name 權限的 API Token \\ {{:tech:2022-09-03_21_15_35.png?600|}} \\ {{:tech:2022-09-03_21_14_35.png?600|}}
* 將產生的 API Token 設定到 dns_cloudflare_api_token
* 要勾選同意 Let's Encrypt 服務條款, 點下 Save 如果沒問題大概 10 秒左右就可以產生SSL憑證 \\ {{:tech:2022-09-03_21_19_54-2.png?1024|}}
===== 更版升級 =====
* 只要執行以下命令就可以直接更版
docker compose pull && docker compose up -d
* 查看啟動過程 Logs
docker compose logs -f
===== 問題處理 =====
==== 1. 使用 Cloudflare 當 CDN 時傳入實際用戶 IP 的設定 ====
* 參考 - https://github.com/NginxProxyManager/nginx-proxy-manager/issues/811
* 編輯 Proxy Host -> Advanced -> Custom Nginx Configuration 加入 real_ip_header CF-Connecting-IP; 即可 \\ {{:tech:2022-09-03_22_42_06.png|}}
==== 2. 解決無法下載Proxy Host 超過 1GB 大檔案的設定 ====
* Proxy Host 是 NextCloud 要提供檔案下載時發現預設下載檔案大小限制為 1GB
* 參考 - https://rodrigolmti.medium.com/nextcloud-with-portainer-nginx-proxy-manager-63df45d62a0b
* 另外 NextCloud/all-in-one 會開啟 TRACE and TRACK method, 會造成主機弱點, 也順便設定關閉
* 編輯 Proxy Host -> Advanced -> Custom Nginx Configuration 加入
client_body_buffer_size 512k;
proxy_read_timeout 86400s;
client_max_body_size 0;
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS)$) {
return 405;
}
==== 3. 解決忘記登入資訊的做法 ====
* 參考 - https://github.com/NginxProxyManager/nginx-proxy-manager/discussions/1634
* 主要就是還原成預設登入帳號密碼的作法
* login: admin@example.com
* pass: changeme
==== 4. 統計分析紀錄的做法 ====
* 可使用 [[https://github.com/xavier-hernandez/goaccess-for-nginxproxymanager|goaccess-for-nginxproxymanager]] 當簡易分析方案
* 安裝方式可參考 [[tech/goaccess-for-nginxproxymanager]]
==== 5. 安裝環境無 IPv6 的議題 ====
* 參考 - https://nginxproxymanager.com/advanced-config/#docker-file-secrets
* 無 IPv6 的環境啟動時 log 內會出現類似以下的錯誤訊息
:
app-1 | ❯ Starting nginx ...
app-1 | nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
app-1 | ❯ Starting nginx ...
app-1 | nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
:
* 只要在 docker-compose.yml 內的環境變數加上 **DISABLE_IPV6=true** 即可 Exp.
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
environment:
- DISABLE_IPV6=true
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
==== 6. 升級到 v2.11 後 Custom locations 無法運作議題 ====
* 參考 - https://github.com/NginxProxyManager/nginx-proxy-manager/issues/3474
* 目前 Workaround 作法
- 在 docker-compose.yml 目錄新增 _hsts_map.conf 檔案
touch _hsts_map.conf
- 修改 docker-compose.yml 內增加
vi docker-compose.yml
:
- ./_hsts_map.conf:/app/templates/_hsts_map.conf
- 重新啟動 docker compose
docker compose up -d
==== 7. 匯出設定資料到另外一台主機匯入的作法 ====
- 在來源主機匯出
cd nginx-proxy-manager
tar -cvf data.tar data/
tar -cvf letsencrypt.tar letsencrypt/
- 將 data.tar 與 letsencrypt.tar 複製到目標主機 Exp.
scp *.tar 172.16.1.99:/root/
- 在目標主機匯入
mv *.tar nginx-proxy-manager/
cd nginx-proxy-manager
docker compose down
mv data data.org
mv letsencrypt letsencrypt.org
tar -xvf data.tar
tar -xvf letsencrypt.tar
docker compose up -d
docker compose logs -f
==== 8. 升級到 v2.12.4 後管理介面無法登入議題 ====
* log 出現 - Cannot install certbot-dns-cloudflare==4.0.0 and cloudflare==4.0.*
* 參考 - https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4606
* 目前 Workaround 作法
- 進入 NPM 容器內執行 Exp.
pve-rproxy:~# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
nginx-proxy-manager jc21/nginx-proxy-manager:latest "/init" nginx-proxy-manager 29 minutes ago Up 11 minutes 0.0.0.0:80-81->80-81/tcp, :::80-81->80-81/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
pve-rproxy:~# docker compose exec -it nginx-proxy-manager bash
_ _ _ ____ __ __
| \ | | __ _(_)_ __ __ _| _ \ _ __ _____ ___ _| \/ | __ _ _ __ __ _ __ _ ___ _ __
| \| |/ _` | | '_ \\ \/ / |_) | '__/ _ \ \/ / | | | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '__|
| |\ | (_| | | | | |> <| __/| | | (_) > <| |_| | | | | (_| | | | | (_| | (_| | __/ |
|_| \_|\__, |_|_| |_/_/\_\_| |_| \___/_/\_\\__, |_| |_|\__,_|_| |_|\__,_|\__, |\___|_|
|___/ |___/ |___/
Version 2.12.4 (b84762b) 2025-07-01 01:23:38 UTC, OpenResty 1.27.1.1, debian 12 (bookworm), Certbot certbot 4.0.0
Base: debian:bookworm-slim, linux/amd64
Certbot: nginxproxymanager/nginx-full:latest, linux/amd64
Node: nginxproxymanager/nginx-full:certbot, linux/amd64
[root@docker-434df09eec04:/app]# sh -c "sed -i 's/cloudflare==4.0.\*/cloudflare/' /app/global/certbot-dns-plugins.json"
[root@docker-434df09eec04:/app]# exit
exit
- 重新啟動容器
pve-rproxy:~# docker compose restart
[+] Restarting 1/1
✔ Container nginx-proxy-manager Started 3.5s
pve-rproxy:~#
==== 9. 查看 SSL Certificates 紀錄的設定內容 ====
* 因為 Web UI 只能針對 SSL Certificates 新增或刪除, 如果想了解之前設定的相關內容, 只能進入 sqlite 內查看
* 進入 data 目錄應該可以看到 database.sqlite
* 使用 sqlite3 進入查詢
~/nginx-proxy-manager/data# sqlite3 database.sqlite
SQLite version 3.49.2 2025-05-07 10:39:52
sqlite> select * from certificate;
1|2024-01-25 12:55:03|2025-10-04 09:16:37|1|0|letsencrypt|*.my.ichiayi.com|["*.my.ichiayi.com"]|2026-01-02 08:18:47|{"letsencrypt_email":"tryweb@ichiayi.com","dns_challenge":true,"dns_provider":"cloudflare","dns_provider_credentials":"# Cloudflare API token\r\ndns_cloudflare_api_token = xO************************************06","letsencrypt_agree":true}
* 如果有興趣了解整個資料庫結構可以下 **.fullschema** 查看
sqlite> .fullschema
CREATE TABLE `knex_migrations` (`id` integer not null primary key autoincrement, `name` varchar(255), `batch` integer, `migration_time` datetime);
CREATE TABLE `knex_migrations_lock` (`index` integer not null primary key autoincrement, `is_locked` integer);
CREATE TABLE `migrations` (`id` integer not null primary key autoincrement, `name` varchar(255), `batch` integer, `migration_time` datetime);
:
CREATE TABLE `access_list_client` (`id` integer not null primary key autoincrement, `created_on` datetime not null, `modified_on` datetime not null, `access_list_id` integer not null, `address` varchar(255) not null, `directive` varchar(255) not null, `meta` json not null);
/* No STAT tables available */
===== 參考網址 =====
* https://nginxproxymanager.com/guide/#features
{{tag>nginx proxy}}