ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

内网搭建Gerrit代码审查服务器:从零到一实战指南

内网搭建Gerrit代码审查服务器:从零到一实战指南 1. 项目缘起为什么要在内网搭建Gerrit在团队协作开发中代码审查是保证代码质量、统一编码规范、促进知识共享的关键环节。你可能用过GitLab、GitHub的Pull Request或者Gitee的合并请求它们都提供了基础的代码审查功能。但如果你所在的团队对代码审查流程有更严格、更定制化的要求比如强制要求每次提交都必须经过至少两位核心成员的评审或者需要将提交与特定的任务管理系统如Jira深度绑定那么一个更专业的代码审查工具就显得尤为重要。Gerrit正是这样一个为“门控式”代码审查而生的工具。它不是一个简单的Git服务器而是一个构建在Git之上的代码评审系统。它的核心思想是“提交即评审”——开发者不能直接将代码推送到主分支而是必须先将代码推送到一个特殊的引用refs/for/*这个操作会触发一次代码审查。只有审查通过后代码才会被真正地合并到目标分支。这种机制强制了评审流程非常适合对代码质量有高要求的团队尤其是在金融、嵌入式、大型基础软件等领域的开发中。那么为什么选择在内网搭建原因很直接安全、速度和自主可控。将Gerrit部署在内网环境意味着所有的代码资产、评审数据、用户信息都留存在公司或团队的私有网络中避免了代码泄露的风险。同时内网访问速度极快无论是克隆仓库、推送代码还是加载评审页面体验都远超公网。更重要的是内网部署让你拥有完全的自主权可以根据团队的特定流程定制Gerrit的配置、插件和工作流不受任何外部服务的限制或变更影响。我经历过从使用公共托管服务到自建Gerrit的完整过程初期确实会面临一些配置上的挑战但一旦跑通它为团队带来的流程规范性和代码质量的提升是显而易见的。接下来我将带你从零开始手把手搭建一个稳定、可用的Gerrit服务器并配置好内网访问。2. 环境准备与基础组件选型搭建Gerrit首先需要明确它的运行依赖。Gerrit是一个Java应用它需要一个Java运行环境、一个数据库来存储元数据如用户、群组、权限、评审记录等以及一个Web容器通常内置Jetty。此外它还需要一个反向代理如Nginx或Apache来处理HTTP/HTTPS请求并提供更灵活的访问控制。2.1 服务器与操作系统选择对于内网环境一台配置中等的Linux服务器就足够了。我推荐使用Ubuntu Server LTS或CentOS/RHEL这类长期支持版本它们拥有稳定的软件源和广泛的社区支持。以下配置可以作为参考CPU: 2核或以上。内存: 4GB或以上。Gerrit本身不算太耗内存但需要为Java堆内存和操作系统预留空间。存储: 50GB以上。空间主要留给Git仓库和数据库。建议使用SSD以提升仓库操作如git clone,git fetch的IO性能。网络: 确保服务器在内网中有固定的IP地址例如192.168.1.100。注意请确保服务器的时间与网络内其他机器同步使用NTP服务否则在认证、日志时间戳等方面可能会遇到奇怪的问题。2.2 Java环境安装Gerrit需要Java运行环境。截至我撰写本文时Gerrit 3.x 版本支持 Java 11 和 Java 17。我推荐使用OpenJDK 11它在稳定性和兼容性方面经过了更长时间的考验。以Ubuntu 20.04/22.04为例安装命令如下sudo apt update sudo apt install openjdk-11-jdk -y安装完成后验证版本java -version你应该能看到类似openjdk version 11.0.xx的输出。2.3 数据库选型与安装Gerrit支持多种数据库包括嵌入式H2、PostgreSQL、MySQL/MariaDB等。强烈不建议在生产环境使用H2它仅适用于测试。对于内网生产环境PostgreSQL是官方推荐且社区支持最好的选择它在性能和稳定性方面表现优异。安装PostgreSQLsudo apt install postgresql postgresql-contrib -y sudo systemctl start postgresql sudo systemctl enable postgresql接下来我们需要为Gerrit创建一个专用的数据库和用户。切换到postgres系统用户来操作sudo -u postgres psql在PostgreSQL的交互命令行中执行以下SQL语句CREATE USER gerrit WITH PASSWORD 你的强密码; CREATE DATABASE gerritdb OWNER gerrit ENCODING UTF8 LC_COLLATEen_US.UTF-8 LC_CTYPEen_US.UTF-8 TEMPLATEtemplate0; GRANT ALL PRIVILEGES ON DATABASE gerritdb TO gerrit; \q请务必将你的强密码替换为一个高强度的密码并记录下来。2.4 创建Gerrit系统用户为了安全和管理方便我们创建一个专用的系统用户来运行Gerrit服务sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/gerrit gerrit这个命令创建了一个名为gerrit的系统用户其家目录在/home/gerrit。后续Gerrit的安装文件和数据都将放在这个目录下。3. 下载、安装与初始化Gerrit准备工作就绪现在可以开始安装Gerrit了。我们将使用Gerrit提供的.war包进行安装这是一种非常灵活的方式。3.1 下载Gerrit WAR包以gerrit用户身份登录服务器或者使用sudo -u gerrit -i切换到该用户。进入其家目录并下载最新稳定版的Gerrit。sudo -u gerrit -i cd /home/gerrit # 从Gerrit官方仓库下载例如3.9.0版本 wget https://gerrit-releases.storage.googleapis.com/gerrit-3.9.0.war你可以访问 Gerrit Releases 查看并选择最新的稳定版本。3.2 执行初始化安装这是最关键的一步。我们将运行.war文件来初始化Gerrit站点。这个命令会启动一个交互式配置向导。java -jar gerrit-3.9.0.war init -d /home/gerrit/gerrit_site-d /home/gerrit/gerrit_site指定了Gerrit站点的安装目录。所有配置、仓库、插件等都将存放在这里。接下来安装程序会提出一系列问题。以下是我推荐的配置选择对于内网环境尤其重要Authentication method[openid/?]:?输入问号查看所有支持的认证方式。对于内网我们通常使用HTTP或LDAP。HTTP 依赖反向代理如Nginx进行用户认证适合与公司已有的统一登录门户如OA系统集成开发简单。LDAP 连接公司现有的LDAP/Active Directory服务器实现账号统一管理。这是企业内网最常见的选择。 这里我们先选择HTTP因为它配置最简单后续可以在配置文件中轻松切换到LDAP。输入http并按回车。Get username from custom HTTP header[y/N]?y因为我们使用HTTP认证需要告诉Gerrit从哪里获取已登录的用户名。通常反向代理会在请求头中设置一个字段如X-Forwarded-User。这里先选y。Header for username[X-Forwarded-User]:X-Forwarded-User使用默认的X-Forwarded-User即可后续在Nginx配置中需要保持一致。Gerrit Code Review server run as[gerrit]:gerrit确认以我们之前创建的gerrit用户运行直接回车。Gerrit Code Review server listening on address[*]:[::]监听所有IPv6地址也包含IPv4。对于内网服务这样配置没问题。直接回车。Gerrit Code Review server listening on port[29418]:29418Gerrit的SSH端口用于git push等操作。保持默认29418回车。Gerrit Code Review canonical URL[http://your-server-hostname:8080/]:http://192.168.1.100:8080/这是非常重要的一步将其替换为你服务器的内网IP和端口。例如http://192.168.1.100:8080/。这个URL是Gerrit生成链接如邮件通知的基础。Database server type[h2/?]:postgresql输入postgresql选择我们安装的PostgreSQL。Database server hostname[localhost]:localhost数据库在本机直接回车。Database server port[5432]:5432PostgreSQL默认端口回车。Database name[reviewdb]:gerritdb输入我们之前创建的数据库名gerritdb。Database username[gerrit]:gerrit输入我们创建的数据库用户gerrit。Database password[]:输入你之前设置的强密码输入为gerrit用户设置的密码。Register new email addresses for users[Y/n]?n在内网环境中我们通常不希望Gerrit自动注册新邮箱。选择n。SMTP server hostname[localhost]:直接回车留空内网可能没有配置邮件服务器可以先留空后续再配置。SMTP server port[25]:直接回车SMTP encryption[NONE/?]:直接回车SMTP username[]:直接回车From email address[gerrityour-server-hostname]:可以设置为一个管理员邮箱如 adminyour-company.local后续可以在配置文件中修改。Install plugin download-commands?[Y/n]?y这个插件提供了方便的脚本下载命令建议安装。初始化过程会持续几分钟它会下载必要的依赖、创建数据库表结构、生成默认配置文件等。完成后Gerrit站点就初始化好了但此时它还没有以后台服务的方式运行。4. 配置反向代理Nginx与HTTP认证默认情况下Gerrit在8080端口以HTTP方式运行。为了提供更标准的Web访问如使用80/443端口、实现负载均衡、以及配置我们刚才选择的HTTP认证我们需要设置一个反向代理。这里我选择Nginx因为它轻量且配置灵活。4.1 安装与配置Nginx首先安装Nginxsudo apt install nginx -y接下来为Gerrit创建一个Nginx配置文件。通常站点配置文件放在/etc/nginx/sites-available/目录下然后创建一个符号链接到/etc/nginx/sites-enabled/。sudo nano /etc/nginx/sites-available/gerrit将以下配置粘贴进去请根据你的实际情况修改server_name和proxy_pass的地址server { listen 80; # 这里使用服务器的内网IP或域名。如果只有IP就写IP。 server_name 192.168.1.100; # 关闭Nginx的版本号显示增加一点安全性 server_tokens off; # 设置请求体大小限制避免大提交被拒绝 client_max_body_size 512m; location / { # 关键配置将请求转发给运行在8080端口的Gerrit proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 这是HTTP认证的核心告诉Gerrit当前登录的用户是谁。 # 我们这里做一个简单的演示假设所有访问者都是‘admin’用户。 # 在实际生产环境中这个头应该由前置的统一认证网关如OA系统的SSO来设置。 proxy_set_header X-Forwarded-User admin; # 以下配置是为了WebSocket和Gerrit特定功能正常工作 proxy_set_header Connection ; proxy_http_version 1.1; proxy_request_buffering off; proxy_buffering off; } # 静态资源缓存提升性能 location ^~ /static/ { proxy_pass http://127.0.0.1:8080; expires 30d; add_header Cache-Control public, immutable; } }重要提示上面配置中的proxy_set_header X-Forwarded-User admin;是一个极简的、不安全的示例。它把所有访问者都识别为admin用户。这仅用于首次登录和测试在实际内网中你需要部署一个真正的认证网关例如使用auth_request模块调用内部认证接口由该网关验证用户身份后动态地将真实的用户名填入X-Forwarded-User头部。保存并退出编辑器。然后创建符号链接并测试配置sudo ln -s /etc/nginx/sites-available/gerrit /etc/nginx/sites-enabled/ sudo nginx -t # 测试配置文件语法如果显示syntax is ok则重载Nginx使配置生效sudo systemctl reload nginx4.2 配置Gerrit以信任代理现在需要告诉Gerrit它运行在反向代理后面并且要信任来自代理的X-Forwarded-*头部。编辑Gerrit的主配置文件sudo -u gerrit nano /home/gerrit/gerrit_site/etc/gerrit.config找到[httpd]和[auth]部分进行如下修改或添加[gerrit] # 确保canonicalWebUrl与Nginx配置的访问地址一致使用HTTP canonicalWebUrl http://192.168.1.100/ [httpd] # 监听地址改为 localhost只让Nginx能够访问 listenUrl proxy-http://127.0.0.1:8080/ [auth] type HTTP # 告诉Gerrit用户登录名来自哪个HTTP头 httpHeader X-Forwarded-User # 设置HTTP认证的Cookie名称保持默认即可 cookieName GERRIT_AUTH # 信任来自本地Nginx代理的请求 trustContainerAuth true保存并退出。4.3 启动Gerrit并验证基础访问Gerrit安装目录下有一个bin/目录里面包含了控制脚本。我们以后台方式启动Gerritsudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh start检查服务状态sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh status应该看到Gerrit running pidxxxx。现在打开内网中另一台机器的浏览器访问http://192.168.1.100。你应该能看到Gerrit的界面并且右上角显示你已经以admin用户登录因为我们的Nginx配置硬编码了此用户。5. 核心配置详解权限、项目与邮件通知成功登录后我们还需要进行一些核心配置让Gerrit真正可用。这些配置主要通过Gerrit的Web界面和配置文件完成。5.1 初始化管理员账户与SSH Key首次以admin用户登录后Gerrit会提示你设置该用户的联系邮箱。请设置一个有效的内网邮箱地址。接下来为了能通过SSH推送代码你需要为admin用户添加SSH公钥。在你的本地开发机器上生成SSH密钥对如果还没有的话ssh-keygen -t ed25519 -C your-emailyour-company.local将公钥文件通常是~/.ssh/id_ed25519.pub的内容复制到剪贴板。在Gerrit Web界面点击右上角用户名 -Settings-SSH Keys。将公钥内容粘贴进去并保存。现在你可以测试SSH连接ssh -p 29418 admin192.168.1.100如果配置正确你会看到一条Gerrit的欢迎信息并立即断开连接。这表示SSH认证成功。5.2 创建群组与配置访问权限权限管理是Gerrit的核心。Gerrit的权限模型基于“群组Group”和“权限规则Access Rule”。一个典型的流程是创建群组例如Developers所有开发者、Maintainers核心维护者、QA测试人员。将用户加入群组可以通过Web界面手动添加如果配置了LDAP则可以同步LDAP群组。为项目或All-Projects父项目设置权限定义哪个群组可以做什么读、写、评审、加标签等。我们首先创建一个Developers群组点击顶部菜单People-Create New Group。组名填写Developers描述可选填点击Create。然后我们需要为默认的父项目All-Projects设置基础权限所有新建项目都会继承这些权限。All-Projects是一个特殊的项目用于存放全局配置。点击顶部菜单Projects-List找到All-Projects并点击进入。点击左侧导航栏的Access。你会看到一个权限表格。我们需要编辑refs/*和refs/heads/*等引用的权限。找到Reference: refs/heads/*点击Edit。点击Add Permission选择Read。然后在Group下拉框中选择我们刚创建的Developers组点击Add。这表示Developers组的成员可以读取所有分支。同样地为Push权限添加Developers组但不要直接赋予 Push 权限。Gerrit的推送是通过refs/for/branch进行的这对应Push权限中的一个子项Push with bypassing code review (Direct Push)和Push merge commits通常只给管理员。我们给开发者的应该是Push权限本身它允许推送到refs/for/*进行评审。更常见的做法是在项目级别而非All-Projects精细控制权限。例如只允许Maintainers组直接推送到主分支而Developers只能通过refs/for/*推送。5.3 创建第一个项目并设置工作流现在我们来创建一个真实的代码仓库。点击Projects-Create New Project。Project Name填写my-first-project。Parent Project选择All-Projects这样它会继承我们之前设置的权限。Submit type选择Merge if necessary这是最常用的在无冲突时创建合并提交。点击Create。项目创建后进入其Access页面。在这里我们可以覆盖从父项目继承的权限。例如我们可以为refs/heads/master添加Push权限给Maintainers组而Developers组只保留Read和推送到refs/for/refs/*即创建评审的权限。这种“门控”模式就建立起来了。5.4 配置内网邮件通知虽然内网可能没有外网SMTP服务器但可以配置一个本地的邮件发送代理如Postfix或者使用一个简单的内部邮件中继。这里以配置一个外部SMTP服务器为例假设内网有邮件服务器。编辑gerrit.config的[sendemail]部分sudo -u gerrit nano /home/gerrit/gerrit_site/etc/gerrit.config添加或修改[sendemail] enable true from Gerrit Code Review noreplyyour-company.local smtpServer smtp.your-company.local smtpServerPort 25 # 如果需要认证 # smtpUser your-username # smtpPass your-password sslVerify false # 内网自签名证书可设为false保存后需要重启Gerrit使配置生效sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh restart你可以在项目的Access-All-Projects-Edit中找到capability下的emailReviewers等权限控制谁可以触发邮件通知。6. 日常维护、问题排查与性能调优Gerrit搭建完成后日常的维护和问题排查同样重要。6.1 服务管理启动sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh start停止sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh stop重启sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh restart查看状态sudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh status查看日志日志文件位于/home/gerrit/gerrit_site/logs/。error_log是错误日志httpd_log是访问日志gerrit.run是启动日志。排查问题时首先查看error_log。6.2 常见问题排查无法通过Web界面登录一直跳转或提示认证失败检查Nginx配置确认proxy_set_header X-Forwarded-User头部是否正确设置并且值不为空。可以使用浏览器开发者工具的“网络”选项卡查看请求头是否包含该字段。检查Gerrit配置确认gerrit.config中[auth]部分的type和httpHeader与Nginx配置一致。检查信任配置确保gerrit.config中[httpd]的listenUrl是proxy-http://开头并且[auth]中设置了trustContainerAuth true。SSH连接被拒绝或超时检查端口确认连接命令中的端口是29418并且服务器防火墙是否放行了该端口内网通常不需要。检查服务状态gerrit.sh status确认Gerrit的SSH服务正在运行。检查SSH密钥确认Web界面中添加的公钥与本地私钥匹配。可以尝试用ssh -v -p 29418 admin192.168.1.100查看详细的调试信息。推送代码到refs/for/master失败提示权限不足检查项目权限进入项目的Access页面检查相应用户或所属群组在refs/for/refs/*或更具体的refs/for/branches/*上是否拥有Push权限。检查分支权限确保对目标分支如refs/heads/master至少有Read权限。6.3 性能调优建议JVM堆内存设置编辑/home/gerrit/gerrit_site/bin/gerrit.sh找到JAVA_OPTIONS或GERRIT_OPTIONS环境变量设置的地方。对于中小型团队可以设置为-Xmx2g -Xms1g最大2G初始1G。根据服务器内存和仓库数量调整。Git仓库存储优化确保Gerrit数据目录/home/gerrit/gerrit_site/git/位于SSD磁盘上。定期在服务器上对大型仓库执行git gc --aggressive需谨慎建议在低峰期进行。数据库连接池在gerrit.config的[database]部分可以配置poolLimit和poolMaxIdle等参数来优化PostgreSQL连接。默认值通常够用如果出现连接数问题可以调整。缓存配置Gerrit使用多种缓存。在gerrit.config的[cache]部分可以调整缓存大小和过期时间。例如增加web_sessions的存活时间可以减少数据库查询。但调整缓存需要根据监控情况来进行不建议初期随意改动。6.4 备份策略任何服务都离不开备份。Gerrit的备份主要包含两部分数据库备份定期使用pg_dump备份PostgreSQL数据库。sudo -u postgres pg_dump gerritdb /path/to/backup/gerritdb_$(date %Y%m%d).sql站点目录备份备份整个/home/gerrit/gerrit_site目录但可以排除cache/,tmp/,logs/等临时目录。Git仓库数据git/子目录是重中之重。tar -czf /path/to/backup/gerrit_site_$(date %Y%m%d).tar.gz \ --exclude/home/gerrit/gerrit_site/cache \ --exclude/home/gerrit/gerrit_site/tmp \ --exclude/home/gerrit/gerrit_site/logs \ /home/gerrit/gerrit_site建立一个自动化的备份脚本并将备份文件传输到另一台机器或存储系统是保障数据安全的最佳实践。7. 从HTTP认证迁移到LDAP认证进阶如果你内网有Active Directory或OpenLDAP服务器将Gerrit认证切换到LDAP可以实现账号的统一管理。这比HTTP认证更安全、更自动化。安装LDAP插件Gerrit默认可能未包含LDAP插件。你需要下载对应的.jar文件放到/home/gerrit/gerrit_site/plugins/目录然后重启Gerrit。修改gerrit.config[auth] type LDAP # 取消或注释掉之前的HTTP配置 # httpHeader X-Forwarded-User # cookieName GERRIT_AUTH # trustContainerAuth true [ldap] server ldap://your-ldap-server.your-company.local:389 username CNGerrit Service Account,OUService Accounts,DCyour-company,DClocal password service-account-password accountBase OUUsers,DCyour-company,DClocal accountScope sub accountPattern ((objectClassperson)(sAMAccountName${username})) groupBase OUGroups,DCyour-company,DClocal groupScope sub groupPattern (cn${groupname}) # 以下配置用于将LDAP群组同步到Gerrit群组 localUsernameToLowerCase true这是一个连接AD的示例配置具体参数需要根据你的LDAP服务器结构进行调整。重启Gerritsudo -u gerrit /home/gerrit/gerrit_site/bin/gerrit.sh restart同步LDAP群组通过Gerrit的Web界面People-List Groups-同步组或使用SSH命令gerrit gsync -c来同步群组。切换到LDAP后用户将使用其LDAP/AD账号密码在Gerrit登录页面直接登录无需再依赖反向代理的HTTP头认证。这实现了真正的集中式身份管理。整个搭建和配置过程虽然步骤不少但每一步都有其明确的目的。从最基础的Java环境、数据库准备到Gerrit的初始化、反向代理配置再到核心的权限、项目管理和后期维护这套流程在内网环境中经过多次实践稳定可靠。关键在于理解每个组件的作用如Nginx的反向代理和认证传递Gerrit的权限模型并根据自己团队的实际情况进行调整。
返回列表