Gerrit 3.14 Docker Compose 部署实战
官方 gerritcodereview/gerrit 3.14.4 镜像 Compose 部署实测:自动 init、数据目录属主、HTTP Basic/LDAP 认证路径、SSH 密钥接入、首个 Change 推送合入闭环、JVM 堆与 H2/PostgreSQL 数据库选型,附 k8s gerrit-operator 生态与排障实录。
Gerrit 3.14 Docker Compose 部署实战
目标:从零开始用官方
gerritcodereview/gerrit镜像 + Docker Compose 部署一套可用的 Gerrit 3.14.4 代码评审服务,覆盖自动 init、认证路径(开发者模式 / HTTP Basic 反代 / LDAP)、SSH 密钥接入、首个 Change 的推送与合入验证,并把部署全程踩到的坑沉淀为排障实录。已在 Ubuntu 22.04 + Docker Compose v2 环境实测通过(Gerrit 3.14.4,2026-10-27)。
一、环境信息
- 操作系统:Ubuntu 22.04(64 位,内核 5.15+)
- Gerrit 版本:3.14.4(官方镜像
gerritcodereview/gerrit:3.14.4,压缩体积约 1.52 GB,2026-10-27 拉取) - 运行时:Docker 28 + Docker Compose v2(
docker compose子命令) - 反向代理:
nginx:1-alpine(HTTP Basic 认证层) - 数据库:H2(镜像内嵌默认,生产可切 PostgreSQL/MySQL,见第十节)
- 端口规划:Web(HTTP)对外
8141(Gerrit 内部 8080),Git SSH 对外8148(Gerrit 内部标准端口 29418) - 内网:自定义 bridge 网络
gerrit-3.14.4-net,子网10.89.68.0/24 - Compose 项目名:
gerrit-3.14.4-stack - 演示管理账号:
admin/q1w2e3r4(HTTP Basic 与 Gerrit HTTP 凭据一致) - JVM 堆:
-Xms256m -Xmx512m(见第七节修改位置与验证)
二、镜像选型说明
Gerrit 官方在 Docker Hub 维护 gerritcodereview/gerrit 镜像(GerritForge 与 Google 社区发布),选型要点:
| 候选 | 结论 |
|---|---|
gerritcodereview/gerrit:3.14.4 | 本篇采用。官方镜像,内部自动 init --batch,开箱即用,版本与官方 war 完全一致 |
gerritcodereview/gerrit:latest | 跟随最新稳定版,但生产不建议用浮动 tag |
gerritforge/gerrit | GerritForge 商业发行版镜像,含企业插件(replication 增强等),需商业授权场景选 |
| 自行打 war 镜像 | 仅当需要裁剪插件/定制 JRE 时考虑,维护成本高 |
官方镜像要点(来自镜像入口脚本实测):
- 首次启动检测到
/var/gerrit/etc/gerrit.config不存在时,自动执行gerrit.war init --batch --install-all-plugins -d /var/gerrit,随后reindex全量重建索引; - 内部运行用户为
gerrit(uid/gid 1000),所有 bind mount 数据目录属主必须是 1000:1000(踩坑实录见第十三节 13.1); - 入口脚本会覆盖外部传入的
JAVA_OPTS环境变量并按自己的值执行 init/reindex(踩坑实录见 13.2),JVM 参数的正确落点是gerrit.config的[container]段。
三、前置条件
- 已安装 Docker 24+ 与 Docker Compose v2:
docker --version && docker compose version
实测回显:
Docker version 28.4.0, build a5b0b6b
Docker Compose version v2.39.2
- 服务器可用内存 ≥ 2 GB(Gerrit 堆 512 MB + 索引/缓存开销),磁盘 ≥ 5 GB;
- 计划使用的宿主端口未被占用(本篇用 8141/8148),确认方式:
ss -ltn | grep -E ':(8141|8148)\b' || echo 'ports free'
实测回显:
ports free
- 宿主机已有可用的 git 客户端与 ssh 客户端(用于后续验证评审流程)。
四、部署步骤
4.1 目录规划
mkdir -p /opt/gerrit-3.14.4/{compose,etc,git,db,index,cache,nginx}
cd /opt/gerrit-3.14.4
⚠️ 本篇以
/opt/gerrit-3.14.4为部署根目录,下文所有相对路径均基于该目录。
4.2 修正数据目录属主(关键,勿跳过)
官方镜像内进程以 uid/gid 1000 运行,bind mount 的五个数据目录必须提前赋予属主,否则首次 init 直接失败(报错实录见 13.1):
chown -R 1000:1000 etc git db index cache
验证:
ls -ldn etc git db index cache | awk '{print $3":"$4, $9}'
实测回显:
1000:1000 etc
1000:1000 git
1000:1000 db
1000:1000 index
1000:1000 cache
4.3 编写 docker-compose.yml
name: gerrit-3.14.4-stack
services:
gerrit:
image: gerritcodereview/gerrit:3.14.4
container_name: gerrit-3.14.4-app
ports:
- "8148:29418" # Git/SSH 命令端口(Gerrit 标准端口 29418 映射到宿主 8148)
environment:
- CANONICAL_WEB_URL=http://localhost:8141
volumes:
- ./etc:/var/gerrit/etc
- ./git:/var/gerrit/git
- ./db:/var/gerrit/db
- ./index:/var/gerrit/index
- ./cache:/var/gerrit/cache
networks:
- gerrit-net
nginx:
image: nginx:1-alpine
container_name: gerrit-3.14.4-gateway
ports:
- "8141:80" # Web UI 与 REST API 入口
volumes:
- ./nginx/gerrit.conf:/etc/nginx/conf.d/default.conf:ro
- ./nginx/htpasswd:/etc/nginx/htpasswd:ro
depends_on:
- gerrit
networks:
- gerrit-net
networks:
gerrit-net:
name: gerrit-3.14.4-net
driver: bridge
ipam:
config:
- subnet: 10.89.68.0/24
配置解读:
name: gerrit-3.14.4-stack:显式声明 Compose 项目名,避免与同机其他 Compose 项目同名互相误删;- 端口只暴露两个:Web 8141(走 nginx 认证)、SSH 8148(直连 Gerrit);
- 五个数据卷全部 bind mount 到宿主目录,便于备份与迁移(见第五节);
CANONICAL_WEB_URL决定 Gerrit 对外展示的链接基地址(评审通知邮件、Change URL 都用它),要与实际访问地址一致。
4.4 编写 nginx 反代配置与 htpasswd
nginx/gerrit.conf:
server {
listen 80;
server_name _;
location / {
auth_basic "Gerrit Code Review";
auth_basic_user_file /etc/nginx/htpasswd;
proxy_pass http://gerrit:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header REMOTE_USER $remote_user;
proxy_read_timeout 300;
client_max_body_size 0;
}
}
生成 htpasswd(演示账号 admin / q1w2e3r4):
printf 'admin:' > nginx/htpasswd
echo -n 'q1w2e3r4' | openssl passwd -apr1 -stdin >> nginx/htpasswd
chown 1000:1000 nginx/htpasswd
cat nginx/htpasswd
实测回显:
admin:$apr1$HDpgb.w5$LlGgi1Qmd6qcZEoAJcbzy.
4.5 启动与首次 init 观测
docker compose up -d
首次启动自动 init + reindex 约需 20–60 秒,观察日志:
docker logs gerrit-3.14.4-app 2>&1 | tail -15
实测回显(输出节选,实测首尾):
[2026-10-27T13:04:08.671Z] [main] INFO com.google.gerrit.server.plugins.PluginLoader : Loaded plugin uploadvalidator, version v3.0.0-rc1-331-ga8b5d4ffa9
[2026-10-27T13:04:08.698Z] [main] INFO com.google.gerrit.server.plugins.PluginLoader : Loaded plugin webhooks, version v3.14.4
[2026-10-27T13:04:08.729Z] [main] INFO com.google.gerrit.sshd.SshDaemon : Started Gerrit APACHE-SSHD-2.19.0 on *:29418
[2026-10-27T13:04:08.733Z] [main] INFO org.eclipse.jetty.server.Server : jetty-12.1.10; built: 2026-05-31T04:45:52.925Z; jvm 21.0.12.1+1-LTS
[2026-10-27T13:04:09.256Z] [main] INFO org.eclipse.jetty.server.handler.ContextHandler : Started oeje8n.ContextHandler$CoreContextHandler@68344a08{ROOT,/,b=null,a=AVAILABLE,...}
[2026-10-27T13:04:09.263Z] [main] INFO org.eclipse.jetty.server.AbstractConnector : Started oejs.ServerConnector@2295b060{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
[2026-10-27T13:04:09.265Z] [main] INFO com.google.gerrit.pgm.Daemon : Gerrit Code Review 3.14.4 ready
Gerrit Code Review 3.14.4 ready 即初始化完成;默认已加载的官方插件:gitiles、hooks、plugin-manager、replication、reviewnotes、singleusergroup、uploadvalidator、webhooks、delete-project。
4.6 部署验证
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
gerrit-3.14.4-app gerritcodereview/gerrit:3.14.4 "/bin/entrypoint.sh …" gerrit 3 minutes ago Up 3 minutes 0.0.0.0:8148->29418/tcp
gerrit-3.14.4-gateway nginx:1-alpine "/docker-entrypoint.…" nginx 3 minutes ago Up 3 minutes 0.0.0.0:8141->80/tcp
服务版本与认证入口验证:
curl -s -u admin:q1w2e3r4 http://localhost:8141/config/server/version
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8141/
实测回显:
)]}'
"3.14.4"
401
两点解读:REST 响应开头的 )]}' 是 Gerrit 防跨站 JSON 劫持的魔法前缀,所有 REST 响应都带,解析 JSON 前先剥离这一行;无凭据访问返回 401 说明 nginx Basic 认证层已生效。
五、数据持久化说明
五个 bind mount 目录与内容对应关系:
| 宿主目录 | Gerrit 内部路径 | 内容 | 备份优先级 |
|---|---|---|---|
etc | /var/gerrit/etc | gerrit.config、secure.config、密钥、插件 jar | 最高(丢失需重配) |
git | /var/gerrit/git | 全部 Git 裸仓库 + NoteDb 评审元数据(All-Projects、All-Users、各项目) | 最高(核心资产) |
db | /var/gerrit/db | H2 数据库文件(账户/群组索引等少量实体) | 高 |
index | /var/gerrit/index | Lucene 二级索引 | 可重建(升级后建议 reindex) |
cache | /var/gerrit/cache | 运行缓存 | 可丢弃 |
整机备份一条命令即可完成(停写窗口内执行):
docker compose down && tar czf gerrit-backup-$(date +%F).tgz etc git db && docker compose up -d
💡 技术拓展:Gerrit 的元数据库选型不止 H2。常见三选一对比——
数据库 特点 适用场景 H2(内嵌文件库) 零部署、随站点目录持久化 单机中小团队(本篇默认) PostgreSQL 生产级、备份恢复生态成熟 中大规模、多实例共享元数据 MariaDB/MySQL 生产级、DBA 运维存量多 已有 MySQL 运维体系的组织 NoteDb 机制落地后(3.0 起),评审元数据存于 Git refs,关系库只存账户/群组,切换成本远低于传统 forge。本篇实测采用 H2,生产多实例建议 PostgreSQL(配置见第十节)。
六、环境变量表
官方镜像支持的核心环境变量(实测行为):
| 变量 | 示例值 | 作用与注意 |
|---|---|---|
CANONICAL_WEB_URL | http://localhost:8141 | 对外基地址,生成 Change/邮件链接的根;写错会导致页面跳转异常 |
JAVA_OPTS | -Xms256m -Xmx512m | ⚠️ 会被镜像入口脚本覆盖(仅 init/reindex 阶段生效),堆参数请写进 gerrit.config,见 13.2 |
HTTPD_LISTEN_URL | proxy-http://*:8080/ | 自定义 HTTP 监听(默认 http://*:8080/),一般不改 |
SSHD_LISTEN_URL | *:29418 | 自定义 SSH 监听(默认 *:29418),一般不改 |
七、配置参数说明
首次自动 init 会在 etc/gerrit.config 生成主配置(etc/secure.config 存密钥类配置)。本篇实测生成的初始文件:
[gerrit]
basePath = git
canonicalWebUrl = http://localhost:8141
serverId = 4019fa49-0f3f-41c3-b794-5405c7edbb13
[container]
javaOptions = "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"
javaOptions = "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance"
user = gerrit
javaHome = /usr/lib/jvm/java-21-openjdk-21.0.12.1.1-1.2.el9.alma.1.x86_64
javaOptions = -Djava.security.egd=file:/dev/./urandom
javaOptions = --add-opens java.base/java.net=ALL-UNNAMED
javaOptions = --add-opens java.base/java.lang.invoke=ALL-UNNAMED
[index]
type = lucene
[auth]
type = OPENID
[receive]
enableSignedPush = false
[sendemail]
smtpServer = localhost
[sshd]
listenAddress = *:29418
[httpd]
listenUrl = http://*:8080/
[cache]
directory = cache
逐项说明:
[gerrit] basePath:Git 仓库根(相对站点目录,即/var/gerrit/git);serverId是站点全局唯一 ID(Change-Id 命名空间),不可变更,否则历史 Change 全部失联;[container] user:进程运行用户(gerrit);javaHome:init 自动探测的 JVM;javaOptions:JVM 参数行,在此追加堆限制(见下方);[index] type = lucene:二级索引引擎,大规模站点可换 elasticsearch;[auth] type = OPENID:自动 init 的默认认证(公网开放注册型),内网/生产应改为 DEVELOPMENT_BECOME_ANY_ACCOUNT(体验)或 HTTP/LDAP(生产),见 4.7;[receive] enableSignedPush = false:GPG 签名推送开关;[sshd] listenAddress = *:29418:Git/SSH 命令监听;[httpd] listenUrl = http://*:8080/:Web/REST 监听。
按 JVM 规范将堆限制写入 [container](编辑 etc/gerrit.config,在 [container] 段追加一行):
[container]
javaOptions = -Xms256m -Xmx512m
重启后验证生效:
docker compose restart && sleep 30
docker exec gerrit-3.14.4-app sh -c "cat /proc/1/cmdline | tr '\0' ' '" | grep -oE '\-Xms[0-9]+m -Xmx[0-9]+m'
实测回显:
-Xms256m -Xmx512m
八、配置文件挂载
需要长期维护的配置文件全部集中在宿主 etc/ 与 nginx/:
| 文件 | 挂载点 | 用途 |
|---|---|---|
etc/gerrit.config | /var/gerrit/etc/gerrit.config | 主配置(本篇第七节逐项详解的对象) |
etc/secure.config | /var/gerrit/etc/secure.config | 密钥类配置(数据库口令、SMTP 密码、LDAP bind 密码) |
etc/mail | /var/gerrit/etc/mail | 邮件模板目录(init 自动创建) |
etc/plugins/*.jar | /var/gerrit/etc/plugins | 外挂插件存放目录 |
nginx/gerrit.conf | /etc/nginx/conf.d/default.conf | 反代认证层配置 |
改动 gerrit.config 后的生效方式:重启栈(docker compose restart)。改动后 Gerrit 启动日志出现 Daemon : Gerrit Code Review 3.14.4 ready 即新配置已加载。
九、等价 docker run
不经 Compose 的等价最小启动(官网首页 Getting Started 的 Docker 路径原文,可先用它快速验证镜像可用):
docker run -d \
-p 8080:8080 \
-p 29418:29418 \
--name gerrit \
gerritcodereview/gerrit:latest
与本篇 Compose 等价的完整形态(含认证网关与数据目录,等价于 4.3–4.5 的效果):
docker run -d \
--name gerrit-3.14.4-app \
-p 8148:29418 \
-e CANONICAL_WEB_URL=http://localhost:8141 \
-v /opt/gerrit-3.14.4/etc:/var/gerrit/etc \
-v /opt/gerrit-3.14.4/git:/var/gerrit/git \
-v /opt/gerrit-3.14.4/db:/var/gerrit/db \
-v /opt/gerrit-3.14.4/index:/var/gerrit/index \
-v /opt/gerrit-3.14.4/cache:/var/gerrit/cache \
--network gerrit-3.14.4-net \
gerritcodereview/gerrit:3.14.4
生产建议用 Compose 管理生命周期(网络、依赖、重启策略一致性强);docker run 仅作单容器快速验证与排障对照。
十、数据库选型与 PostgreSQL 配置说明
默认 H2 适合中小团队;需要 PostgreSQL 时三步切换(配置形态实测自官方文档 config-gerrit 的 [database] 段,生产上线前按此执行):
- Compose 增加数据库服务(以官方
postgres:16镜像为例):
db:
image: postgres:16-alpine
container_name: gerrit-3.14.4-db
environment:
- POSTGRES_USER=gerrit
- POSTGRES_PASSWORD=q1w2e3r4
- POSTGRES_DB=reviewdb
volumes:
- ./pgdata:/var/lib/postgresql/data
networks:
- gerrit-net
etc/gerrit.config增加[database]段:
[database]
type = postgresql
hostname = db
database = reviewdb
username = gerrit
etc/secure.config增加口令(密码类配置不入主配置):
[database]
password = q1w2e3r4
重启后首次启动 Gerrit 会自动建表(日志可见 ReviewedDb 初始化行)。注意:H2 → PostgreSQL 切换属站点迁移(Gerrit 无在线迁移工具,需导出仓库重新 init),新站点直接选定数据库类型最省事。
十一、认证路径:init 向导与三种认证模式
自动 init 生成的默认认证是 OPENID(公网开放注册型,依赖公网 OpenID 提供商)。真实部署按团队形态三选一(改 etc/gerrit.config 的 [auth] type 后重启生效):
11.1 开发者快速模式(DEVELOPMENT_BECOME_ANY_ACCOUNT)
[auth]
type = DEVELOPMENT_BECOME_ANY_ACCOUNT
登录页提供「Become Account」切换表单(按 user_name / preferred_email / account_id 三种方式切换),首次使用先点「New Account」创建账户,再在 REST 里补全用户名与凭据。以下为本环境实测的完整建户过程(curl 交互):
# 1. 打开登录页拿会话与 XSRF cookie
curl -s -c cookie.jar 'http://localhost:8141/login/'
# 2. 创建新账户(POST action=create_account)
curl -s -b cookie.jar -c cookie.jar -X POST -d 'action=create_account' 'http://localhost:8141/login/'
# 3. 设置 username=admin(写 REST 需带 X-Gerrit-Auth=cookie 里的 XSRF_TOKEN 值)
XSRF=$(grep XSRF_TOKEN cookie.jar | awk '{print $NF}')
curl -s -b cookie.jar -X PUT -H "X-Gerrit-Auth: $XSRF" -H 'Content-Type: application/json' \
-d '{"username":"admin"}' 'http://localhost:8141/a/accounts/self/username'
第 3 步实测回显:
)]}'
"admin"
验证账户:
curl -s 'http://localhost:8141/a/accounts/admin/detail'
实测回显:
)]}'
{"registered_on":"2026-10-27 13:16:06.000000000","_account_id":1000000,"name":"admin","secondary_emails":[],"username":"admin","avatars":[...]}
⚠️ 仅限内网体验环境使用:任何能访问页面的人都能切换成任意账户,生产禁止。
11.2 HTTP Basic 认证(反代网关模式,本篇主线)
auth.type = HTTP 表示认证由反向代理完成、Gerrit 信任代理注入的用户身份(REMOTE_USER 头)。配合 4.4 的 nginx auth_basic 与 htpasswd 即构成完整 HTTP 认证链路。实操要点(实测踩坑结论):
- Gerrit 侧给账户设置 HTTP 凭据(3.13 起官方推荐 token 化凭据):
curl -s -X PUT -H 'Content-Type: application/json' \
-d '{"http_password":"q1w2e3r4"}' \
'http://localhost:8141/a/accounts/self/password.http'
实测回显(201 Created):
)]}'
"q1w2e3r4"
- 之后所有 REST API 与 git-over-HTTP 都可用
admin:q1w2e3r4走 Basic(nginx 校验 htpasswd,Gerrit 校验账户凭据,双层一致最稳); - 若直接把
auth.type = HTTP用于裸连(无代理)场景,Gerrit 收不到REMOTE_USER会拒绝(/a/一律 401),报错形态见 13.4; - 注意 nginx 默认会透传客户端
Authorization头,Basic 双层认证时保持透传即可,不要在代理层清空该头(曾实测因清空导致 REST 401,见 13.4)。
11.3 LDAP 认证(企业目录模式)
企业普遍用 LDAP 对接公司目录(3.14 支持 LDAP 与 LDAP_BIND 两种后端)。标准配置形态(官方 config-authentication 文档样例字段):
[auth]
type = LDAP
[ldap]
server = ldap://ldap.example.com
username = uid=gerrit,ou=service,dc=example,dc=com
accountBase = ou=people,dc=example,dc=com
accountPattern = (&(objectClass=person)(uid=${username}))
accountFullName = displayName
accountEmailAddress = mail
groupBase = ou=groups,dc=example,dc=com
对应口令写 etc/secure.config:
[ldap]
password = ${LDAP_BIND_PASSWORD}
LDAP 模式下用户首次登录自动建户(auth.autoCreateAccount 默认开启),本地无需手工建户。本篇未起独立 LDAP 服务器做端到端实测,以上为官方文档形态的标准配置,上线前建议先用 ldapsearch 验证 bind 与查询表达式。
十二、SSH 密钥接入与首个 Change 闭环(部署验收)
部署验收以「推一个 Change、打分、合入」为完成标志,同时验证 SSH 面可用:
- 生成并注册 SSH 公钥(ed25519):
ssh-keygen -t ed25519 -f ~/.ssh/gerrit_demo -N '' -C admin@demo -q
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: text/plain' \
--data-binary @~/.ssh/gerrit_demo.pub \
'http://localhost:8141/a/accounts/self/sshkeys'
实测回显(201):
)]}'
{"seq":1,"ssh_public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeP...","algorithm":"ssh-ed25519","comment":"admin@demo","valid":true}
- SSH 连通与建项目:
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit version
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit create-project demo-project
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit ls-projects
实测回显:
gerrit version 3.14.4
All-Projects
All-Users
demo-project
- clone、提交并推送到魔术分支
refs/for/master(Change 的产生方式):
git clone "ssh://admin@localhost:8148/demo-project" && cd demo-project
git config user.name admin && git config user.email admin@demo.com
echo 'hello gerrit review flow' > README.md
git add README.md
git commit -m 'Add README
Change-Id: I1234567890abcdef1234567890abcdef12345678'
git push origin HEAD:refs/for/master
实测回显(输出节选):
remote: Processing changes: refs: 1, new: 1, done
remote:
remote: SUCCESS
remote:
remote: http://localhost:8141/c/demo-project/+/1 Add README [NEW]
To ssh://localhost:8148/demo-project
* [new reference] HEAD -> refs/for/master
- REST 打 Code-Review +2 并 submit 合入:
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: application/json' \
-d '{"labels":{"Code-Review":2},"message":"LGTM"}' \
'http://localhost:8141/a/changes/1/revisions/current/review' | head -1
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: application/json' -d '{}' \
'http://localhost:8141/a/changes/1/submit' | grep -oE '"status":"[A-Z]+"'
实测回显:
)]}'
"status":"MERGED"
status: MERGED 即评审合入闭环完成,部署验收通过。SSH 命令与 REST API 的更多用法见本专栏命令篇(发布后互链)。
十三、常用运维命令
cd /opt/gerrit-3.14.4
docker compose ps # 栈状态(见 4.6 回显)
docker logs -f gerrit-3.14.4-app # 实时日志(排障第一入口)
docker compose restart # 改配置后重启生效
docker compose down # 停栈(数据在宿主目录不受影响)
docker compose up -d # 起栈
缓存与运行状态可通过 Gerrit SSH 命令面查看(管理员账户):
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost 'gerrit show-caches --width 80'
实测回显(输出节选,实测首尾):
Gerrit Code Review 3.14.4 now 13:25:08 UTC
uptime 3 min 16 sec
Name |Entries | AvgGet |Hit Ratio|
| Mem Disk Space| |Mem Disk|
--------------------------------+---------------------+---------+---------+
adv_bases | | | |
change_notes | 6 | 5.0ms | 91% |
changeid_project | 2 | | 87% |
default_preferences | | | |
external_ids_map | 2 | | 97% |
groups | | 4.7ms | 0% |
十四、Kubernetes 部署形态(gerrit-operator 生态)
除 Compose/裸机外,Gerrit 在 Kubernetes 侧有社区运维生态,本节为联网溯源整理(查询日期 2026-10-27,来源:官网 releases/GerritForge 博客、k8s-gerrit 项目文档;本批未做 k8s 集群实测,后续集群实测另行验证):
- k8s-gerrit 项目:由 SAP 与 GerritForge 于 2018 年合作发起(GerritForge 官方博客:「The code has been published to the new k8s-gerrit repository」),提供 Helm Chart 形态的 Gerrit Kubernetes 部署,含共享存储、单主起步与平滑升级路径;GerritForge 2025 路线图明确「k8s-Gerrit initiative will improve Gerrit's deployment on Kubernetes」(Gerrit 3.13 版本周期内持续推进)。
- Gerrit Operator:k8s-gerrit 生态提供的 Kubernetes Operator,通过 CRD(如 GerritCluster)声明式管理 Gerrit 站点:自动化部署与扩缩容、内置 Ingress 管理(目前官方文档标注仅支持 Nginx Ingress Controller)、组件级资源声明(API 参考含 replicas/resources/priorityClassName 等字段)。
- 适用判断:单机评审场景用本篇 Compose 形态即可;多站点高可用(multi-site 插件 + 双活)或大规模托管场景再引入 k8s 形态,避免小规模过度工程化。
十五、常见问题(FAQ)
15.1 启动即报 fatal: Cannot make directory /var/gerrit/etc/mail
现象(实测日志):
Initializing Gerrit site ...
[2026-10-27 13:03:16,562] [main] INFO com.google.gerrit.server.config.GerritServerConfigProvider : No /var/gerrit/etc/gerrit.config; assuming defaults
fatal: /var/gerrit/etc/mail
fatal: Cannot make directory /var/gerrit/etc/mail
原因:bind mount 数据目录属主不是 uid 1000(镜像内 gerrit 用户),init 无权写入。解决:chown -R 1000:1000 etc git db index cache 后重新 docker compose up -d。
15.2 JAVA_OPTS 环境变量设置了但堆没变
原因:镜像入口脚本第一行 export JAVA_OPTS='--add-opens ...' 覆盖了外部传入值,且 daemon 运行参数只读 gerrit.config 的 container.javaOptions。解决:堆参数写入 etc/gerrit.config(第七节),重启并用 /proc/1/cmdline 验证(回显见第七节)。
15.3 端口被占用:failed to bind host port ... address already in use
原因:宿主端口已被其他进程/Compose 项目占用。解决:换宿主侧映射端口(本篇 SSH 从 29418 改映射 8148 即此原因),Compose 里改 ports: 左侧宿主端口即可,Gerrit 内部端口无需动;改完 docker compose up -d 重建。
15.4 auth.type = HTTP 下 REST 一律 401(account inactive or not provisioned in Gerrit)
现象(实测日志):
WARN com.google.gerrit.httpd.ProjectBasicAuthFilter : Authentication failed for admin: account inactive or not provisioned in Gerrit
定位过程与结论:该 401 说明请求既无有效 REMOTE_USER 上下文、账户也未预置 HTTP 凭据。两步修复:① 账户侧先设置 HTTP 凭据(11.2 第 1 步 password.http);② 代理层确认 REMOTE_USER 头注入且未清空 Authorization 头。本篇实测中「代理清空 Authorization 头 + 账户未设凭据」两者叠加时表现为持续 401,逐一修复后 Basic 认证恢复 200。
15.5 推送被拒:change ... closed
现象(实测回显):
! [remote rejected] HEAD -> refs/for/master (change http://localhost:8141/c/demo-project/+/1 closed)
原因:Change 已合入(MERGED)后,再用同一个 Change-Id 推送会被拒绝——closed 状态的 Change 不能追加 patchset。解决:修改提交信息换新 Change-Id(git commit --amend)后重推,产生全新的 Change。
15.6 gerrit review 报 is not a valid patch set
原因:3.x 的 SSH 评分命令参数格式是 CHANGE,PATCHSET 逗号组合(如 2,1),裸写 change 号会被当作 patch set 解析失败。另外注意:2.x 时代的 gerrit approve、gerrit set-review、gerrit ls-users 命令在 3.14 已不存在(实测均报 not found),评分与评审人管理分别用 gerrit review 与 gerrit set-reviewers。
15.7 日志中的 GuiceFilter/AssistedInject WARNING 是否需要处理
WARNING: Multiple Servlet injectors detected. ...
WARNING: AssistedInject factory ... will be slow because ...
两者均为插件装载期的通用告警(官方镜像默认输出),不影响功能,无需处理;若关注 replication 插件那 6500% 提示的性能注记,按官方建议升级插件版本即可。
十六、参考链接
- 官方镜像(Docker Hub):https://hub.docker.com/r/gerritcodereview/gerrit
- Gerrit 官网下载页:https://www.gerritcodereview.com/
- 版本发布总览:https://www.gerritcodereview.com/releases/README.md
- 官方配置文档(config-gerrit):https://gerrit-review.googlesource.com/Documentation/config-gerrit.html
- 反向代理与 HTTP 认证文档:https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html
- 认证配置文档:https://gerrit-review.googlesource.com/Documentation/config-authentication.html
- REST API 文档:https://gerrit-review.googlesource.com/Documentation/rest-api.html
- k8s-gerrit 项目(SAP + GerritForge):https://gerritforge.com/
- 站内《Gerrit 介绍与选型指南》:https://www.quzuo.net/document/jBzSHXoP3n0J