news 2026/10/7 3:07:00

Nginx Proxy Manager实战:告别IP加端口,统一内网服务域名

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nginx Proxy Manager实战:告别IP加端口,统一内网服务域名

1. 先别急,聊聊这段痛苦的"IP加端口"日子

我猜你和我一样,电脑上存着一大堆书签,全是类似192.168.1.5:3000、192.168.1.5:8080、192.168.1.8:5601这样的地址。每次想打开个服务,都得先回忆那串数字,要不就在路由器后台翻半天。家里的 NAS、开发机上的 Grafana、办公室里的 Ollama、虚拟机里跑的测试环境,每个都占一个端口,时间一长自己都分不清哪个端口对应哪个服务。

更难受的是,有的服务还会因为端口冲突互相打架——你启动了一个新容器,提示端口被占,你查来查去,发现是另一个早已忘记的服务还挂在那个端口上。还有手机上访问局域网服务,每次都要手动输入一长串 IP 加端口,用完之后浏览器历史记录里全是乱七杂八的数字。

我自己的办公室环境就是典型:一台装了 Proxmox 的服务器,上面跑着十几个虚拟机,其中有 GitLab、Jenkins、Ollama、Open WebUI,还有一两个练手的代码仓库。一开始大家访问全靠 Excel 表格维护的"端口对照表",截图发群里。直到某天我实在忍不了,花了一个周末把 Nginx Proxy Manager(下称 NPM)部署起来,把所有服务全部收敛到http://git.lab、http://ollama.lab、http://grafana.lab这样的域名下,整个局域网访问体验完全不一样了。

这篇博文就是把我那次改造的过程、踩过的坑、以及后来的优化经验完整分享给你。内容不挑系统,Windows、macOS、Linux 都适用,只要你手里有一台能跑 Docker 的机器即可。哪怕你从来没配过 Nginx,跟着操作也能跑起来。

2. 为什么说这个方案"超简单":NPM 到底是什么样的存在

2.1 反向代理不是魔法,就是个"大堂前台"

先说个概念,别被"反向代理"这四个字吓到。你想像一下:一个大公司有很多部门(服务),每个部门有自己的分机号(端口)。外人打进来如果直接拨分机,得记一大堆号码;有了前台(反向代理),你只拨总机转一个分机号,前台帮你转接。NPM 就是那个总机前台。

传统做法是手写 Nginx 配置文件,每个站点写一个server{}块,改完还nginx -s reload。对于只想在局域网里访问几个服务的人来说,这有点过于"硬核"。你得记路径、管语法、注意分号,一个空格错了页面就 500。我当年刚接触时没少在这上面翻车。

NPM 把这一切变成了网页上的表单。你告诉它"把 http://grafana.lab 转发到 192.168.1.50:3000",它自己生成 Nginx 配置、自动重载、管理证书,你甚至不用碰一次终端。所以标题说"超简单",一点也不夸张。它适合的场景非常明确:内网服务多、端口难记、偶尔需要加个 HTTPS、还想顺便做访问控制——这就是 NPM 的主场。

2.2 为什么不是直接改 Nginx,也不是用 1Panel

我知道很多人在用 1Panel 这类面板,它也集成反向代理功能。我这里不是说 1Panel 不好,而是两个工具的定位不同。1Panel 更像一个"服务器管理全家桶",反代只是它的众多功能之一;NPM 则专职做反代和证书管理,界面更聚焦,配置项也更贴合代理场景。如果你的服务器上已经有 1Panel 管着很多网站,那直接在面板里配反代完全没问题;但如果你只是想给局域网里的 Docker 服务做个统一入口,NPM 更轻、更快、也更符合"搞完就忘"的心态。

另外还有一个常见替代品是 Traefik,它靠标签自动发现容器,看起来很科技,但配置方式对新手不太友好:要理解"动态配置""中间件""入口点"这些概念。我曾试用过一次,折腾两小时没完全搞定标签语法,而 NPM 十分钟就让我看到了效果。所以结论很简单:想要直观、快、稳,选 NPM;想折腾、想要完全自动化和极致的灵活,再考虑 Traefik。

2.3 它的核心功能一览

NPM 主要提供四类能力,我按使用频率排序:

  • Proxy Hosts:HTTP/HTTPS 反向代理,浏览器访问页面、调用 API 都靠它
  • Streams:TCP/UDP 端口转发,比如把服务器的某个端口转发到另一台机器的 SSH
  • Access List:访问控制列表,限制哪些 IP 能访问,还能加登录认证
  • SSL Certificates:证书管理,既可以用内网自签证书,也可以接入正规证书(如果你有)

后面我会逐个讲实际用法。

3. 动手之前,先想清楚这几件事

3.1 域名方案:没有公网域名,用 hosts 和本地 DNS

局域网里没有注册域名的必要,但我们依然可以"借用"域名格式。比如约定所有内网服务统一使用*.lab后缀(lab代表局域网,随便取的),于是grafana.lab、ollama.lab都是合法的主机名。这些名字不会和公网域名冲突,也容易记忆。

关键在于怎么让电脑把这些名字解析成你的服务器 IP。两种常用办法:

  • 改 hosts 文件:每台电脑的C:\Windows\System32\drivers\etc\hosts(Windows)、/etc/hosts(macOS/Linux)里加一行192.168.1.50 grafana.lab ollama.lab。适合设备少、不常变的场景。
  • 搭一个内网 DNS:用 AdGuard Home 或 Pi-hole 这类工具,统一管理解析。设备少用 hosts,设备多了强烈建议上 DNS,手机和智能设备改一下路由器 DNS 指向就能全局生效。后面我单独开一章详细讲。

这里有个细节:hosts 文件不支持泛解析,也就是你没法写一行*.lab让它通配所有子域名。每多一个服务就得手动加一行。如果你预计将来会不断加新服务,直接上 DNS 方案会更省心。

3.2 安装 Docker 和规划网络

NPM 官方推荐用 Docker 部署。以 Debian/Ubuntu 服务器为例,装 Docker 和 Compose 插件:

sudo apt update sudo apt install docker.io docker-compose-v2 -y sudo systemctl enable --now docker

Windows 用户可以用 Docker Desktop,macOS 同理。NPM 容器最常见的运行方式是单独挂一个 Docker 网络,或者干脆使用host网络模式(直接共享宿主机的网络栈)。我个人建议:NPM 单独容器跑在一个自定义 bridge 网络里,不需要 host 模式。因为 NPM 需要监听 80、443 和 81 端口,bridge 模式通过端口映射也能实现同样的效果,而且你可以灵活控制到底暴露哪些端口。

不过这里有个坑,我后面会单独说:如果 NPM 用 bridge 默认网络,它默认没法直接用容器名访问宿主机上的服务。解决办法有两个:要么在 Compose 里把 NPM 和你的服务放进同一个自定义网络,要么在转发目标里填宿主机的实际 IP。我自己是把所有需要反代的服务和 NPM 放进了同一个网络webnet,这样容器之间可以直接用"服务名"互相访问,配置反代时写http://nginx-app-1:8080这种容器名即可,干净利落。

3.3 提前体检,别让端口纠纷耽误时间

动手前先查一下宿主机上 80、443、81 是否被占用。我在本地笔记本第一次部署时就撞上了 IIS 占着 80,NPM 容器一直起不来。

检查端口占用,不同系统姿势不同:

  • Linux:sudo ss -lntp | grep -E ':80|:443|:81'
  • Windows:netstat -ano | findstr :80
  • macOS:lsof -i :80

看到已经有的监听进程,先关掉或者改端口。这里有个常见误区,热搜里也提到"0.0.0.0:80 被占是所有地址的 80 端口都没占了吗"。答案是:当某个服务绑定了0.0.0.0:80,它意味着占用了本机所有网卡的 80 端口,此时另一个服务即使只绑定某个特定 IP 的 80 端口也会冲突。所以查端口时如果看到0.0.0.0:80或:::80,基本就是全局占用,得先处理它。

4. 十分钟部署 Nginx Proxy Manager:实操记录

4.1 用 Docker Compose 一键拉起

我的部署目录是/opt/npm,里面放一个docker-compose.yml:

version: "3.8" networks: webnet: external: true services: npm: image: jc21/nginx-proxy-manager:latest container_name: npm restart: unless-stopped networks: - webnet ports: - "80:80" - "443:443" - "81:81" volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt environment: - ACME_EMAIL=admin@example.com

注意我在 Compose 里用了外部网络webnet。如果你还没创建这个网络,先执行:

docker network create webnet

然后把你的其他服务也接入webnet,这样 NPM 就能用容器名互相访问。如果你的服务是此前已经创建好的容器,需要重新连接网络:

docker network connect webnet 容器名

这点很重要,后面配置反代目标时你会感谢这个设计。

4.2 启动与初始化

拉起来之后:

cd /opt/npm docker compose up -d

浏览器访问http://服务器IP:81,第一次会要求注册管理员账号。默认初始账号是admin@example.com/changeme,第一次登录会强制让你改邮箱和密码。改完就进入主界面,左侧菜单就是那四项:Proxy Hosts、Redirection Hosts、Streams、Access Lists。

顺手看一眼日志确认没有报错:

docker logs -f npm

如果你看到类似[6/6] Starting Nginx或者ok的消息,就说明基础环境已经就绪。

4.3 界面地图:五分钟熟悉布局

主界面里真正常用的就这几个地方:

  • Proxy Hosts:这里的"Add Proxy Host"按钮你每天都会点,进去后有五个 Tab:Details、SSL、Advanced、Custom Nginx Configuration、Location
  • Streams:做 TCP/UDP 转发
  • Access Lists:把规则集中管理,应用到任意主机
  • SSL Certificates:PEM 格式的证书、密钥可以从这里导入,也可以申请内置证书

说白了,绝大多数配置都在"Add Proxy Host"这个弹窗里。后面每个场景我都按这个弹窗给你走一遍。

5. 第一次真的上手:给一个普通网页服务挂上域名

5.1 自己写个小服务做实验

动手时建议先用一个无风险的测试服务练手。比如我们在服务器上跑一个最简单的 Nginx 容器:

docker run -d --name test-web --network webnet -p 8888:80 nginx:alpine

这是一个返回默认欢迎页的 Nginx 容器,映射到宿主机 8888 端口。在没配 NPM 之前,你得访问http://服务器IP:8888才能看到它。

5.2 打开 Add Proxy Host 面板,逐项填清楚

登录 NPM,点Proxy Hosts->Add Proxy Host,弹窗里:

  1. Domain Names填test.lab
  2. Scheme选http(因为上游服务默认就是 http)
  3. Forward Hostname / IP填test-web
  4. Forward Port填80
  5. 勾选Block Common Exploits和Websocket Support——前者加一些 Nginx 安全过滤规则,后者让 WebSocket 长连接正常工作

填完点 Save。如果一切正常,你的浏览器访问http://test.lab就能看到测试页了。当然,前提是你的 hosts 文件已经加了192.168.1.x test.lab,或者 DNS 已经解析。

这里有个关键细节:NPM 容器和 test-web 容器必须在同一个 Docker 网络里,才能直接通过容器名test-web访问。如果你没在同一网络,这段配置会触发后面的 502 错误——遇到别慌,去看第 8 节。

5.3 为什么我建议用容器名而不是 IP

有朋友觉得"那我直接填192.168.1.50:8888不就行了,何必非用容器名"。实话讲,在 NPM 里填宿主 IP 确实也能通,但有个问题:如果服务容器迁移了、端口变了、或者 Docker 重启后 IP 变了,你还得回来改 NPM 配置。容器名在 Docker 网络内固定不变,填一次就永远有效。

打个比方,容器名相当于员工的花名,IP 相当于员工的工位号。花名不会变,工位号今天在这明天在那。所以凡是跑在 Docker 里的服务,我都建议把 NPM 和目标容器放在同一网络,直接用容器名转发。

5.4 顺手开启 WebSocket 的必要性

如果你以后要反代那些带实时交互功能的应用——比如 Jupyter、VS Code Server、Open WebUI 这类聊天界面——没勾 WebSocket 可能导致页面能打开但聊天一直转圈、或者文件实时同步总是断。我的经验是"无条件打开",因为开启后不会对普通 HTTP 请求造成负面影响,却能让长连接场景免遭折腾。勾选一次,省心很久。

6. 三个常见实战场景的完整配置

6.1 场景一:给 Grafana 或 Ollama 这类开发工具挂域名

假设你的开发机里起了 Grafana 在192.168.1.50:3000,Ollama 在192.168.1.50:11434。现在的痛点是:一个给 UI 用,一个给 API 用,端口完全不同。用 NPM 后:

  • 新建 Proxy Host:grafana.lab->http://192.168.1.50:3000
  • 再建一个:ollama.lab->http://192.168.1.50:11434

注意:ollama.lab不是给浏览器写聊天框用的,而是给后端代码或命令行配置 base_url 用的。比如我在 Python 脚本里把 Ollama 的地址从http://192.168.1.50:11434改成http://ollama.lab,代码迁移后完全不用改地址,配合 DHCP 固定 IP 更是稳如老狗。

如果 Ollama 容器跑在 Docker 里,直接用容器名http://ollama:11434。只要 NPM 和它一个网络,就不需要关心 Ollama 映射在宿主机的哪个端口上。这里有个好处:你甚至可以把容器端口映射去掉,让服务只对 Docker 网络可见,对外完全由 NPM 统一出口。这样端口扫描脚本扫不到它,能减少很多无意义攻击面。

关于大模型推理服务,很多朋友在局域网里跑 DeepSeek 这类模型的本地部署(类似 deepseek harness 离线的场景),前端负载均衡需要 NPM,还能给后续多个推理节点做按路径分发。你只要建模型A.lab指向192.168.1.51:8000,建模型B.lab指向192.168.1.52:8000,多个模型服务互相隔离又统一入口,排查问题会非常直观。

6.2 场景二:同一台机器多环境的多站点隔离

做开发的朋友经常在本地跑"前端 + 后端 + 数据库",或者虚拟机里一套、物理机一套。假如你有三个项目同时开发,传统的localhost:3001、localhost:3002、localhost:3003切来切去非常痛苦。用 NPM 之后:

  • project-a.lab->http://127.0.0.1:3001(前端)
  • api.project-a.lab->http://127.0.0.1:8080(后端接口)
  • project-b.lab->http://虚拟机IP:3100

这样每个项目都是独立的"域名",调试前端的时候再也不怕 cookie、localStorage 跨端口串数据。对死磕跨域问题的开发来说,端口隔离和域名隔离体验完全不同:端口不同导致的前端跨域问题会经常出现,统一走 80/443 后 cookie 的 Domain 属性能更干净地隔离,踩过的都懂。

如果服务在本地开发机上,NPM 也在同一台机器,转发地址可以直接写http://127.0.0.1:3001。但有一种情况例外:NPM 跑在 Docker 里,你要转发的服务跑在宿主机上,此时填127.0.0.1通常不通(因为容器网络和宿主网络是隔离的),要填宿主机的实际内网 IP,比如http://192.168.1.50:3001。这是新手最容易踩的坑,记住这个区分。

6.3 场景三:用 Stream 转发 SSH,让内网服务安全暴露

NPM 的Streams模块很适合做 TCP 转发。比如你不想把 SSH 端口22裸露在防火墙外,可以先把宿主机的 SSH 改到2222,然后用 NPM 做一个 Stream:监听2222转发到localhost:22。这样你从外面访问 NPM 的2222就等于访问服务器的 SSH。好处是规则统一在 NPM 面板里管理,还可以配合 Access List 做来源 IP 限制,比裸奔 22 端口安心得多。

创建方式:

  1. 进入Streams->Add Stream
  2. Incoming Port 写2222
  3. Forward Host 写127.0.0.1(或容器名),Forward Port 写22
  4. 保存后,防火墙里放行2222

注意:Stream 转发不能复用已经监听的端口。如果某个端口被 Nginx 或 NPM 本身占用了,再建 Stream 会报错。常见做法就是给 Stream 留一批独立的高位端口,比如2200-2300,每个端口对应一台机器的 SSH,再由 NPM 统一管理。至于要不要把所有 Stream 端口都暴露到公网,这属于安全规划范畴,我建议只在信任网络里这么做。

7. 局域网 DNS 怎么搭:从 hosts 到一劳永逸

7.1 每台电脑改 hosts 的操作细节

如果你只有两三个设备,改 hosts 是最快的方式。Windows 上用管理员身份打开记事本,编辑C:\Windows\System32\drivers\etc\hosts,追加一行:

192.168.1.50 test.lab grafana.lab ollama.lab

macOS/Linux 改/etc/hosts后,刷新 DNS 缓存:

  • macOS:sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
  • Linux:sudo systemctl restart systemd-resolved或sudo resolvectl flush-caches

这里提醒一句:hosts 文件不支持*.lab的泛解析。每新增一个服务都要手动加一行。所以我在本地机器上维护了一个hosts片段,每次加服务就追加一行,定期清一次。后来服务超过 10 个,我彻底弃用改 hosts,转用下面这套方案。

7.2 用 AdGuard Home 做内网 DNS,解决全家设备访问

我的方案是:在服务器上跑 AdGuard Home,让它和 NPM 在同一 Docker 网络里,只开 53 端口(DNS)和 3000 管理端口。配置步骤:

  1. 添加 DNS 重写规则,把test.lab、grafana.lab都指向 NPM 所在机器的 IP
  2. 在路由器 DHCP 设置里,把 DNS 服务器改为 AdGuard Home 的 IP
  3. 重启路由器连接,手机、电脑、智能电视全部自动生效

这样以后新加服务,只需要在 AdGuard Home 后台添加一条重写规则,所有设备立刻能解析到新域名,根本不用再碰每台设备的 hosts。顺便还能看查询日志,谁在访问什么一清二楚,还能顺手屏蔽掉一堆广告域名。这是我这套方案里性价比最高的一个改动。

如果你不想多维护一个服务,也可以在路由器里直接设"自定义域名"映射,部分路由器支持把内部域名解析到内网主机。不过这类功能一般藏在"高级 DHCP/DNS"里,不如 AdGuard Home 直观。我的建议是:设备超过五个,直接上 AdGuard Home,一天内能稳定跑通,省下的精力远超投入。

7.3 手机和智能设备需要注意的细节

手机浏览器访问http://grafana.lab默认会尝试连接 80 端口,NPM 已经开了 80,所以没问题。但 iOS 的 Safari 对 HTTP 站点有时会在"自动开启 HTTPS"的选项上做文章,导致访问http://xxx.lab被强制跳转到https://xxx.lab,而你没配证书就会打不开。解决方式是:在 Safari 设置里关闭"自动更新为 HTTPS"。

iOS 访问自签名 HTTPS 证书则更麻烦些,它要求在"设置 -> 通用 -> 关于本机 -> 证书信任设置"里手动信任证书。Android 相对宽松,访问时会弹风险提示,选"仍然访问"即可。这一块内容容易被忽略,实际操作中踩到了才会感谢别人提前写了这段。

8. 加一层主动权:访问控制、高级安全和运维习惯

8.1 Access List:不让乱七八糟的 IP 靠近

NPM 的 Access List 本质上就是 ACL 规则列表。你可以建立一条规则"只允许家里的网段访问",然后应用到需要受保护的站点。用法:

  1. 进入Access Lists->Add Access List
  2. 加一条规则:Accept+ CIDR192.168.1.0/24
  3. 可以再加一条:Satisfy Any或者Satisfy All
  4. 在对应的 Proxy Host 的Access List下拉框里选择该规则

如果局域网里设有访客 Wi-Fi,访客网络可能在不同网段,比如192.168.2.0/24。此时想禁止访客访问内部工具,就把规则限制成只放行192.168.1.0/24,其余默认拒绝。这是成本最低的隔离手段,强烈建议给 SSH、数据库管理面板这类敏感服务挂上。

8.2 给敏感页面套一层用户名密码

在 NPM 里,Access List 的编辑页有Authorization标签页,可以设置 Basic Auth 账号密码。配好后访问对应域名会弹出一个浏览器原生登录框。这个功能我用来保护 NPM 管理面板(81 端口)的前置层——你不要把 NPM 管界面直接暴露,外面至少套一层密码和 IP 白名单,哪怕在局域网内也别裸奔。

限定场景:如果你有防火墙阻断策略,Windows 2016 服务器上还涉及入站出站规则放行 80/443/81,记得检查 Windows PowerShell 脚本或防火墙面板,确保不是系统防火墙把 NPM 的端口拦了。有时候 Docker 映射成功,但从外部访问就是不通,十有八九是防火墙规则没放行。

8.3 定期看看 NPM 的访问日志和错误日志

NPM 日志不用装额外组件,直接在容器里看:

docker logs npm --tail 100 -f

排查问题时,一条经典线索是:NPM 日志里出现connect() failed (111: Connection refused) while connecting to upstream,这基本等于"转发目标没启动"或者"IP/端口填错了"。如果看到permission denied,则可能和容器网络权限有关。

为什么强调日志习惯?因为 NPM 的 Web UI 不显示具体错误,只会给你一个 502。我刚开始总以为是"反正不对就怪 NPM",后来才发现 90% 的错误其实是上游服务没起来或者 Docker 网络没接上。学会看日志能帮你把排查时间从二十分钟压到两分钟。

9. 常见问题与排查技巧实录

下面把我在使用 NPM 过程中真正遇到过的坑,结合社区里的高频问题整理成速查表,你大概率迟早会碰到其中一个。

现象最常见原因处理方式
访问域名 502 Bad Gateway上游服务未启动,或 NPM 与上游不在同一网络检查服务是否运行,核对 Forward Host 是否填错
80 端口冲突导致 NPM 起不来IIS、Apache、Synology Web 后台占用了 80停掉占用进程,或临时改 NPM 端口映射
NET::ERR_CERT_COMMON_NAME_INVALID证书域名与访问域名不匹配证书改成访问的完整域名或加自定义 SAN
页面能开但 WebSocket 一直断未开启 WebSocket Support编辑 Proxy Host,勾选 Websocket Support
上传文件提示 413 Request Entity Too LargeNginx 默认限制 client_max_body_size 1M在 Advanced 加client_max_body_size 100m;
内网能访问,外网不行防火墙或路由器端口没放行查系统防火墙和路由器的端口转发规则
手机访问 HTTP 被强制跳 HTTPSiOS 自动启用 HTTPS关闭 Safari 自动 HTTPS 开关,或补上证书
新增服务 hosts 不生效hosts 文件缓存flush DNS 缓存,或换用 DNS 方案

9.1 502 的终极排查顺序

遇到 502,我现在的排查顺序固定如下:

  1. 先问"这个服务真的在跑吗?"——在浏览器用http://IP:端口直接访问上游,能通才继续
  2. 再问"NPM 能访问到它吗?"——如果上游是容器,看是否和 NPM 同一个webnet;如果上游是宿主机进程,看 NPM 填的是不是宿主 IP
  3. 最后看日志——docker logs npm --tail 50,看upstream关键字

这三步做完,90% 的 502 都解决了。尤其是第二步,多少人栽在"填了 localhost"上,怎么试都不通,因为 localhost 在容器里指的是 NPM 自身。

9.2 证书错误的 3 种解法

NET::ERR_CERT_COMMON_NAME_INVALID这个错误在局域网里几乎人手一次。我遇到的情况是:用 IP 访问https://192.168.1.50,但证书给test.lab签的,域名对不上。解法按优先级排列:

  • 用域名访问,别用 IP。所有用 NPM 的服务都改成域名,证书和 URL 对齐,问题自然消失
  • 如果证书是自签的,把证书导出、安装到客户端的系统证书库,并设为"始终信任"
  • 测试期间可以临时忽略证书错误,但不建议长期养成这种习惯,自签证书也是可以导入信任的,花三分钟做正事

要注意,如果你在 NPM 的 SSL 选项里选了"Request a new SSL Certificate",它默认会往 Let's Encrypt 申请证书(写 ACME_EMAIL 时填的),内网环境不一定能顺利签发。所以内网我一般选择Custom,上传一份脚本生成的自签证书,或者直接用 NPM 内置的 Internal 证书。生成自签证书的经典命令:

openssl req -x509 -newkey rsa:2048 -nodes \ -keyout key.pem -out cert.pem -days 825 \ -subj "/CN=test.lab" \ -addext "subjectAltName=DNS:test.lab,DNS:*.lab,IP:192.168.1.50"

然后把cert.pem和key.pem导入 NPM 的SSL Certificates,再把对应的 Proxy Host 选上这份证书。顺带说明,自签证书有效期建议别太长,825 天(Chrome 信任上限)是比较稳妥的时长。

9.3 端口冲突排查的一句话口诀

做端口操作时请记住这句话:"先看谁占着,再想怎么让"。用ss、netstat、lsof查出占用进程后,先判断那个服务还要不要,再决定是改它的端口还是停掉它。别一上来就强行 kill 进程,一句ss -lntp能省下你半小时找服务的时间。

尤其要注意的是:0.0.0.0:80被占用时,不意味着某些 IP 上的 80 还能用,前文已说过全局占用的问题。所以查询时看到0.0.0.0或:::80,直接认定 80 全局被占即可,不要心存侥幸。

9.4 裸奔 80/443 的这些坑

把几十个内部服务统一暴露到 80/443 确实方便,但方便也带着风险。我的建议是:管理后台和敏感工具一定挂 Access List;NPM 管理面板 81 端口不对外;有条件的话加一层防火墙(比如只允许内网网段访问 NPM)。还有,注意不要把 NPM 的 443 直接映射到公网路由器并做成端口转发,除非你清楚自己在做什么。反代是收敛入口的好工具,不是把内网全部暴露出去的借口。

10. 后续还能怎么玩,以及我的几点体会

这套方案的扩展空间其实很大。比如给 NPM 加多台后端服务器做负载均衡,同一个域名下配多个 Forward Host,NPM 默认会轮询。或者用 NPM 的Redirection Hosts把old.lab永久重定向到new.lab,省得老同事记错地址。再配合 AdGuard Home 的过滤规则,局域网里访问ads.lab也会直接被拦截,体验上很像企业级网关的雏形。

我个人在实际使用过程中的三点体会:

第一,稳定优先。NPM 本身很成熟,不用天天升级追新版本。只要容器没有崩溃,配置就没必要频繁改动。我的 NPM 从部署到现在已经跑了 8 个多月,期间只重启过一两次,配置完全没变。与其天天折腾工具,不如把时间留给业务。

第二,命名规范非常重要。开头我给每个服务起的域名都随意,后来导致同事问"那个proj2-old-final.lab是什么"。后面我统一按项目-环境-功能.lab的规则命名,比如blog-prod-web.lab、api-staging.lab,一眼就能明白语义。这个习惯应该从第一天就开始。

第三,备份策略别忘。NPM 的/data目录就是全部家当,定期把docker cp出来或者挂到一个备份盘上,一次导出也就几十 MB。真要哪天重装系统,恢复也就几分钟的事,比重新配全部代理主机强太多。我写了条 cron 凌晨自动打包上传备份盘,从此再没为配置丢失发愁过。

最后再分享一个小技巧:如果某天你发现某个 Proxy Host 访问特别慢,先在 Advanced 标签页加上proxy_read_timeout 300s;,看看能否缓解。不少内网服务在处理大文件或复杂请求时,Nginx 默认的 60 秒超时会打断长任务,调大这个值比换机器管用多了。

工具始终是手段,整理了自己的访问习惯,才真正算把这块空间收好。希望这一套分享能让你摆脱"IP 加端口"的日子,给内网的每个服务都安上自己的名字。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 3:06:47

Linux挂载Windows磁盘全攻略:NTFS驱动、fstab配置与报错排查

装过双系统,或者手头常备一块NTFS格式移动硬盘的朋友,大概率都遇到过“Linux挂载Windows磁盘”这个需求:插上盘,lsblk还能看见设备,但点进文件管理器却是只读,或者干脆mount就报wrong fs type。这篇文章我把…

作者头像 李华
网站建设 2026/10/7 3:06:28

转盘抽奖前端实现:可乱序、加权随机与动画控制

转盘抽奖这种需求,一说出来大家脑子里基本都是同一个画面:一个大圆盘,指针一停,奖品到手。但实际做起来,真正考验人的不是转盘有多好看,而是抽奖结果到底怎么定——尤其是接到"抽奖逻辑,可…

作者头像 李华
网站建设 2026/10/7 3:05:48

FZ-PanDA 5.72 离线部署与任务调度实战:从解压到批量编排

简介:FZ-PanDA5.72版是一款面向机器人视觉检测领域的仿真软件,主要服务于自动化生产线、智能制造与工业4.0场景下的工程师及研究人员。它围绕CCD视觉引导任务,帮助用户在虚拟环境中预演机器人动作、调整参数并测试多种工况,从而降…

作者头像 李华
网站建设 2026/10/7 3:05:41

BERT中文情感分类实战:从模型选型到微调避坑全解析

简介:这是一个基于BERT模型的中文文本情感分类毕业设计项目,面向计算机相关专业正在准备大作业、毕业设计的学生,也适合需要NLP项目实战练习的Python学习者。项目经导师指导并认可,评审分98分,所有源码均在本地编译调试…

作者头像 李华
网站建设 2026/10/7 3:05:22

SpringBoot智慧校园平台实战:从架构设计到部署避坑全记录

做智慧校园这个方向之前,我其实已经带团队接过不少类似的管理系统项目,但很多都是“小切口”式的:做一个失物招领、做一个课程表、做一个报修单。真正把“综合服务平台”这个概念落地,SpringBoot才是我绕不开的选择。这篇不是来科…

作者头像 李华