本文将手把手教你在家庭服务器(以群晖 NAS 为例)上搭建属于自己的个人博客。无需公网 IP,无需复杂代码。
1. 申请一个域名
访问一个网站,本质上是去网络世界拜访一位朋友。
IP 地址:好比朋友家的 GPS 坐标(如
116.40, 39.90),机器能懂,但人类记不住。域名:好比通讯录里的名字(如
baidu.com),简单好记,自动指向背后的坐标。
我推荐在 Cloudflare 购买域名。理由很简单:良心。他们的价格基本就是批发成本价,而且首年与续费同价。不像某些平台首年 $1 诱惑你,续费时突然涨到 $20 割韭菜。

2. 搞定公网访问
域名买好后,如何让外网用户访问你放在家里的 NAS 呢?
❌ 传统方案的痛点
公网 IPv4:国内家庭宽带几乎不提供。IPv4 地址资源枯竭,除非你办理昂贵的企业专线,否则很难拿到。
公网 IPv6:虽然 IPv6 地址多到能给地球上每一粒沙子编号,但目前连通性并不完美。受限于路由配置或防火墙策略,可能有 30%-50% 的用户因网络环境不支持 IPv6 而无法访问你的博客。
✅ 终极方案:Cloudflare Tunnel
这是 Cloudflare 提供的一项免费反向代理服务(Zero Trust)。简单来说,就是让 Cloudflare 帮你打通一条从你家 NAS 到互联网的专属隧道。
它比IPv6 直连强在哪?
3. 在本地部署Cloudflare Tunnel服务
第一步:获取隧道 Token
登录 Cloudflare 面板,在左侧菜单点击 Zero Trust。如果是首次使用,根据提示点击免费订阅(费用为 $0)。
进入 Networks网络 -> Tunnels连接器,点击 Create a tunnel创建隧道。

Connector隧道类型 选择 Cloudflared,给隧道取个名(如
nas-blog)。在 Install and run a connector安装并运行连接器 页面,操作系统选择 Docker。
在下方的代码框中,找到
tunnel run --token后面的那串长字符(Token),复制并保存好。
第二步:在群晖上运行 Tunnel 容器
打开群晖 Container Manager (或 Docker) 套件。
下载镜像:点击“注册表/镜像仓库”,搜索
cloudflared。选择cloudflare/cloudflared,标签选latest,点击下载。
⚠️ 注意:由于国内网络环境,Docker Hub 可能拉取失败。如果下载不动,请配置国内 Docker 镜像源(可参考网上的
registry-mirrors教程)。启动容器:
选中下载好的镜像,点击“运行”。
容器名称:填写
cloudflared-tunnel。自动重启:务必勾选 “启用自动重新启动”,确保 NAS 重启后隧道自动重连。
高级设置(关键点):
网络:选择
host。这步非常重要,否则 Cloudflare 无法转发请求到 NAS 的其他端口。执行命令:在“命令”框中填写:
tunnel run --token 你的那串长token。
完成向导并启动容器。
回到 Cloudflare 网页,如果看到隧道状态变为 Healthy(绿色),恭喜你,隧道已打通!
点击左侧映像,等待下载完成,然后选中下载好的 cloudflare/cloudflared,点击上方运行。容器名称随便填,比如cloudflared-tunnel,然后务必勾选上启用自动重新启动,这样群晖重启后它才能自动连上。

然后是高级设置,网络选择host,执行命令处以下面格式填写tunnel run --token 你的那串长token,然后点击下一步,检查摘要,点击完成。

容器启动后,回到电脑浏览器的 Cloudflare 页面。打开连接器页面,列表里应该会出现一个连接,状态是绿色的正常。现在隧道打通了,我们还需要告诉Cloudflare,当别人访问你的域名时,要转到你群晖的哪个端口,也就是把来访的客人正确地引到客厅,而不是厕所。
我们点击该隧道的名字,然后选择编辑。选择上方已发布应用程序路由的标签,点击添加已发布应用程序路由。

以本站为例,在域中选择你最开始注册好的域名,然后服务-类型选择HTTP,URL填写localhost:8090,8090是本站使用的建站服务Halo的端口。

在群晖上部署博客服务,以Halo为例
现在打开手机浏览器,用移动网络访问你的域名,理论上就可以连到服务器了,但是会报错,因为上面填写的端口没有任何服务。那么我们开始在群晖上开始部署博客服务吧。
Halo (发音:/ˈheɪloʊ/) 是目前国内开发者圈子里口碑最好、颜值最高的开源博客系统之一。可以实现打开就能写,写完就很好看的需求。
打开群晖 File Station。在 docker 目录下新建文件夹 halo。
打开 Container Manager -> 项目 -> 新增。
项目名称:halo-blog。
路径:选择刚才的 /docker/halo。
来源:选择“创建 docker-compose.yml”。
粘贴以下配置代码(这是 Halo 2.0 标准生产环境配置):
version: "3"
services:
halo:
image: halohub/halo:2.20
container_name: halo
restart: on-failure:3
depends_on:
halodb:
condition: service_healthy
networks:
halo_network:
volumes:
- ./halo-data:/root/.halo2
ports:
- "8090:8090" # 8090是Halo的后台端口
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
environment:
# 连接数据库的配置
- SPRING_R2DBC_URL=r2dbc:pool:postgresql://halodb/halo
- SPRING_R2DBC_USERNAME=halo
# 务必修改下面的数据库密码
- SPRING_R2DBC_PASSWORD=你的数据库强密码
- SPRING_SQL_INIT_PLATFORM=postgresql
# 外部访问地址 (解决反向代理后的链接问题)
- HALO_EXTERNAL_URL=https://你的域名.com
halodb:
image: postgres:15.4
container_name: halo-db
restart: always
networks:
halo_network:
volumes:
- ./db-data:/var/lib/postgresql/data
ports:
- "5433:5432" # 避免数据库端口冲突
environment:
- POSTGRES_PASSWORD=你的数据库强密码 # 必须和上面一致
- POSTGRES_USER=halo
- POSTGRES_DB=halo
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
networks:
halo_network:注意请把代码里的 你的数据库强密码 改成你自己设的密码(两处要一致);把 https://你的域名.com 改成你实际申请的域名。
点击下一步,完成创建。群晖会开始拉取镜像。Java 应用启动比较慢,尤其是第一次初始化数据库,可能需要 1-2 分钟。你可以查看容器日志,直到看到 Started Application in ... seconds 字样。
现在博客已经运行起来了,进入博客和后台非常简单:
公网访问(推荐):直接输入你之前配置的域名,例如 https://你的域名.com
局域网访问(备用):输入 http://你的群晖IP:8090
你看到的画面: 你应该会看到一个 Halo 的初始化引导页面。