家庭服务器从入门到精通 · 第 5 篇 · NPM反向代理从安装到起飞:一条命令搞定HTTPS

# 家庭服务器从入门到精通 · 第 5 篇· NPM反向代理从安装到起飞:一条命令搞定HTTPS

本文是「家庭服务器从入门到精通」系列文章,记录了从零搭建家庭服务器的完整过程。
系列:家庭服务器从入门到精通 · 第 5 篇

作者:妍杰丽云

标签:NPM 反向代理 SSL 1Panel Docker

到目前为止,你已经能让外网访问家里的某个端口了。但家里跑着三四十个 Docker 服务------导航站、聊天室、Jenkins、AI 面板------如果每个都在路由器上开一个端口映射,你得配几十条规则,记几十个端口号,还全是 HTTP 明文传输。NPM 就是来解决这个"幸福的烦恼"的:一个端口进,按域名分发给不同服务,就像一栋大楼的前台------访客只认门牌号,前台负责带你去对应的房间。


一、为什么需要反向代理

回顾一下前几篇的成果:

  • 第 3 篇yourdomain.top → 公网 IP(DDNS)
  • 第 4 篇:路由器 888 → NPM:30080,8443 → NPM:30443

现在访问 `https://<你的域名> 能到达 NPM。但你有几十个服务:

makefile 复制代码
导航站:    <内网服务器>:5000
Jenkins:   <内网服务器>:8080
VoceChat:  <内网服务器>:3000
QwenPaw:   <内网服务器>:9090
...        ...(还有 34 个)

如果每个服务都在路由器上开一个端口映射,你得配 38 条规则,记 38 个端口号。而且大部分服务的端口还不是 HTTPS------外网明文传输,不安全,而且路由器一般配置的端口映射也是有限的,我家路由器只能配置32条。

**NPM(Nginx Proxy Manager)**就是来解决这个问题的。它的核心能力:一个端口进,按域名分发给不同内网服务。

css 复制代码
外网请求
    │
    ├─ nav.yourdomain.top:8443 → NPM → 转发到 :5000(导航站)
    ├─ jenkins.yourdomain.top:8443 → NPM → 转发到 :8080
    ├─ chat.yourdomain.top:8443 → NPM → 转发到 :3000
    ├─ ai.yourdomain.top:8443 → NPM → 转发到 :9090
    └─ ...

路由器只需要配两条端口映射。所有流量的分发在 NPM 内部完成。


二、NPM 安装在哪个设备?

关键决策:NPM 装在哪台机器上?

我有三台"设备"(见第 1 篇)。路由器的端口映射只能指向一个 IP ,所以 NPM 必须装在要被映射的那台机器上。

候选 能不能装 NPM 理由
NAS () 能,但不推荐 NAS 是数据心脏,尽量少暴露公网流量
AI Server (<AI 服务器>) 但它主要负责 AI,不想掺杂网络流量
webServer (<内网服务器>) 最佳 本身就是对外服务机,40+ Docker 容器都在上面

路由器端口映射也是指向 <内网服务器>。链路一致:

xml 复制代码
公网 → 路由器:8443 → <内网服务器>:30443 → NPM 容器 → 分发
公网 → 路由器:888 → <内网服务器>:30080 → NPM 容器 → 分发

三、Docker 部署 NPM

在 webServer (<内网服务器>) 上,用 1Panel 或者 docker-compose 部署。

我用的 1Panel,在应用商店搜 nginx-proxy-manager 一键安装,配置好容器和宿主机端口。

宿主机端口 容器端口 用途
30080 80 HTTP 入口
30443 443 HTTPS 入口
30081 81 管理面板

📌 宿主机 30080/30443 就是第 4 篇路由器映射的目标。NPM 容器内部还是用标准的 80/443,宿主机做了端口转换。

NPM 的管理面板在 `<NPM 管理地址>

makefile 复制代码
Email:    admin@example.com
Password: changeme

首次登录会要求改密码。


四、配置第一条反向代理

以家庭导航站为例------假设导航站跑在 <内网服务器>:5000

4.1 添加 Proxy Host

NPM 面板 → HostsProxy HostsAdd Proxy Host

配置项 说明
Domain Names nav.yourdomain.top 子域名
Scheme http 后端服务协议
Forward IP <内网服务器> 后端服务所在 IP
Forward Port 5000 后端服务端口
SSL 先不勾 后面单独配

保存后,NPM 自动生成 Nginx 配置。

4.2 DNS 添加子域名

去阿里云 DNS 解析控制台,给 nav.yourdomain.top 加一条 A 记录,指向你的公网 IP(和主域名一样),或者直接加一条 CNAME 指向 yourdomain.top

💡 推荐更省事的办法:加一条泛解析 *.yourdomain.top → 公网 IP。后面所有新增子域名自动生效,不用每次加 DNS 记录。

4.3 验证

外网(手机切 4G)访问:

xml 复制代码
https://<你的域名>:<端口>

应该能看到导航站页面。


五、SSL 证书:1Panel 自动申请 + 自动续期

HTTP 是明文传输。外网访问最好使用 HTTPS。NPM 自带 Let's Encrypt 申请功能,但有个问题:Docker 容器内的 certbot 续期不稳定,需要定期手动申请,一旦忘记了,域名访问就失败了。

我的方案:用 1Panel 的证书功能接管 SSL,然后把证书"喂"给 NPM。

5.1 为什么用 1Panel 而不用 NPM 自带

对比 NPM 自带 Let's Encrypt 1Panel 证书管理
续期稳定性 偶发失败(尤其国内网络) 稳定,支持多个 DNS 服务商
管理方式 NPM 面板内操作 1Panel 统一管理多域名
推送证书 仅 NPM 自己用 可以推送到任意路径
通知提醒 证书到期前邮件/通知提醒

5.2 1Panel 申请证书

1Panel → 网站证书申请证书

配置项 说明
类型 Let's Encrypt 免费,3 个月有效期
域名 *.yourdomain.top, yourdomain.top 泛域名证书,所有子域名通用
验证方式 DNS-01 需要阿里云 API 密钥验证
DNS 服务商 阿里云 1Panel 内置支持
AccessKey 填入阿里云子账号 Key 第 4 篇创建的那个
自动续期 ✅ 开启 到期前自动续,永远不过期

🔐 DNS-01 验证比 HTTP-01 更好------不需要开放 80 端口,而且支持泛域名证书。

申请成功后,1Panel 会显示证书详情(域名、到期时间、签发机构)。

5.3 把证书推送给 NPM

这是最妙的一步。1Panel 支持证书推送------把申请好的证书文件复制到指定路径。

在 1Panel 证书管理页面,点刚申请的证书 → 推送 → 添加推送目录:

bash 复制代码
证书路径: /opt/1panel/apps/nginx-proxy-manager/nginx-proxy-manager/data/data/custom_ssl/npm-3
私钥路径: /opt/1panel/apps/nginx-proxy-manager/nginx-proxy-manager/data/data/custom_ssl/npm-3

📌 为什么要推送到 custom_ssl/npm-3?NPM 的 Docker 数据持久化在 /opt/1panel/apps/nginx-proxy-manager/nginx-proxy-manager/data/ 下,其中 custom_ssl 目录存放的是 NPM 自定义 SSL 证书 。NPM 内部证书编号从 npm-1 开始递增,你的第一个自定义证书就是 npm-3(前两个是 NPM 自带的默认证书)。

推送后,这个目录下应该有:

bash 复制代码
npm-3/
  ├── fullchain.pem    # 完整证书链
  └── privkey.pem      # 私钥

5.4 NPM 里启用 SSL

回到 NPM 面板 → 编辑刚才的 Proxy Host → SSL 选项卡:

配置项
SSL Certificate Custom(不要选 Let's Encrypt)
Certificate 下拉选 npm-3(NPM 自动识别了 custom_ssl 下的证书)
Force SSL ✅ 勾选(HTTP 自动跳转 HTTPS)
HTTP/2 Support ✅ 勾选

保存。现在访问:

xml 复制代码
https://<你的域名>:<端口>

绿色小锁出现了 ✅。

5.5 续期流程全自动

bash 复制代码
1Panel 检测证书即将到期
    ↓
自动调用阿里云 DNS API 续期
    ↓
新证书生成
    ↓
自动推送到 custom_ssl/npm-3/
    ↓
NPM 自动加载新证书(检测到文件变化)
    ↓
无缝续期,服务不中断

全程零手动。设置一次,永久有效。


六、子域名 + 端口号如何实现内网服务暴露

现在把整个链路串一遍,以一个具体服务为例------VoceChat 聊天服务 跑在 <内网服务器>:3000

6.1 配置链路

xml 复制代码
第 1 步:DNS
  阿里云 → *.yourdomain.top → 公网 IP
  访问 chat.yourdomain.top → 解析到公网 IP

第 2 步:路由器端口映射
  8443 → <内网服务器>:30443
  流量从公网进入 webServer 的 NPM

第 3 步:NPM 反向代理
  chat.yourdomain.top → <内网服务器>:3000
  NPM 根据请求的 Host 头匹配规则,转发到后端

第 4 步:SSL
  1Panel 泛域名证书 → 推送 custom_ssl → NPM 加载
  HTTPS 加密全程

6.2 完整访问效果

子域名 内网服务 外网访问
nav.yourdomain.top:8443 <内网服务器>:5000 导航站
chat.yourdomain.top:8443 <内网服务器>:3000 聊天室
jenkins.yourdomain.top:8443 <内网服务器>:8080 CI/CD
git.yourdomain.top:8443 <内网服务器>:3001 Gitea
ai.yourdomain.top:8443 <AI 服务器>:7860 AI 面板

注意最后一行------AI 面板跑在 AIServer (.95) 上,NPM 一样可以转发,只要 webServer 能访问到 <AI 服务器> 就行(都在同一局域网)。


七、常见问题与避坑

Q1:路由器端口映射应该指向哪个 IP?

指向运行 NPM 的那台机器。 我的 NPM 在 webServer (<内网服务器>),路由器映射就指向 .103。

如果你把 NPM 装在别的机器上,记得把路由器映射一起改。指向了错的 IP,外网请求到不了 NPM,自然一片空白。

Q2:为什么是 8443 不是 443?

443 被运营商封了(见第 5 篇)。访问 URL 必须是 https://<你的域名>:<端口>,不要忘了端口号。

💡 嫌 URL 带端口号不好看?存浏览器收藏夹。谁天天手动输 URL 呢。

Q3:新加了一个子域名服务,NPM 配了但访问不了

三步排查:

bash 复制代码
# 1. DNS 生效了吗
nslookup new.yourdomain.top
# 返回公网 IP 了没有?

# 2. NPM 代理通吗(在 webServer 上测)
curl -I <内网服务地址>
# 内网直接访问后端服务正常吗?

# 3. NPM 配置对了吗
# NPM 面板 → Hosts → 检查 Domain Names 拼写、Forward IP/Port

80% 的情况是 DNS 还没生效(新加的泛解析要等几分钟传播)。

Q4:1Panel 证书推送后 NPM 找不到证书

检查两点:

  • 推送的路径对不对:必须是 custom_ssl/npm-X(X 是 NPM 的证书编号)
  • NPM 的 data 目录是持久化的吗:Docker 映射的宿主机路径和 1Panel 推送的路径是否一致

如果路径对了但 NPM 不认,重启 NPM 容器让它重新扫描 custom_ssl 目录。

Q5:泛域名证书包含所有子域名吗

*.yourdomain.top 覆盖一级子域名:nav.yourdomain.topchat.yourdomain.top 都算。但 xxx.nav.yourdomain.top(二级子域名)不覆盖。

家庭场景一级子域名完全够用。

Q6:NPM 能代理非 HTTP 服务吗

NPM 主要做 HTTP/HTTPS 反向代理。TCP/UDP 代理(比如 Minecraft 服务器、SSH)需要用 NPM 的 Stream 功能,在面板的 Streams 菜单里配置。


八、NPM 管理的 38 条代理概览

写到这里,我的 NPM 已经管着 38 条代理了。分类如下:

类别 数量 典型服务
网络工具 8 条 NPM 面板、1Panel、路由器管理
开发工具 8 条 Gitea、Jenkins、IT-Tools、API 文档
AI 服务 6 条 QwenPaw、Ollama、FunASR、Stable Diffusion
影音媒体 7 条 Jellyfin、有声书、视频站、Firefox Docker
生活服务 5 条 导航站、VoceChat、密码管理、云盘
其他 4 条 博客、监控面板、HomeAssistant

每一条代理的配置都一样------域名 + 后端 IP:端口 + SSL。背后的技术原理完全相同,一旦搞懂了第一条,后面 37 条就是复制粘贴的体力活。


九、总结

xml 复制代码
┌──────────────────────────────────────────────────┐
│                    公网请求                        │
│         https://<你的域名>:<端口>           │
└────────────────────┬─────────────────────────────┘
                     │
              ┌──────┴──────┐
              │   路由器      │  端口映射 8443→30443
              │  (公网 IP)   │
              └──────┬──────┘
                     │
              ┌──────┴──────┐
              │   webServer  │  NPM 监听 30443
              │ <内网服务器>│
              │              │
              │  ┌─────────┐ │
              │  │   NPM   │ │  根据域名匹配
              │  │ SSL证书 │ │  nav → :5000
              │  │ (1Panel │ │  chat → :3000
              │  │  自动续) │ │  ...
              │  └─────────┘ │
              └──────┬──────┘
                     │
          ┌──────────┼──────────┐
          │          │          │
     ┌────┴───┐ ┌───┴────┐ ┌──┴─────┐
     │ 导航站  │ │ 聊天室  │ │Jenkins │ ...
     │ :5000  │ │ :3000  │ │ :8080  │
     └────────┘ └────────┘ └────────┘

核心就四步:

步骤 在哪配置 做了什么
① DNS 泛解析 阿里云 *.yourdomain.top → 公网 IP
② 端口映射 路由器 8443 → <内网服务器>:30443
③ NPM 反向代理 NPM 面板 子域名 → 内网服务 IP:Port
④ SSL 证书 1Panel 泛域名证书 → 推送 NPM → 自动续期

📸 截图占位:1Panel 应用商店 NPM 安装、NPM 面板 Proxy Hosts 列表、1Panel 证书申请页面、证书推送配置、浏览器访问带绿色锁的导航站

🔗 下一篇:导航站自动化------从 NPM 数据库一键生成家庭导航页


💡 系列文章导航 本系列涵盖家庭服务器集群搭建、网络配置、Docker部署、AI应用等方方面面,适合有一定技术基础的读者。

相关推荐
天狼啸月19903 小时前
RagSEDE复现: Docker and Ragflow 关系
docker·容器·ragflow·ragsede
java_logo4 小时前
Docker 部署 SamWaf 完整教程:开源 Web 应用防火墙实测
docker·开源·防火墙·waf·samwaf·轩辕镜像·docker部署waf
C137的本贾尼4 小时前
第十篇:Docker & K8s——标准化应用的“集装箱“和“码头调度中心“
docker·容器·kubernetes
增量星球4 小时前
《持续交付2.0系列一》从技术交付到业务引领
java·docker·容器·devops
探索云原生19 小时前
终于搞懂 Kueue:5 个核心对象一次讲透
linux·docker·ai·云原生·kubernetes
AI服务老曹20 小时前
Docker部署AI视频分析平台参数配置说明与调优指南
人工智能·docker·音视频
eggcode21 小时前
docker拉取、重命名、导出导入、删除镜像的示例
docker
静待雨落1 天前
Docker 高频命令
docker·容器
Java小白笔记1 天前
Docker 命令大全:从入门到精通的完整指令集
spring cloud·docker