如何优雅地使用 NPM 进阶篇
本文最后更新于:2023年4月5日 凌晨
前言
在如何优雅地替换掉宝塔面板 一文中我介绍了通过 Nginx Proxy Manager 来替换宝塔面板的方案。该文章中我用的是 host 网络,由于 NPM 无法更改默认的 81 端口,所以会有安全隐患。本文会介绍如何创建一个 docker network 并兼容 IPv6 来更优雅的使用NPM。
搭建步骤
开启 Docker 的 IPv6(可选)
对于本机配置好 IPV6 的情况,如果想要 Docker 内也能使用 IPV6,需要手动的配置。
首先你要获知本机 IPv6 的子网,运行命令 ifconfig 找到网卡的如下段:
inet6 2605:xxxx:xxxx::1 prefixlen 64 scopeid 0x0<global>其次请将 Docker 尽可能更新到新版,然后编辑如下配置文件,如果没有这个文件就新建:
nano /etc/docker/daemon.json写入如下配置:
{
"ipv6": true,
"fixed-cidr-v6": "2605:xxxx:xxxx::1/64",
"experimental": true,
"ip6tables": true
}这里的
fixed-cidr-v6并不一定需要你的公网 IP,只是用于bridge网络的,实际上可以用任意的子网,至少你和我下面提供的网段冲突即可。
注意修改 IPv6 子网。重启 Docker 服务:
systemctl restart docker这样就给 docker 默认的 bridge 网络启用了 ipv6,注意此时只有使用 bridge 这个网络的容器才有 ipv6,我们可以简单的验证一下:
docker network inspect bridge可以看到 "EnableIPv6": true 的字段。
创建一个公用的 docker network
创建一个名为 web_apps 的网络,对于有 IPv6 的服务器,直接运行命令,不用修改:
docker network create --subnet="fc00:0000:0000:2::/64" --ipv6 web_apps如果本机没有 IPv6,则运行:
docker network create web_apps其他步骤都是相同的。
搭建 NPM
其他的和上文就比较类似了。对于 NPM 的docker-compose.yaml文件如下:
version: "3"
services:
npm-proxy:
image: jc21/nginx-proxy-manager:latest
container_name: npm-proxy
restart: always
ports:
- 81:81
- 80:80
- 443:443
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
networks:
- web_apps
php74:
image: webdevops/php:7.4-alpine
container_name: php74
restart: always
environment:
- fpm.pool.listen=9074
volumes:
- ./data:/data
networks:
- web_apps
php73:
image: webdevops/php:7.3-alpine
container_name: php73
restart: always
environment:
- fpm.pool.listen=9073
volumes:
- ./data:/data
networks:
- web_apps
data-static:
image: mariadb:10
container_name: data-static
restart: always
environment:
- MARIADB_ROOT_PASSWORD=sample-password
volumes:
- ./database:/var/lib/mysql
networks:
- web_apps
networks:
web_apps:
external: true请仔细看上面的配置文件,对于 PHP 等服务以及其他的 Docker 应用,其端口都 没必要映射出来 *,直接用NPM 反代即可。
值得注意的是,对于需要使用 web_apps 的服务,yaml 配置文件末尾必须包括
networks:
web_apps:
external: true并且 每个 service 块中必须包括
networks:
- web_apps这样该 service 才会用 web_apps 这个网络。并且每个 service 名必须保持唯一,其他同网络内的容器想要访问该 service 只需要把 service 名作为 host 即可。
例如放置于 ./data/static_websites/ 目录下的enable-73.conf 和enable-74.conf需要修改为
# ./data/static_websites/php/enable-73.conf
location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass php73:9073;
fastcgi_index index.php;
include /data/static_websites/php/fastcgi.conf;
include /data/static_websites/php/pathinfo.conf;
}# ./data/static_websites/php/enable-74.conf
location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass php74:9074;
fastcgi_index index.php;
include /data/static_websites/php/fastcgi.conf;
include /data/static_websites/php/pathinfo.conf;
}NPM在线配置
首次访问 NPM 需要开放 81 端口来进行设置,建议在 NPM 中创建一个网站并开启 HTTPS 来反代 81 端口,然后再关闭 81 端口的映射,这样最为安全。

然后就可以通过域名来访问了,记得还要删除 81 端口的映射,即删除如下行:
- 81:81然后重建即可:
docker-compose down && docker-compose up -d一个🌰
例如我需要建一个 Cloudreve,同样是 Docker 容器,则 docker-compose.yaml 需要这样配置:
# ~/Cloudreve/docker-compose.yaml
version: "3"
services:
cloudreve:
image: cloudreve/cloudreve:latest
container_name: cloudreve
restart: always
volumes:
- ./downloads:/data
- ./config/conf.ini:/cloudreve/conf.ini
- ./config/cloudreve.db:/cloudreve/cloudreve.db
- ./uploads:/cloudreve/uploads
- ./avatar:/cloudreve/avatar
networks:
- web_apps
cloudreve-redis:
image: redis:alpine
container_name: cloudreve-redis
restart: always
volumes:
- ./redis:/data
networks:
- web_apps
networks:
web_apps:
external: true如前文所提到的,Cloudreve的 HTTP 端口不需要映射出来,因为其和 NPM 处于同一个网络中。
Cloudreve 默认是监听 5212 端口,则 NPM 需要这样配置:

即 Forward Hostname/IP 需要填入你的 service 名(而不是 container_name,container_name 可以随意起)。
后记
请把本文与 如何优雅地替换掉宝塔面板 结合在一起参考,相信通过这两篇文章的介绍 NPM 的使用应该非常好上手了。