Ghost 开发环境多 URL 场景测试指南:设备访问、HTTPS 与子目录配置验证
【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/Ghost
本篇指南聚焦 Ghost 开源发布平台的开发环境 URL 测试方法论。Ghost 的常规开发环境固定运行在http://localhost:2368,但真实业务往往涉及局域网设备访问、HTTPS 站点、站点部署于子目录以及 Admin 与站点分离在不同域名等复杂形态。读完本文,你将掌握:如何借助 HTTPS 隧道在手机/平板/另一台电脑上临时验证站点与 Admin、如何用 Caddy +.localhost域名在本地完整复现「HTTPS + 子目录 + 独立 Admin URL」三合一配置,以及如何为 URL 相关行为补充自动化测试覆盖。
一、先理解 Ghost 的 URL 配置体系
Ghost Core 的 URL 由两部分核心配置驱动:
url:站点对外公开的完整基础地址,既决定路由解析,也决定站点内部生成的绝对链接;admin.url:Admin 后台的独立地址,可选。一旦配置,/ghost/相关请求会按该地址重定向与路由。
开发期这些值可以通过运行时配置覆盖,其中首选载体是ghost/core/config.local.json——它是 Ghost 开发环境约定俗成的本地配置覆盖文件,会被 Git 忽略,适合存放仅限本机/本次测试的临时 URL 覆盖。与之相对的默认开发配置 ghost/core/config.development.json 内容极为精简(仅开启enableDeveloperExperiments),常规启动参数并不在配置文件中写死 URL,而是由环境与启动脚本决定默认的http://localhost:2368。
测试的基本原则是:针对你的改动所影响的 URL 形态去测试,而不是为了覆盖每一种 URL 边界情况反复重建整个开发环境。下文所有方案都建立在已有的pnpm dev/ Docker 开发环境之上做增量验证。
二、在另一台设备上测试:HTTPS 隧道方案
当需要在手机、平板或另一台电脑上打开站点或 Admin 时,最省事的方式是打一条 HTTPS 隧道。这能避免每台测试设备都要维护本地 DNS、分配静态 IP、安装本地证书颁发机构(CA)的麻烦。
操作步骤
- 保持
pnpm dev正常运行; - 安装并认证 ngrok 的 ngrok agent(Ghost 开发团队也确认 Caddy 网关信任 Tailscale Funnel 等同类隧道代理转发的协议头);
- 针对开发网关所在端口打隧道:
ngrok http 2368- 在另一台设备上打开 ngrok 给出的 HTTPS 转发地址,站点即可访问;Admin 在同一 URL 的
/ghost/路径下。
两个关键经验
隧道要打在网关(2368),不要打在单个子服务上。Ghost 前端(public app)与 Admin 各有独立的 Vite/开发服务器,如果只给某一个开发服务器打隧道,请求就绕过了开发环境既有的路由与中间件链条。把隧道开在统一入口的 Caddy 开发网关上,请求才会继续走与平时开发环境完全一致的路径,转发协议头也能被正确信任。
隧道 URL 通常是临时的,链接仍指向本机。隧道只解决了“打开页面”的入口问题,Ghost 内部根据配置的url生成的绝对链接(分享卡片、邮件链接、规范链接等)仍会是http://localhost:2368。如果被测行为依赖绝对链接,就需要把转发域名写进配置并重启开发环境:
- 创建
ghost/core/config.local.json:
{ "url": "https://your-forwarding-domain.example" }- 重启开发环境使配置生效;
- 测试结束后删除该文件——它被 Git 忽略,切勿提交。
同时请把公共隧道 URL 视为一次临时的公网暴露:不要在本地使用生产数据或生产凭据,测完立即关闭隧道。
三、完整复现「HTTPS + 子目录 + 独立 Admin URL」:本地 Caddy 环境
当改动影响重定向、生成的链接、API 请求、Cookie 或静态资源,而这些行为又依赖 HTTPS 协议、子目录路径或 Admin 独立域名时,单靠隧道就不够了。仓库提供了一个专用的手动环境来在浏览器里逐项检查这三种行为。
方案原理
- 在 Ghost Core 前面跑一个本地 TLS 代理(Caddy),提供真正的 HTTPS 请求;
- 使用
.localhost主机名——如site.localhost、admin.localhost——它们无需修改/etc/hosts、也无需运行 DNS 服务器就会自动解析到回环地址(loopback),证书则由 Caddy 的本地 CA 自动签发并可信; - 用覆盖文件同时配置站点 URL 的 HTTPS 协议、
/blog/子目录与 Admin 独立主机名,一次覆盖全部三种边界。
第一步:准备本地配置覆盖
安装 Caddy(若尚未安装),然后创建ghost/core/config.local.json:
{ "url": "https://site.localhost:8443/blog/", "admin": { "url": "https://admin.localhost:8443/blog/" } }注意两点语义:
- 站点 URL 中的
/blog/提供子目录路径。站点页面会挂在/blog/下,根路径/将不再返回站点内容; - 独立 Admin URL 使用了同一个子目录——因为 Ghost 的 Admin 与 API 路由始终位于所配置的站点路径之下,二者不能各用各的子目录,否则路由会错位。
第二步:用 URL-testing Compose 覆盖启动 Docker 服务
从仓库根目录执行:
DEV_COMPOSE_FILES="-f docker/dev-url-testing/compose.yaml" \ pnpm nx run ghost-monorepo:docker:up这条命令相当于在默认docker compose -f compose.dev.yaml ... up之上叠加了 docker/dev-url-testing/compose.yaml。该覆盖文件的核心只有一处端口映射:
services: ghost-dev: ports: - '2369:2368'即把 Ghost Core 额外暴露在本机2369端口。这是故意为之:额外启动的 Caddy 进程必须直连 Ghost Core(而不是走默认 2368 的开发网关),Express 才能信任 Caddy 转发的 HTTPS 请求头。如果让请求继续经过默认网关,转发协议信息会在中间层丢失或不被信任,HTTPS 场景就无法真正模拟。
从源码看,根目录 package.json 中的 npm 脚本docker:down与 Nx 目标docker:up/docker:down均通过${DEV_COMPOSE_FILES}环境变量透传额外 Compose 文件,这正是DEV_COMPOSE_FILES前缀能被统一识别的原因;docker:up还会自动dependsOn构建并执行up -d --force-recreate --wait,保证服务就绪后才返回。
第三步:启动本地 TLS 代理
另开一个终端,运行:
caddy run --adapter caddyfile \ --config docker/dev-url-testing/Caddyfile首次运行 Caddy 可能要求输入系统密码——它需要把本地 CA(local_certs)安装进系统信任链,才能为.localhost站点签发并信任证书。仓库中的 docker/dev-url-testing/Caddyfile 内容如下:
{ local_certs http_port 9080 } https://site.localhost:8443 { reverse_proxy http://localhost:2369 { header_up Host site.localhost:8443 } } https://admin.localhost:8443 { reverse_proxy http://localhost:2369 { header_up Host admin.localhost:8443 } }值得逐行解读:local_certs启用本地 CA 自动签发证书;http_port 9080把明文 HTTP 端口改到 9080,避免与环境中其它 80 端口服务冲突;两个站点块分别以各自的主机名反代到localhost:2369(即上一步直连的 Ghost Core),并且通过header_up Host重写 Host 头——这是关键所在:Ghost 依赖 Host 头区分当前请求归属site.localhost还是admin.localhost,从而决定子目录页面与 Admin 路由如何响应,也便于 Express 侧基于该信息处理重定向。
第四步:在浏览器中验证
Caddy 就绪后,打开:
- 站点:
https://site.localhost:8443/blog/ - Admin:
https://admin.localhost:8443/blog/ghost/
重点检查受改动影响的:重定向行为、生成的链接、API 请求、Cookie 与静态资源。一个典型的自检用例:请求站点主机名的/blog/ghost/路径,应当被 301 重定向到 Admin 主机名(即https://admin.localhost:8443/blog/ghost/)。若请求落回站点主机或没有发生重定向,说明独立 Admin URL 配置或 Host 路由未生效。
适用范围与局限
此配置提供的是从 Ghost Core 直接吐出的 Admin 静态资产,它不会走常规 Admin 的 Vite/HMR 开发链路——那个开发服务器的启动探针假定使用默认根 URL,无法在自定义子目录/端口下自举。因此推荐的工作方式是:日常高频小步迭代用下一节的自动化测试兜底,浏览器端最终验证再启这套手动环境。
清理
按Ctrl+C停止 Caddy;然后带着同一个 Compose 覆盖停掉 Docker 服务:
DEV_COMPOSE_FILES="-f docker/dev-url-testing/compose.yaml" pnpm docker:down最后务必删除ghost/core/config.local.json——只要它存在,Ghost 就会继续使用备选 URL,导致回到pnpm dev时站点无法按默认地址访问。该文件虽被 Git 忽略,仍需手动清理。
四、把 URL 配置行为固化为自动化测试
手工环境适合浏览器最终验证,而日常回归与聚焦开发则应交由 HTTP 层的自动化测试。Ghost Core 将高级 URL 配置测试集中在 ghost/core/test/e2e-frontend/advanced-url-config.test.js,适合承载依赖以下三种形态的覆盖:
- HTTPS 站点 URL;
- 站点安装在子目录下;
- Admin 与站点使用不同的 origin(主机/端口)。
在ghost/core目录下运行该文件:
pnpm test:single test/e2e-frontend/advanced-url-config.test.js从该测试文件源码可以读出既有覆盖的形态与断言方式,也便于理解“什么用例应该放这里”:
子目录路由(
url = http://localhost/blog/):断言根路径/返回 404;/blog301 到/blog/;/blog/与/blog/welcome/返回 200;/welcome/(子目录之外)返回 404;/blog/tag/getting-started/200 而/tag/getting-started/404;AMP 路径/blog/welcome/amp/301 而/welcome/amp/404;草稿预览路由/blog/p/<uuid>/返回 200 且Cache-Control为禁止缓存的规则。子目录 + 独立 Admin origin 的重定向(
url = http://localhost/blog/+admin:url = http://admin.localhost/):断言/blog/ghost、/blog/ghost/均 301 到http://admin.localhost/blog/ghost/;Admin API 请求/blog/ghost/api/admin/posts/、/blog/ghost/api/admin/site/也会 301 到 Admin origin 下同路径——证实了“Admin 与 API 路由始终在站点子目录之下、再整体跳转到独立 Admin origin”的架构事实。
测试通过config-utils的configUtils.set('url', ...)/configUtils.set('admin:url', ...)等共享测试配置助手在启动 Ghost 实例前注入配置,并用urlUtils.stubUrlUtilsFromConfig()让 URL 工具从配置重建,最后在afterAll里统一restore。
补充自动化覆盖的准则:当改动可通过 Ghost 的 HTTP 响应、重定向、生成 URL 或路由行为验证时,优先在advanced-url-config.test.js中新增聚焦用例;只有当更低层级的单测足以验证时,才在ghost/core/test/其它测试文件中通过同样的共享配置助手设置url与admin:url。这样既能保持高级 URL 形态的 HTTP 层回归集中在一处,又能避免不必要的 e2e 开销。
五、方案选型速查
| 需要验证的场景 | 推荐方案 | 核心配置/命令 |
|---|---|---|
| 在另一台设备/浏览器打开站点与 Admin | ngrok 等 HTTPS 隧道打在网关 | ngrok http 2368;必要时用 config.local.json 覆盖url |
HTTPS +/blog/子目录 + 独立 Admin URL 三合一浏览器验证 | Caddy +.localhost+ Compose 覆盖 | config.local.json、docker/dev-url-testing/compose.yaml、Caddyfile |
| 子目录路由、独立 Admin origin 重定向的持续回归 | HTTP 层自动化测试 | advanced-url-config.test.js,pnpm test:single运行 |
无论选择哪条路径,通用纪律始终一致:临时配置一律放ghost/core/config.local.json,绝不提交;测试结束清掉覆盖文件并关闭隧道;保持普通开发环境与 URL 测试环境彼此隔离,按需启停。
【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/Ghost
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考