☰
Phabricator 私有代码审查平台搭建与配置实战
2026/10/14 16:55:33 网站建设 项目流程

1. 为什么我最终选了 Phabricator 而不是其他方案

团队规模到了七八个人之后,代码合并这件事就开始变得微妙了。最开始大家用 Git 自带的邮件列表,后来换成某个轻量级的 Web 端工具,再后来发现每次 Review 都像在玩捉迷藏——谁该看哪个提交、哪条评论对应哪次修改、改完之后谁来点通过,全靠群里喊。这种状态下,一个能集中管理代码审查流程的平台就成了刚需。

市面上能选的方案其实不少。GitLab 自带 Merge Request,功能确实全,但整套装下来资源占用不低,对于只想解决 Review 这一件事的小团队来说有点重。Gerrit 的权限模型和提交规范非常严谨,可学习曲线陡峭,新同事上手要花不少时间。Phabricator 是 Facebook 早年开源的整套研发协作套件,里面包含 Differential(代码审查)、Diffusion(仓库浏览)、Maniphest(任务管理)等模块,可以只启用代码审查相关的部分,资源占用相对可控,而且它的 Review 流程设计得非常清晰——每个提交对应一个 Revision,评论、修改、通过都是围绕这个 Revision 展开的,不会出现"这条评论到底在说哪一版代码"的混乱。

我最终选它的另一个原因是部署确实简单。官方提供了 Docker 镜像,配合 MySQL 和一个后台任务进程,三行核心命令就能把服务跑起来。当然"三行命令"指的是核心启动部分,真正要让邮件提醒、仓库同步、权限配置都正常工作,还需要做一些额外设置。这篇文章就把我从零搭建到日常使用的完整过程拆开讲,包括那些官方文档里一笔带过、但实际会卡住人的细节。

适合读这篇内容的人:手里有一台能跑 Docker 的服务器、团队规模在几人到几十人之间、希望快速拥有一个私有代码审查平台、并且不想在部署上花太多时间的开发者或运维同学。如果你完全没接触过 Docker,建议先补一下基础概念,否则后面挂载目录和端口映射的部分会有点吃力。

2. 部署前的环境盘点与镜像选型

2.1 服务器配置的最低门槛与推荐值

Phabricator 本身是 PHP 写的,对 CPU 要求不高,但它依赖 MySQL 存储元数据,而且后台有一堆守护进程要跑(比如仓库同步、邮件发送、任务队列)。我实测下来,2 核 4G 的机器跑起来会有点喘,尤其是仓库稍微大一点、或者同时有几个人在页面上操作的时候。推荐配置是 4 核 8G,磁盘至少 40G 起步,因为仓库镜像和附件都会占空间。

操作系统方面,只要宿主机能装 Docker 和 Docker Compose 就行,我用的是常见的 Linux 发行版,内核版本不要太老。这里有个容易忽略的点:Phabricator 对时间同步比较敏感,如果服务器时间漂移太大,邮件里的时间戳和仓库提交时间会对不上,排查问题时很误导人。部署前先确认 NTP 服务是正常工作的。

2.2 镜像选择:官方镜像与社区维护版的差异

Docker Hub 上能搜到好几个 Phabricator 相关的镜像。官方曾经维护过一个,但后来更新频率降低了。社区里有几个活跃度不错的维护版本,它们的好处是基础依赖更新得更勤,PHP 版本和扩展都配好了。我选的是一个基于较新 PHP 版本构建的镜像,省去了自己写 Dockerfile 装扩展的麻烦。

选镜像的时候重点看几个东西:一是它默认的 Web 根目录在哪里,二是它期望的 MySQL 连接参数通过什么方式传入,三是它有没有内置对仓库同步工具的支持。这三点决定了你后面配置文件怎么写。我用的这个镜像把配置集中在几个环境变量里,启动时自动生成配置文件,对新手比较友好。

提示:不要用 latest 标签,尽量锁定一个具体的版本号。Phabricator 的数据库结构在不同版本间可能有变化,锁定版本能避免某天重新拉镜像后服务起不来的尴尬。

2.3 目录规划:数据持久化到底要挂哪些路径

容器一删数据就没,所以持久化必须做。需要挂载出来的主要有三块:MySQL 的数据目录、Phabricator 的仓库存储目录、以及配置文件目录。我习惯在宿主机上建一个统一的项目目录,比如/opt/review-platform,下面再分mysql-data、repos、config三个子目录。

仓库目录尤其重要,因为所有被 Review 的代码仓库都会以镜像形式存在这里。如果这个目录丢了,虽然元数据还在数据库里,但仓库内容要重新同步,大仓库同步一次可能要很久。配置文件目录则是方便你改完配置后重启容器生效,不用进容器里面改。

3. 三行核心命令背后的完整启动流程

3.1 第一行:准备 MySQL 容器

Phabricator 需要一个 MySQL 实例来存数据。我直接用 Docker 跑一个 MySQL 容器,和 Phabricator 放在同一个自定义网络里,这样它们可以通过容器名互相访问,不用暴露数据库端口到公网。

docker run -d --name phab-mysql \ --network phab-net \ -e MYSQL_ROOT_PASSWORD=你的强密码 \ -e MYSQL_DATABASE=phabricator \ -v /opt/review-platform/mysql-data:/var/lib/mysql \ mysql:8.0 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

这里有几个细节值得说。字符集必须设成 utf8mb4,否则中文评论和 emoji 会出问题。数据库名我直接指定为 phabricator,省得后面再建。密码别用简单的,因为这个容器虽然不暴露端口,但同网络内其他容器是能访问的。--network phab-net要求你先创建这个网络,命令是docker network create phab-net,这算是个前置步骤,但很多教程会漏掉。

3.2 第二行:启动 Phabricator 主容器

主容器负责跑 Web 服务和后台守护进程。启动命令大概长这样:

docker run -d --name phabricator \ --network phab-net \ -p 8080:80 \ -e MYSQL_HOST=phab-mysql \ -e MYSQL_USER=root \ -e MYSQL_PASS=你的强密码 \ -e PHABRICATOR_HOST=你的域名或IP:8080 \ -v /opt/review-platform/repos:/var/repo \ -v /opt/review-platform/config:/config \ 镜像名:版本号

端口映射我用了 8080,你可以按需改成 80 或其他。PHABRICATOR_HOST这个环境变量很关键,它决定了页面里生成的链接地址,如果填错,邮件里的链接点开会是错的。仓库目录挂到/var/repo,这是镜像约定的路径,具体以你选的镜像说明为准。

3.3 第三行:初始化数据库与管理员账号

容器起来之后,数据库还是空的,需要执行初始化。不同镜像的初始化方式不一样,有的在容器启动时自动跑迁移,有的需要你手动进容器执行命令。我用的这个镜像需要手动触发一次:

docker exec -it phabricator /app/bin/storage upgrade --force

这条命令会创建所有需要的表结构。跑完之后,访问http://你的地址:8080,应该能看到登录页。第一个注册的账号会自动成为管理员,所以初始化完成后要立刻去注册,别让其他人抢先了。

注意:初始化命令执行时间可能比较长,取决于服务器性能,几分钟到十几分钟都有可能。期间不要中断,否则数据库可能处于半初始化状态,后面会报各种奇怪的错。

4. 邮件提醒配置:让 Review 通知真正送达

4.1 为什么邮件提醒是 Review 流程的命脉

代码审查最怕的就是"提交了但没人看"。如果每次有新的 Revision 或者有人评论了,相关人能立刻收到邮件,整个流程的流转速度会快很多。Phabricator 的邮件系统支持 SMTP,配置好之后可以自动发送各种通知:新提交、新评论、状态变更、被指派为 Reviewer 等等。

配置邮件之前,你需要有一个可用的 SMTP 服务。可以是企业邮箱提供的 SMTP,也可以是自建邮件服务。我建议用企业邮箱的 SMTP,因为送达率相对有保障,而且配置简单,只需要知道服务器地址、端口、账号密码就行。

4.2 在 Phabricator 里配置 SMTP 的完整步骤

登录管理员账号后,进入 Config 模块,找到邮件相关的配置项。核心要填的有这么几个:

  • metamta.mail-adapter:选择PhabricatorMailImplementationPHPMailerAdapter,这是走 SMTP 的适配器。
  • phpmailer.smtp-host:SMTP 服务器地址。
  • phpmailer.smtp-port:端口,通常是 465(SSL)或 587(TLS)。
  • phpmailer.smtp-user:登录账号。
  • phpmailer.smtp-password:登录密码或授权码。
  • phpmailer.smtp-protocol:选ssl或tls,要和端口匹配。
  • metamta.default-address:发件人地址,比如review@你的域名。

填完之后,Config 页面通常会提供一个"发送测试邮件"的按钮,点一下,填个收件地址,看能不能收到。收不到的话,先检查端口和协议是否匹配,这是最常见的坑。465 配 ssl,587 配 tls,配反了就连不上。

4.3 邮件发不出去时的排查顺序

如果测试邮件失败,按这个顺序查:第一,确认容器能访问外网,有些服务器默认限制出站连接;第二,确认 SMTP 账号密码正确,很多邮箱用的是授权码而不是登录密码;第三,看 Phabricator 的日志,日志里会记录具体的 SMTP 错误信息,比如认证失败还是连接超时;第四,检查发件人地址是否被 SMTP 服务允许,有些服务要求发件人地址必须和登录账号一致。

我遇到过一种情况:SMTP 配置全对,但邮件就是发不出去,最后发现是服务器防火墙把出站的 465 端口拦了。换成 587 端口就通了。所以端口不通的时候,不妨换个端口试试。

5. 仓库接入与 Review 流程跑通

5.1 把代码仓库导入 Phabricator

Phabricator 的仓库管理在 Diffusion 模块里。你可以新建一个仓库,然后让它从现有的 Git 地址拉取镜像。支持 HTTP 和 SSH 两种方式,如果仓库是私有的,需要配置对应的凭据。

新建仓库时,Phabricator 会问你仓库类型,选 Git。然后填上游地址。如果上游需要认证,在 Credentials 里先建一个凭据,填用户名和密码或密钥。建好之后,Phabricator 会启动一个后台任务去拉取仓库,拉取进度可以在仓库详情页看到。

仓库拉下来之后,你可以在 Diffusion 里浏览代码、查看提交历史。但要让 Review 流程跑起来,还需要配置一个东西:仓库的"自动关闭"规则和 Herald 规则。Herald 是 Phabricator 的规则引擎,可以设置"当有人提交代码时,自动创建 Revision 并指派 Reviewer"。

5.2 发起第一个 Revision 的两种方式

发起代码审查有两种常见方式。一种是通过命令行工具 Arcanist,在本地提交时用arc diff命令,它会自动创建一个 Revision 并把 diff 上传上去。另一种是直接在 Web 界面上传 diff 文件。Arcanist 的方式更流畅,适合日常开发;Web 上传适合临时改个小东西。

Arcanist 需要先在本地安装,然后配置好 API Token。Token 在 Phabricator 的个人设置里生成。配置好之后,在 Git 仓库里执行arc diff,它会引导你填写标题、描述、Reviewer 等信息,然后创建 Revision。Reviewer 会收到邮件通知,点进链接就能看到 diff、留评论、点通过或要求修改。

5.3 Review 状态流转与常见操作

一个 Revision 的生命周期大概是:Draft(草稿)→ Needs Review(待审查)→ Needs Revision(需修改)或 Accepted(已通过)→ Closed(已关闭)。Reviewer 可以留行内评论,针对具体某一行代码。提交者根据评论修改后,再次arc diff会更新同一个 Revision,Reviewer 能看到新旧版本的差异。

这里有个实用技巧:如果某个 Reviewer 一直没响应,可以在 Revision 上重新指派或者加人。Phabricator 支持多个 Reviewer,只要有一个点了 Accept,并且没有其他人反对,就可以合并。合并操作可以在 Web 界面上点按钮完成,也可以用arc land命令在本地合并并推送。

6. 日常使用中积累的配置心得与避坑记录

6.1 权限模型:别让所有人都能改所有东西

Phabricator 的权限控制比较细,默认情况下新用户权限有限。建议建几个用户组,比如"开发者"、"Reviewer"、"管理员",然后针对仓库和项目分别授权。仓库的读权限可以放开给所有登录用户,但写权限要控制。Reviewer 组的人应该有权限点 Accept,普通开发者只能提交 Revision。

有个容易踩的坑:如果你把仓库的写权限收得太紧,arc land会失败,因为推送被拒绝了。所以要么给开发者推送权限,要么统一由有权限的人来合并。我们团队的做法是开发者只有提交 Revision 的权限,合并由 Reviewer 在 Web 上点按钮完成,这样能保证每次合并都经过审查。

6.2 后台守护进程挂了会怎样

Phabricator 依赖几个后台进程来处理异步任务,比如发邮件、拉仓库、跑 Herald 规则。这些进程如果挂了,表现是:邮件不发、仓库不更新、规则不触发。排查方法是进容器看进程状态,或者看 Phabricator 的 Daemon 日志。

我遇到过一次邮件突然不发了,查了半天 SMTP 配置没问题,最后发现是后台进程因为内存不足被系统杀掉了。给容器加了内存限制并重启后恢复正常。所以服务器内存不要太抠,留点余量给这些后台进程。

6.3 备份策略:数据库和仓库目录一个都不能少

备份分两块:MySQL 数据库和仓库存储目录。数据库可以用mysqldump定期导出,仓库目录直接打包或者用 rsync 同步到另一台机器。恢复的时候,先恢复数据库,再把仓库目录放回原位置,然后重启容器。

建议把备份脚本写成定时任务,每天跑一次。数据库 dump 出来的文件不大,仓库目录可能比较大,可以增量同步。我试过只备份数据库不备份仓库,结果有次磁盘故障,仓库全丢了,虽然代码在开发者的本地还有,但 Review 历史全没了,挺可惜的。

6.4 性能调优的几个小开关

如果感觉页面加载慢,可以调整几个地方。一是给 PHP 开 OPcache,这个在镜像里通常已经配好了。二是调整 MySQL 的缓冲池大小,默认值偏小。三是如果仓库特别大,可以关闭一些不必要的后台同步任务,减少资源占用。

另外,Phabricator 的搜索功能依赖一个全文索引服务,如果没配,搜索会走数据库全表扫描,很慢。小团队可以先用数据库搜索顶着,人多了再考虑上专门的索引服务。

7. 从搭建到用顺手的几个关键节点

整套东西跑起来之后,真正让团队用顺手还需要一点推动。我的经验是,先自己用一周,把流程跑通,然后拉一两个核心同事一起用,收集反馈调整配置,最后再全员推广。推广的时候做个简单的内部文档,把arc diff的用法、Review 的规则、常见问题写清楚,能省掉大量重复答疑。

Phabricator 的界面初看有点老派,但功能确实扎实。它的 Review 流程设计得很严谨,每个评论、每次修改都有迹可循,对于需要追溯"这个改动为什么被通过"的场景特别有用。而且整套系统跑在自己的服务器上,代码和数据都在自己手里,心里踏实。

如果你也在为团队找代码审查方案,不妨按上面的步骤试一遍。三行核心命令确实能把服务跑起来,但真正让它好用的,是后面那些邮件配置、权限调整、流程约定的细节。这些细节花的时间,会在日后的每一次代码合并里省回来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询