反向代理工具 Nginx Proxy Manager
简介
Nginx Proxy Manager(以下简称 NPM)就是一个 Nginx 的代理管理器,它最大的特点是简单方便。
即使是没有 Nginx 基础的小伙伴,也能轻松地用它来完成反向代理的操作,不需要自己写复杂的 nginx 配置,而且因为自带面板,操作极其简单。
Nginx Proxy Manager 后台还可以一键申请 SSL 证书,并且会自动续期,方便省心。
官方网站:Nginx Proxy Manager
官方快速安装:Guide | Nginx Proxy Manager
准备工作
- 服务器
- Vultr 注册购买:SSD VPS Servers, Cloud Servers and Cloud Hosting - Vultr.com
- Racknerd 注册购买:RackNerd LLC
- 域名(可选)
- SSH 连接工具(可选)
- 反向代理工具(可选)
- NPM 官网:Nginx Proxy Manager
以上提供的内容仅作为参考,请按需选用
快速使用
环境搭建
我们推荐按照 Docker 官方文档安装 Docker 和 Docker Compose,因为部分 Linux 发行版软件仓库中的 Docker 版本可能过旧。
创建容器
- 在系统任意位置创建一个文件夹,此文档以
/opt/docker/npm
为例
mkdir -p /opt/docker/npm && cd /opt/docker/npm
mkdir -p ./{conf,data,logs}
注意:后续操作中,产生的所有数据都会保存在这个目录,请妥善保存
- 创建
docker-compose.yaml
vim docker-compose.yml
在英文状态的输入法下,按下 i
,左下角出现 --INSERT--
后,粘贴填入下面的内容:
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80' # 不建议修改端口
- '81:81' # 可以把冒号左边的 81 端口修改成你服务器上没有被占用的端口
- '443:443' # 不建议修改端口
volumes:
- ./data:/data # 点号表示当前文件夹,冒号左边的意思是在当前文件夹下创建一个 data 目录,用于存放数据,如果不存在的话,会自动创建
- ./letsencrypt:/etc/letsencrypt # 点号表示当前文件夹,冒号左边的意思是在当前文件夹下创建一个 letsencrypt 目录,用于存放证书,如果不存在的话,会自动创建
# network_mode: "host"
注意:安装了 NPM 之后,就不需要再安装 Nginx 了,否则会端口冲突(不建议修改 NPM 的 80、443 端口)。如果你的服务器安装了宝塔面板,也可以和 NPM 一起使用,只要你到软件后台把宝塔安装的 Nginx 关闭或者卸载即可。
之后,同样在英文输入法下,按一下 esc
,然后 :wq
保存退出。
- 启动服务
docker-compose up -d
实时查看日志:
docker-compose logs -f
- 用浏览器访问
http://ip:端口号
即可
默认登陆的用户名:admin@example.com
密码:changeme
第一次登陆会提示更改用户名和密码,建议修改一个复杂一点的密码。
如果需要配置域名访问,建议先配置好反向代理以及域名解析再进行初始化。如果通过
http://ip:端口号
的形式无法访问,请到服务器厂商后台将运行的端口号添加到安全组,如果服务器使用了 Linux 面板,请检查此 Linux 面板是否有还有安全组配置,需要同样将端口号添加到安全组。
更新容器
- 停止运行中的容器组
cd /opt/docker/npm && docker-compose down
- 备份数据(重要)
cp -r /opt/docker/npm /opt/docker/npm.archive
需要注意的是,
npm.archive
文件名不一定要根据此文档命名,这里仅仅是个示例。
- 更新服务
修改 docker-compose.yaml
中配置的镜像版本
拉取镜像
docker-compose pull npm
重新启动容器
docker-compose up -d
操作指南
配置反向代理
首先我们登陆网页端之后,会弹出修改用户名和密码的对话框,我们根据自己的实际来修改自己的用户名和邮箱。
保存之后,会让我们修改密码(建议用一个复杂的密码)。
接着我们就可以添加一个反向代理了。
点击 Proxy Hosts
,
接着点击 Add Proxy Host
,弹出如下对话框:
看起来都是英文,很复杂,但是其实很简单,我们只要用到其中的几个功能即可,这边稍微解释一下:
Domain Names
:填我们网站的域名,首先记得做好 DNS 解析,把域名绑定到我们的服务器的 IP 上Scheme
:默认http
即可,除非你有自签名证书Forward Hostname/IP
:填入服务器的 IP,或者 Docker 容器内部的 IP(如果 NPM 和 网站搭建在同一台服务器上的话)Forward Port
:填入网站映射出的端口,这边默认是8090
Cache Assets
:缓存,可以选择打开Block Common Exploits
: 阻止常见的漏洞,可以选择打开Websockets Support
:WS 支持,可以选择打开Access List
: 这个是 NPM 自带的一个限制访问功能,这边我们不管,后续可以自行研究。
以下是一个样列:
因为样例的 NPM 和 网站搭建在同一台服务器 上,所以这边的 IP,图中填的是 172.17.0.1
,为 Docker 容器内部的 IP 地址,
可以通过下面的命令查询:
ip addr show docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:e4:a3:b5:b9 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
这边的 IP 是 172.17.0.1
,填入这个 IP,可以不用打开防火墙的 8090
端口。
当然,如果你的 NPM 和网站不在同一台服务上,你需要在 IP 部分填入 你的 网站所在的服务器的 IP,并在服务商(部分服务商如腾讯、阿里)的后台打开 8090
端口。
申请 SSL 证书
接着我们来申请一张 SSL 证书,让我们的网站支持 https
访问。
如图所示,记得打开强制 SSL,其他四个的功能请自行研究,这边不多做讨论。
- 申请证书需要你提前将域名解析到 NPM 所在的服务器的 IP 上;
- 如果你使用的是国内的服务器,默认
80
和443
端口是关闭的,你需要备案之后才能使用;- 如果你使用了 CloudFlare 的 DNS 服务,记得把小黄云关闭(即不开启 CDN)。
不出意外,你将成功申请到 SSL 证书,证书会三个月自动续期。
再次点开配置,查看一下,将强制 SSL 打开。
至此,你已经成功完成了网站的反向代理,快尝试使用域名访问一下看看吧!
同样的,举一反三,试试把你的 NPM 也用一个域名来反向代理一下吧。(小提示:你需要再解析一个域名(可以是二级域名)到 NPM 所在的服务器上,反代页面需要填的 IP 可以填 docker 容器内的 IP 也可以填服务器的 IP,端口填 81 即可)
FAQ
申请证书过程出现异常,导致申请失败
- Internal Error while applying let’sencrypte certificate
- Temp workaround (that works for me!) for SSL certificate renewal bug
- ModuleNotFoundError: No module named ‘zope’
- AttributeError: module ‘certbot.interfaces’ has no attribute ‘IAuthenticator’
- Internal Error while applying let’sencrypte certificate
如何安装中文版
- GitHub: xiaoxinpro/nginx-proxy-manager-zh
- Docker: chishin/nginx-proxy-manager-zh
当你使用官方示例的 docker-compose
时需要注意,将 image 镜像 jc21/nginx-proxy-manager
替换为 chishin/nginx-proxy-manager-zh
即可实现中文部署
中文镜像并没有重新构建后端代码,由 Dockerfile-zh 源码可以得知,中文版镜像基于官方镜像替换前端代码来实现的,所以中文版本的全部功能与官方版本完全相同,只是显示界面的文字不同的区别。
端口无法访问怎么办
sudo systemctl stop firewalld
处理遇到 502 的问题
setsebool -P httpd_can_network_connect 1