Reading System

收录整理

XBlog 公网访问方案:单台云主机 + Caddy + 子域隔离

用 4 个子域分别暴露:公开站、管理后台、收录入口、资源域名。

2026 年 3 月 15 日3 分钟石臻

目标

迁到一台公网 Linux 云主机,做长期正式站点;公开站对外开放,管理后台单独保护;OpenClaw 收录入口单独暴露。

推荐拓扑

  • xblog.<你的域名>:公开站
  • admin.xblog.<你的域名>:管理后台,前置一层 Basic Auth,再走 XBlog 自身登录
  • ingest.xblog.<你的域名>:只给 OpenClaw / 机器令牌调用的收录入口
  • assets.xblog.<你的域名>:MinIO 公共资源域名

不再直接把 3000/3001/4000/9000/9001 裸露到公网;公网只开放 80/443/22,其余服务仅本机访问。


运行拓扑

云主机建议 Ubuntu 24.04 LTS,先按 2 vCPU / 4 GB RAM / 40+ GB SSD 起步。

  • Caddy 跑在公网 80/443
  • web 跑本机 127.0.0.1:3000
  • admin 跑本机 127.0.0.1:3001
  • api 跑本机 127.0.0.1:4000
  • PostgreSQL 跑本机,仅内网访问
  • MinIO API 跑本机 127.0.0.1:9000,Console 跑本机 127.0.0.1:9001

反向代理路由

xblog.<domain> -> reverse proxy 到 127.0.0.1:3000

admin.xblog.<domain> -> 先 Basic Auth,再按路径分流:
  /api/* -> strip /api 后 reverse proxy 到 127.0.0.1:4000
  其余路径 -> reverse proxy 到 127.0.0.1:3001

ingest.xblog.<domain> -> 只放行 /api/health 和 /v1/ingest/articles 到 127.0.0.1:4000,其他路径直接拒绝

assets.xblog.<domain> -> reverse proxy 到 127.0.0.1:9000,只用于公开读对象

MinIO Console 不走公网子域,默认只通过 SSH 隧道临时访问。


应用配置

apps/web

  • 运行时:XBLOGAPIURL=http://127.0.0.1:4000
  • 构建时:NEXTPUBLICADMINAPPURL=https://admin.xblog.<domain>

apps/admin

  • 构建时:NEXTPUBLICXBLOGAPIURL=https://admin.xblog.<domain>/api

apps/api

  • 运行时:
  • APIHOST=127.0.0.1
  • WEBORIGIN=https://xblog.<domain>
  • ADMINORIGIN=https://admin.xblog.<domain>
  • APIBASEURL=https://admin.xblog.<domain>/api
  • OBJECTSTORAGEPUBLICBASEURL=https://assets.xblog.<domain>/xblog-assets

OpenClaw 生产侧

  • XBLOGAPIBASEURL=https://ingest.xblog.<domain>
  • XBLOGWEBBASEURL=https://xblog.<domain>

代码/配置收口要求

  1. 把当前本地默认值保留给开发环境,但生产必须补 .env.production 或 systemd EnvironmentFile
  2. 明确覆盖公开站里的后台入口默认值 NEXTPUBLICADMINAPPURL
  3. 明确覆盖管理端 API 默认值 NEXTPUBLICXBLOGAPIURL
  4. 不新增"公网公共 API"域名,公开读数据仍由 web 服务器端向本机 API 拉取

运维形态

Node 进程用 systemd 管理:

  • xblog-web.service
  • xblog-admin.service
  • xblog-api.service
  • xblog-minio.service

PostgreSQL 用系统服务管理,Caddy 用系统服务管理。


域名未准备好的处理方式

两阶段部署:

  • 第1阶段:只完成云主机、系统服务、内网反代、数据迁移和 smoke test
  • 第2阶段:域名到位后再接入 DNS 与正式 HTTPS

在域名未准备好前,不把"正式公网可访问"视为完成。


测试计划

基础访问

  • https://xblog.<domain> 可打开首页、分类页、文章页
  • http://xblog.<domain> 自动跳转到 HTTPS
  • 上传后的封面图和正文图通过 assets.xblog.<domain> 正常加载

管理端保护

  • 访问 https://admin.xblog.<domain> 先弹 Basic Auth
  • 通过 Basic Auth 后仍需 XBlog 后台登录
  • 未通过 Basic Auth 时,浏览器拿不到后台 HTML 和后台 API

管理端功能

  • 登录后台后,文章创建、分类保存、令牌创建/撤销/删除、封面上传都正常
  • 管理端上传流程里的 completeUrl 指向 https://admin.xblog.<domain>/api/...,不再回落到本地地址

OpenClaw 收录

  • https://ingest.xblog.<domain>/api/health 正常
  • POST https://ingest.xblog.<domain>/v1/ingest/articles 用有效机器令牌可成功
  • 同域名下访问 /v1/admin/、/v1/auth/ 必须被 Caddy 拒绝

安全与网络

  • 云主机安全组/防火墙只开放 22/80/443
  • PostgreSQL、MinIO API、MinIO Console 都不能从公网直连
  • SSH 隧道可临时访问 MinIO Console 做运维

假设

  • 继续沿用自部署 MinIO,不切换 AWS S3 / R2
  • 继续沿用单库 PostgreSQL,不引入托管数据库作为本轮必需项
  • 以"单台云主机承载全部服务"作为第一版正式公网方案
  • 管理后台的"单独保护"定义为:反代层 Basic Auth + 应用层登录双层保护
  • 公开站和后台的生产构建必须在最终域名确定后重新构建一次(因为 NEXTPUBLIC 变量会进入前端产物)