CGNAT环境下如何将家用Docker服务暴露至外网?
CGNAT环境下如何将家用Docker服务暴露至外网?
哥们,太懂你这种被CGNAT坑的感觉了——家里的HP小服务器跑着Docker服务,想分享给朋友却拿不到公网IP,ISP还不给帮忙。既然你会Docker和Linux,还有域名甚至愿意掏点钱搞VPS,那咱们直接上简单、实用、不搞复杂理论的方案!
先给你把反向代理的核心逻辑讲明白,其实没那么玄乎:因为CGNAT让你家服务器没法被公网直接找到,但你家服务器主动连外面的公网节点是完全没问题的。反向代理就是找一个有公网IP的“跳板”(比如VPS或者Cloudflare的节点),让公网用户先访问这个跳板,再由跳板把请求转发到你家里的服务器上。
下面给你两个最适合你的方案,按需选:
方案一:用VPS做反向代理跳板(稳定可控,适合长期用)
既然你愿意付费,这个是最靠谱的,完全自己掌控,没有流量限制(只要VPS带宽够)。
步骤拆解:
- 搞个便宜VPS:买个1核1G的入门款就行(比如年付几十块的那种),系统选Ubuntu/Debian,拿到公网IP。
- 建立VPS和家里服务器的私密隧道:用WireGuard(轻量、快,适合Docker),相当于给两者拉一条专属网线。
- 在VPS上装WireGuard服务器,生成客户端配置文件(照着网上的入门教程抄就行,不用深究原理)。
- 家里的HP mini上用Docker跑WireGuard客户端:
把你从VPS生成的客户端配置文件放到指定目录,启动容器后,VPS和家里服务器就打通了(比如VPS的隧道IP是docker run -d \ --name wireguard-client \ --restart always \ --cap-add NET_ADMIN \ --cap-add SYS_MODULE \ -v /path/to/your/wireguard/config:/etc/wireguard \ linuxserver/wireguard10.0.0.1,家里的是10.0.0.2)。
- 在VPS上装反向代理工具:推荐用Caddy,自动搞定SSL证书,不用手动折腾Let's Encrypt。
- 安装Caddy后,创建配置文件
/etc/caddy/Caddyfile:# 比如你要分享的服务域名是app.yourdomain.com app.yourdomain.com { reverse_proxy 10.0.0.2:8080 # 这里填你家里Docker服务的内网端口(比如8080) tls your@email.com # 填你的邮箱,Caddy自动申请SSL证书 } - 启动Caddy:
systemctl start caddy,设置开机自启:systemctl enable caddy。
- 安装Caddy后,创建配置文件
- 域名解析:把你的域名(比如app.yourdomain.com)的A记录指向VPS的公网IP。
搞定!现在朋友访问app.yourdomain.com,请求会先到VPS,再通过WireGuard隧道转发到你家里的Docker服务。
方案二:用Cloudflare Tunnel(免费省心,适合小流量)
如果不想折腾VPS,Cloudflare Tunnel是个绝佳选择——完全免费,不用管公网IP,直接用Cloudflare的全球节点做跳板,还自带CDN和SSL。
步骤拆解:
- 把你的域名托管到Cloudflare:如果还没弄,先去Cloudflare后台添加域名,把DNS服务器改成Cloudflare的(跟着指引走就行)。
- 创建Cloudflare Tunnel:
- 登录Cloudflare后台,进入「Zero Trust」→「Access」→「Tunnels」,点击「Create a tunnel」,给隧道起个名字。
- 复制生成的token(别弄丢了)。
- 家里的Docker跑Cloudflare Tunnel客户端:
把docker run -d \ --name cloudflared \ --restart always \ cloudflare/cloudflared tunnel run --token YOUR_TOKENYOUR_TOKEN换成你刚才复制的token,启动容器就行。 - 配置域名指向隧道:回到Cloudflare Tunnel页面,点击「Add a public hostname」,填写你要用来访问服务的域名(比如app.yourdomain.com),然后把「Service」设置为
http://家里Docker服务的内网IP:端口(比如http://192.168.1.100:8080)。
完事!Cloudflare的节点会主动连到你家里的容器,朋友访问域名就直接到你的服务了,连防火墙都不用开(因为是出站连接)。
一些小提醒
- 不管用哪个方案,家里的HP mini要保持开机,Docker容器记得加
--restart always,保证重启后自动运行。 - 用VPS的话,要在VPS的防火墙里打开80、443端口(Caddy用)和WireGuard的默认端口51820。
- 如果是多服务,Caddy和Cloudflare Tunnel都支持配置多个域名,分别转发到不同的Docker端口。
备注:内容来源于stack exchange,提问作者Sam Cooper




