首页
/ Ghost 代码库开发指南:从零搭建 Ghost Monorepo 本地开发环境与代码库导航

Ghost 代码库开发指南:从零搭建 Ghost Monorepo 本地开发环境与代码库导航

2026-09-08 15:42:43作者:吴年前Myrtle

本文是面向所有想在 Ghost 代码库上做贡献、阅读源码或二次开发的技术人员的入门指南。Ghost 是一个面向现代出版、会员订阅与邮件通讯的开源发布平台,其仓库是一个由 pnpm + Nx 组织的大型 Monorepo。本文以仓库根目录的 代码库文档索引 为主线,讲解如何从零克隆、安装依赖并启动完整的本地开发环境(含 MySQL、Redis、邮件捕获与 Admin/Portal 热更新),随后剖析整个仓库的目录结构与各工作区的职责划分,最后给出贡献流程、测试策略与发布节奏,并串联出阅读源码所需的全部代码库指南。读完本文,你将具备独立跑通 pnpm dev 开发链路、准确定位 Ghost Core / Admin / Koenig / 公共前端应用等代码,并按其规范提交改动与测试的能力。

这篇文档是什么:代码库开发者的一站式入口

Ghost 的 docs/ 目录是代码库文档(codebase docs),它面向的目标人群是"要在 Ghost 代码库上工作"的开发者,而不是自托管用户或主题作者(后者的资料在 Ghost 的官方文档站点)。根目录下的 docs/README.md 正是这组文档的索引与总纲,它同时承担三种职责:

  1. 提供最快跑起开发环境的 Quick Start 命令;
  2. 给出仓库整体结构的总览图;
  3. 以分类目录的形式索引全部 20+ 篇开发指南(代码库架构、工程实践、贡献流程、参考手册)。

换句话说,无论你想理解 Ghost 的运行时架构,还是想改 Admin 某个组件、提交一篇翻译,这个文件都是你首先应该打开的地图。整个 docs/ 目录的组织情况如下(可通过 docs/ 目录树确认):

  • docs/codebase/ —— 架构类:运行时架构、认证、配置、数据库、内部缓存、任务系统等;
  • docs/contributing/ —— 流程类:开发环境搭建、E2E 测试、Stripe/邮件测试、发布等;
  • docs/practices/ —— 规范类:API 设计、数据库迁移、错误处理、特性开关、国际化;
  • docs/reference/ —— 参考类:Node.js 版本兼容表。

Quick Start:两条命令跑起整个 Ghost

文档开篇给出了极简的启动路径。完整的环境要求请见 development-setup.md 的前置条件,核心包括 Git、Node.js 22.23.1(版本记录在仓库根目录的 .nvmrc.node-version)、带 Docker Compose v2 的 Docker,以及随 Node 发行版自带的 Corepack。默认环境会占用 8023683306637980258026 端口,启动前需要停掉占用这些端口的本机服务。

git clone --recurse-submodules https://gitcode.com/GitHub_Trending/gh/Ghost
cd Ghost

pnpm setup
pnpm dev

逐一拆解这三步的实际作用:

  • git clone --recurse-submodules:Ghost 仓库包含 Git 子模块,因此克隆时就要递归拉取。如果忘记带 --recurse-submodules 也没关系,pnpm setup 会自动初始化它们。
  • pnpm setup:对应根 package.json 中的 setup 脚本,它执行 pnpm installgit submodule update --init --recursive 并设置 blame.ignoreRevsFile。文档建议在首次克隆后、以及每次切换分支导致 workspace 依赖或子模块变化后都运行一次。
  • pnpm dev:根 package.json 中该命令会经由 Nx 启动 Docker Compose 开发环境(目标定义在 package.jsondocker:dev 中),它在后台拉起 Ghost Core、MySQL、Redis、Mailpit 容器,以及一个挂在 http://localhost:2368 的 Caddy 网关,同时在本机启动 Admin 与 Portal 的开发监听(watch)进程。首次运行需要构建开发镜像,耗时会长于后续启动。

等 Docker Compose 报告服务健康后,即可访问三个核心地址:

  • 主站:http://localhost:2368
  • 管理后台:http://localhost:2368/ghost/
  • 开发邮件:http://localhost:8025

首次启动且数据库为空时,Admin 会进入 Ghost 的安装(setup)界面,需要你在本地创建一个 owner 账号——开发环境不预设共享登录凭据。这也是一个很好的健康检查点:如果站点与 Admin 都能正常打开,且 docker compose -f compose.dev.yaml ps 显示各服务 running/healthy,环境就算跑通了。按 Ctrl+C 可停止监听进程与容器,但 Docker 卷会保留数据库和上传的开发内容,因此再次启动不需要重新初始化。

访问开发环境中的各项服务

pnpm dev 起的不只是一个 Node 进程,而是一整套与生产形态接近的本地服务矩阵。完整的端口分配见 development-setup.md 的服务表,摘录关键几项:

服务 地址 / 端口 说明
Ghost 站点 http://localhost:2368 Caddy 网关入口
Ghost 站点(网关别名) http://localhost 同网关的 80 端口别名
Ghost Admin http://localhost:2368/ghost/ 后台管理界面
Mailpit http://localhost:8025 开发邮件捕获
Mailpit(E2E) http://localhost:8026 供浏览器 E2E 使用
MySQL localhost:3306 使用 ghost_dev 数据库
Redis localhost:6379 缓存等用途

额外说明:Tinybird(http://localhost:7181)、MinIO 控制台(http://localhost:9001)与 S3 API(http://localhost:9000)只在启用对应开发变体时才拉起(见下文)。

开发变体:按工作对象选择启动命令

Quick Start 的 pnpm dev 覆盖了 Ghost Core / Admin / Portal 三类常见工作,但仓库里还准备了按功能叠加的变体命令(同样定义在 package.json 中),根 package.json 里的 dev:publicdev:lexicaldev:stripe 等都通过追加 Docker Compose 文件(DEV_COMPOSE_FILES 环境变量)或外层包装脚本来扩展基础环境:

命令 适用场景
pnpm dev Ghost Core、Admin、Portal
pnpm dev:public Comments UI、Signup Form、Search、Announcement Bar、Admin Toolbar 等公共前端
pnpm dev:lexical 在 Ghost Admin 内联开发 Koenig 的 Lexical 编辑器
pnpm dev:analytics 基于 Tinybird 的流量分析(使用最新发布版 Traffic Analytics 服务)
pnpm dev:analytics:local 基于 Tinybird 的分析,但接入你本地运行的 Traffic Analytics
pnpm dev:storage 通过 MinIO 模拟 S3 存储(端口 9000/9001)
pnpm dev:stripe 按生产形态接收 Stripe webhook
pnpm dev:mailgun 走 Mailgun API 的真实邮件投递
pnpm dev:full 公共前端 watcher + 分析 + 存储 + Stripe 全集

一次只运行一个根命令。仅当需要某个可选集成时才复制根目录 .env.example.env,且永远不要把凭据或本地 .env 提交进仓库

数据与邮件:填充开发站点与验证邮件

创建本地 owner 账号后,可以用 pnpm reset:data 生成稳定的示例数据:它会清空开发数据库但保留 owner,然后创建 1,000 名会员与 100 篇文章。pnpm reset:data:empty 则生成一个空站点。这两个命令都有破坏性,且需要开发环境在运行;更大的自定义数据集可参考 test-data.md

开发中的邮件默认被 Mailpit 捕获而不会真实投递,打开 http://localhost:8025 即可查看。需要 Mailgun 真实投递或自动化邮件测试时,参见 email testing。若在开发数据库迁移功能,可用 pnpm migrate:db 把待应用的迁移同步到运行中的开发库。

Repository Structure:看懂 Monorepo 的顶层地图

Quick Start 之后,原文档给出了仓库结构的 ASCII 总览。将这个总览与 monorepo 结构指南 结合,可以得到更完整的图景。仓库是 pnpm workspace,而构建、lint、测试与开发任务由 Nx 依据 workspace 依赖图调度执行。哪些目录是工作区,由根目录 pnpm-workspace.yamlpackages 字段(ghost/*apps/*koenig/*packages/**configs/*e2escripts 等)作为唯一事实来源决定。

顶层目录一览

目录 内容
apps/ Admin 应用、公共浏览器应用与前端库
ghost/core/ Ghost 服务端、前端渲染、迁移与服务器测试
koenig/ Koenig 编辑器及内容存取/转换/渲染的 kg-*
packages/ 共享库、schema、翻译、测试数据与适配器契约
configs/ 共享的 ESLint、TypeScript、Vite、Vitest 配置包
e2e/ 覆盖完整 Admin 与公网站点旅程的 Playwright 测试
docker/ 本地开发与 CI 的容器与支撑服务
scripts/ 仓库设置、校验、构建与发布工具

前端应用(apps/)

apps/ 下包含几类前端工程,它们的运行与打包方式各不相同:

  • admin/ —— 新的 React Admin 应用,同时 activitypub/ 是以 React 编写的、随 Admin 一同发布的 ActivityPub 应用;
  • ember-admin/ —— 遗留的 Ember Admin,路由正在逐步从 Ember 迁移到 React,两者被整合进同一个管理界面,集成边界见 apps/admin/README.md
  • portal/comments-ui/signup-form/sodo-search/announcement-bar/admin-toolbar/ —— 发布到 npm、再通过 CDN 以 script 标签加载的公共应用,它们在运行时从 DOM data-attribute 读取配置,由 Ghost Core 通过 {{ghost_head}}{{comments}} 等主题 helper 渲染注入;
  • shade/ —— 现行 Admin 设计系统(design system),此外 admin-x-framework/ 提供 Admin 共享的 API hooks、路由与工具。

Ghost Core(ghost/core/)

ghost/core/ 是主 ghost 包,其中最常用的路径包括:

路径 内容
ghost/core/core/server/ API、模型、服务、数据访问与服务端启动
ghost/core/core/frontend/ 主题渲染、helpers、中间件与公共资源
ghost/core/core/shared/ 跨 server 边界共享的配置与代码
ghost/core/content/ 默认主题、适配器、设置、图片与运行时内容
ghost/core/test/ 单元、集成与服务器 E2E 测试

注意 built/build/dist/umd/ 属于构建产物——Admin 的构建产物会被拷贝进 ghost/core/core/built/admin/ 参与发布,这些目录除非就近 README 有说明,否则不应手工改动。

Koenig、共享包与配置

koenig/ 容纳 Lexical 编辑器 UI 与用于存储、转换、渲染 Ghost 内容的 kg-* 包;这些包已并入本仓库并作为本地 workspace 依赖使用,编辑器被打包进 Admin,Ghost Core 也消费其中的服务端包做内容转换渲染。新增内部包应以 packages/_template/ 为起点(该模板本身被排除出 workspace)。

packages/ 内的适配器基包(storage、scheduling、redirects、caching 等)定义了可替换服务的契约;configs/ 里的配置包被各 workspace 按包名依赖,而不是把配置复制进每个工程。依赖管理上,仓库内部包用 workspace: 版本本地链接,外部依赖版本则统一收口在 pnpm-workspace.yamlcatalog 目录中,用 catalog: 引用以避免多包重复写版本。

源码与生产构建:source 条件导出

从源码结构可以注意到一个重要机制:部分 TypeScript 包同时暴露 source 导出条件与编译产物。Ghost Core 的开发服务器与测试开启 source 条件,能直接加载 @tryghost/kg-default-nodes 这类包的原始 TypeScript,改完即生效;而生产构建不开启该条件,使用的是 build/ 下的编译产物。Koenig 已发布的 kg-* 包保留了 ESM(build/esm/)+ CommonJS(build/cjs/)双输出作为既有公共契约。这带来的实操提示是:源码改动在开发环境可能即时生效,但发布产物仍需要 pnpm build——当你改了包导出、构建配置或会进入发布物的代码时,务必跑一次构建。

Nx 任务与常用命令

Nx 会读取包依赖图并按依赖顺序执行任务——例如构建某工程前会先构建它所依赖的工程,同时会缓存声明过的任务输出。仓库根 package.json 中暴露了大量以 Nx 为后端的命令,日常高频使用这些:

pnpm dev              # 启动完整 Docker 开发环境(含 watcher)
pnpm check            # 一站式检查:格式 + lint + 测试
pnpm lint             # 批量运行 lint 与 lint:boundaries
pnpm test             # 批量运行单元/集成测试
pnpm nx show projects # 列出全部 workspace 工程
pnpm nx graph         # 可视化依赖图
pnpm nx run <project-name>:<target>

其中根命令 pnpm buildpnpm lintpnpm test 都是通过 Nx 对全仓库匹配 target 的任务批量执行。若要单独查看某工程的依赖图信息,可用 pnpm nx show project <project-name>

贡献与开发工作流

代码库文档明确区分了两类读者:想贡献代码的人和想深入源码的人。贡献前应阅读 .github/CONTRIBUTING.md(贡献指南)与 .github/CODE_OF_CONDUCT.md(社区行为准则)。仓库根目录 .github/ 下真实存在这两个文件(另有 SUPPORT.md、issue/PR 模板与 CI workflows)。

官方推荐的标准开发流程是:

  1. 克隆仓库(含子模块);
  2. 创建分支承载你的改动;
  3. 编写改动并附上测试
  4. 运行 pnpm check 确保一切通过;
  5. 按提交信息约定提交
  6. main 分支提交 Pull Request

其中"寻找可做的问题"在文档中通过 Good First IssuesHelp Wanted 两类标签索引,前者适合新手入门。更多流程细节参见 贡献工作流指南

测试策略:就近写测试,pnpm check 兜底

pnpm check 是文档钦点的"一站式"命令——从根 package.json 可以看到它实际等价于 pnpm format:check && pnpm lint && pnpm test,即依次完成格式化检查、代码规范与全部(除 E2E/Admin 之外的)测试。

实践上遵循两条原则:

  • 把测试加在离你改动行为最近的那一层——改 API 层就写对应的服务/集成测试,改前端组件就写该组件的组件测试;
  • 浏览器端到端测试与 Ember Admin 测试不包含在 pnpm check,它们作为独立的测试跑道单独运行。

具体如何选择测试套件、如何运行聚焦的单项测试、如何接入浏览器与 Ember Admin 测试跑道,可进一步阅读 testing 指南e2e-testing 指南;本仓库的浏览器 E2E 位于 e2e/,是一套覆盖完整 Admin 与公网站点旅程的 Playwright 测试。

发布节奏与兼容性纪律

Ghost 在 Ghost(Pro) 上对 Admin 采用持续交付:每次合入 main 的 Admin 改动都可能在下一个服务器版本发布前就上线。因此贡献者必须让 Admin 持续兼容仍在线运行的各个服务器版本。面向公众的 Ghost 版本则每周二同时发布 Admin 与服务器。某次改动何时到达 Ghost(Pro)、自托管安装、npm、jsDelivr 或 Docker 官方镜像,参见 shipping 指南

指南地图:按需深入六大主题

docs/ 的定位是"代码库本身的地图",因此每个子系统都配有一篇聚焦指南。按你的目标选取:

架构与运行原理(docs/codebase/

工程实践与贡献流程(docs/practices/docs/contributing/

参考手册(docs/reference/

与代码库源码相互印证

选一篇指南与源码对照阅读是理解 Ghost 最快的路径。以配置系统为例: configuration.md 指出 Ghost Core 用 nconf 合并 10 层配置来源(内部 override、命令行参数、密钥文件、环境变量、config.<NODE_ENV>.json、Docker 默认值、config.local.jsonconfig.local.jsonc、环境默认值、全局默认值),其加载器与共享配置都位于 ghost/core/core/shared/config/,且配置只在进程启动时读取,因此改动配置后必须重启进程。再如数据库迁移,文档与 scripts 以及根 package.jsonmigrate:db / rollback:db / reset:db 命令相互印证,形成"文档—源码—命令"三层的完整证据链。

故障恢复与日常维护命令速查

当环境出现依赖或 Nx 状态不一致时,原文档的 development-setup.md 提供了分级恢复策略:

pnpm setup          # 依赖/子模块变化后重新安装并初始化
pnpm fix            # 修剪 pnpm store、清空 node_modules 并重装、重置 Nx
pnpm nx reset       # 仅清 Nx 缓存
pnpm build:clean    # 清 Nx 缓存与 Ghost 构建产物
pnpm docker:down    # 停掉非 pnpm dev 进程托管的容器
pnpm docker:clean   # 彻底移除开发容器、卷与本机构建镜像(会清库!)

其中 pnpm fix(对应根 package.json)适合切换分支后依赖状态错乱的场景;pnpm docker:clean 会删除本地开发数据库与上传内容,是保数据场景下的最后手段。启动失败时先查 docker compose -f compose.dev.yaml psdocker compose -f compose.dev.yaml logs SERVICE-NAME,优先排查端口占用、Docker 守护进程异常与过期依赖。开始新工作前,也建议先拉取最新 main 并重新 pnpm setup

结语:从 Quick Start 到源码深潜

docs/README.md 表面看只是一个入口页,但它精准定义了进入 Ghost 代码库的三层路径:先跑起来pnpm setup && pnpm dev,配套服务表与开发变体)、再认结构apps/ghost/core/koenig/packages/ 的职责边界与 workspace/Nx 协作机制)、最后按需深潜(六大类指南把架构、实践、测试与发布方法论精确锚定到对应目录与源码)。Ghost 采用 MIT 开源许可(见仓库根 LICENSE)。后续如需更深度的主题,推荐从 runtime-architecture.mdconfiguration.md 起步,再把 monorepo-structure.md 当作你浏览代码时的随身地图。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391