背景:为什么要迁回国内
博客最初部署在 Netlify,国内访问有几个硬伤:评论后端偶尔加载慢、图片走海外源站体验差,还有一个合规问题——用已备案的国内域名解析到境外服务器,并不符合 ICP 备案管理要求。虽然只是个人博客,但既然要做长期维护,早晚都要将站点放到国内。
目标是:主站跑在国内服务器,图片走国内对象存储,评论后端自建在国内,全流程备案合规。
时间线:域名、备案、服务器与迁移
| 顺序 | 阶段 | 说明 |
|---|---|---|
| 1 | 购买域名与服务器 | 腾讯云新客活动,一年几十块 |
| 2 | 提交个人 ICP 备案 | 腾讯云初审 + 管局审核,前后约两周 |
| 3 | 整站迁移 | 图片、评论、主站一次性切完,约半天 |
博客还没正式推广,没有评论数据要迁,旧 Netlify 站点也继续跑着做备份,并无迁移压力。
基础设施:域名、服务器与 ICP 备案
域名
主域名为 lblog.com.cn,评论子域名为 comments.lblog.com.cn,都在腾讯云注册和管理。
服务器
腾讯云轻量应用服务器新客专享型实例:
| 配置项 | 参数 |
|---|---|
| CPU | 2 核 |
| 内存 | 2 GB |
| 系统盘 | SSD 50 GB |
| 流量包 | 300 GB/月 |
| 带宽 | 4 Mbps |
服务器会分配一个公网 IP(49.233.x.x)。腾讯云新客购买和首次续费同价,一年几十块。
备案
域名购买后两天提交个人 ICP 备案。腾讯云会先初审,大概两天左右,期间会打电话确认信息;初审通过后提交管局,管局审核时间约十天(具体以当地管局为准)。备案期间旧站点继续跑在 Netlify,没有中断访问。
备案时站点名称审核比较严格,不能带”博客""个人”这类通用词。建议按官方命名规范填写,避免不符合要求。
公安联网备案
ICP 备案通过后还有一步:公安联网备案。建议也都一并申请备案也更加合规。ICP 备案管的是”这个域名能不能用”,公安联网备案管的是”这个网站是谁在运营”,两者都要做,不是可选项。
流程比 ICP 备案简单:ICP 备案通过后,备案平台会给你一个公安联网备案数据码(30 天内有效,过期要重新获取)。拿着数据码,登录全国互联网安全管理服务平台(beian.mps.gov.cn),注册账号后按提示绑定数据码、补充服务商信息,提交审核即可。
审核通过后会拿到一个「XX 公网安备 00000000 号」格式的公安备案号,和 ICP 备案号一样要展示在站点页脚,并链接到公安备案平台。
DNS 与 SSL:解析和证书
DNS 解析
在腾讯云 DNSPod 里配了三条 A 记录:
| 主机记录 | 记录类型 | 记录值 |
|---|---|---|
| @ | A | 49.233.x.x |
| www | A | 49.233.x.x |
| comments | A | 49.233.x.x |
主站和 Waline 评论后端共用一台服务器,通过不同域名和 Nginx 反代分流。
SSL 证书
宝塔面板里一键申请了 Let’s Encrypt 免费 SSL 证书,主站和 comments.lblog.com.cn 子域都开了 HTTPS。
图片加速:从 R2 到腾讯云 COS
建桶
在腾讯云 COS 控制台创建存储桶:
| 项目 | 参数 |
|---|---|
| 存储桶名称 | lublog-images-<APPID> |
| 地域 | 北京(ap-beijing) |
| 访问权限 | 指定用户 |
| 当前存储量 | 约 90 MB |
后端适配
src/lib/storage.ts 里已经预留了 COS 后端,和 Cloudflare R2 复用同一套 AWS S3 SDK。只是 endpoint、region 和 forcePathStyle 不同:
- COS:
cos.ap-beijing.myqcloud.com,forcePathStyle=false - R2:
<accountId>.r2.cloudflarestorage.com,forcePathStyle=true
代码层配置好 COS_SECRET_ID、COS_SECRET_KEY、COS_BUCKET、COS_REGION、COS_PUBLIC_URL 后,存储后端就切过去了,业务代码零改动。图片 URL 继续走签名 URL,原 R2 的私有化逻辑在 COS 上同样适用。
数据迁移
图片迁移用项目里的脚本完成:npm run migrate:r2-to-cos。
脚本会读取 MongoDB 里 gallery_images 实际引用的 storageKey/thumbKey,只搬这些对象(R2 里共 260 个对象,画廊只引用其中一部分),流式从 R2 get 到本地再 put 到 COS。全部成功后,批量把 store 里的 url/thumbUrl 域名前缀从 R2 换成 COS;中途若有失败项则不改 store,避免指向没迁完的 COS。
迁移后旧 Netlify 站点和原 R2 桶保留,旧方案有足够的免费额度,也不必担心双桶重复计费或提前停机。
评论后端:Waline 从 Vercel 到自建容器
部署方式
Waline 后端从 Vercel + Neon Postgres 迁回国内服务器,用 Docker 容器部署:
- Web 服务:
waline:latest,端口8360 - 数据库:MariaDB 10
容器编排文件放在宝塔 /www/docker/waline/docker-compose.yml 下。
数据库选型波折
一开始尝试过旧方案的 Postgres,后来想更轻量化用 SQLite,结果首次注册管理员时报错提示缺表。最后选了 MariaDB,稳定可用。
建表
在宝塔文件管理器里把 Waline 官方建表 SQL 上传到 /www/docker/waline/waline.sqlite.sql,包含评论表、表情反应计数器表、用户表三张核心表,手动执行完成初始化。
反代
Nginx 把 comments.lblog.com.cn 反代到本机 8360 端口。防火墙不需要对外开放 8360,外网只通过域名和 HTTPS 访问。
主站部署:宝塔反向代理 + Astro node standalone
Astro 配置已经从 @astrojs/netlify 切到 @astrojs/node standalone 模式。构建产物是一个 Node 服务,宝塔里建网站后做反向代理即可。
首次配置:在宝塔网站里添加反向代理,指向 http://127.0.0.1:4321(Astro node standalone 服务默认监听端口),配置一次即可。
之后每次更新站点:
- 服务器上拉取最新代码
npm ci安装依赖npm run build构建- 重启 Node 服务
目前站点还没正式推广,构建频率不高,没有专门写自动部署脚本,手动执行足够。
经验与教训
-
备案通过前域名不能指向国内服务器:管局审核未完成,域名就无法正式解析到国内 IP。旧 Netlify 站点继续跑,可以平稳过渡。
-
数据库选型按场景来,别追”专业”:一开始想用 Postgres,最后选了 MariaDB。回头看,选型应该看这几点:
- 数据规模:个人博客评论量很小,单机文件型数据库完全够用,MySQL/Postgres 的优势要到更大数据量和并发才体现
- 服务器资源:2 核 2G 的轻量服务器,为一个评论后端跑完整 Postgres 实例属于浪费内存,MariaDB 更轻
结论:小场景优先选”够用且自己能排查”的方案,不要因为某个数据库更”专业”就选它。
-
容器编排文件要放到固定路径:第一次在宝塔 Docker 容器编排上传后,在文件管理器里找不到目录,后来又重新又建了一套
/www/docker/waline,建议一开始就指定好持久化目录。 -
反代端口要记牢:主站和 Waline 共用一台服务器,靠域名和端口区分,配置时别写错后端地址。
-
迁移前先确认有没有数据要迁:本站没有评论、没有注册用户,所以数据库从 Postgres 换到 MariaDB 没有数据迁移负担。如果有相关数据,这一步必须提前规划。
评论及留言规则
评论提交后需审核通过才会展示,请耐心等待。
请在交流中保持友善、理性和尊重。
你不得利用本站发布、传播或实施以下行为:
评论提交后需审核通过才会展示。什么是 Waline?