Ubuntu + Gerrit + Apache 搭建代码审核服
我们公司采用Gerrit作为代码审核服务器并结合JIRA、Jenkins等开源工具,组成了一个完整项目管理平台。某天,我兴致来了,也想在自己的服务器上搭建一个Gerrit。于是,便有了以下内容...
Gerrit介绍
Gerrit的目的是提供一个轻量级的框架来review每一个commit,review通过之后,commit会被合入代码库。
Gerrit是一个中间区域,可以看到提交至Gerrit上的代码相对于服务器代码仓库中代码的差异,从而便于检查代码的改动。Gerrit也是整个代码review的推动者。
任何拥有多个成员的团队都应该有一个中央代码仓库。 Git在理论上可以在没有这样的中心位置的情况下工作,但实际上通常有一个中央仓库库作为项目实际内容的权威副本。 开发者从该中央仓库fetch和push
imageGerrit被部署在上图的中央仓库的位置,并增加一个新的概念:a store of pending changes(未决的修改)。每个人仍然可以从中央仓库fetch,但是push操作则有所变化,push操作会直接push到中央仓库,而是push到了pending changes location,以供review。只有在commit通过了review之后,才会被submit到中央仓库。如下图所示。
imageGerrit具有强大的访问控制模型。用户可以被授予访问权限,绕过review,直接推送到中央仓库。Gerrit甚至可以在没有代码review的情况下使用,只用于托管仓库和访问控制。
应用场景
在安装gerrit之前,我使用node
在服务器上部署了一个站点,也就是本博客,其占用了80
端口。
在安装gerrit之后,我的服务器又将多出一个站点,用户该如何访问?我又该如何部署呢?这时候,我们就需要了解一下反向代理
和端口转发
了。
正向代理与反向代理
如下所示为正向代理和反向代理的示意图。一般来说,我们会把正向代理是与客户端划为一体,把反向代理和服务器划为一体。
image此时,重新思考一下我们的应用场景:博客是一个web服务器,gerrit是一个web服务器,apache作为反向代理,这样就可以满足我们的需求了。
那么反向代理到底是如何做到的呢?答案就是端口转发
。
我们知道在浏览器输入网址后,它会在解析后的IP地址之后加上一个默认的端口号80
。所以,我们访问chuquan.me
时就不需要输入完整的地址chuquan.me:80
了。正因为如此,绝大多数服务器软件(包括apache)的默认监听端口也是80
。
在安装了apache之后,80
端口被apache占用了。因此,gerrit和博客都不能使用80
端口了。这时候,我们需要给这两个站点配置使用其他的端口号,如:gerrit的HTTP协议使用8081
端口,博客使用8082
端口。它们与apache之间使用端口转发
来实现反向代理
。
开发环境
- Ubuntu 14.04.5 LTS
- Java 1.8.0_151
- Git 1.9.1
- Apache/2.4.7
安装Gerrit
新建专用用户
新建一个用户来专门管理Gerrit相关内容。在root用户下新建一个gerrit用户。
$ adduser gerrit
$ su gerrit
下载Gerrit安装包
Gerrit下载地址:https://www.gerritcodereview.com/releases/2.14.md
我安装的Gerrit版本是2.14.6。在Linux环境下使用wget
进行下载,最终得到一个war
包,位于/home/gerrit/
目录下。
$ wget https://gerrit-releases.storage.googleapis.com/gerrit-2.14.6.war
安装Gerrit
在/home/gerrit/
目录下,进行安装:
$ java -jar gerrit-2.14.6.war init -d review_site
上述命令会在当前目录下创建一个review_site
目录。接下来就开始进行对话式安装,我们可以直接回车,表示采用默认安装选项。之后还可以通过配置文件进行详细配置。
*** Gerrit Code Review 2.14.6
***
*** Git Repositories
***
Location of Git repositories [git]:
*** SQL Database
***
Database server type [h2]:
*** User Authentication
***
Authentication method [OPENID/?]: http
Get username from custom HTTP header [y/N]?
SSO logout URL :
*** Email Delivery
***
SMTP server hostname [localhost]:
SMTP server port [(default)]:
SMTP encryption [NONE/?]:
SMTP username :
*** Container Process
***
Run as [gerrit]:
Java runtime [/usr/lib/jvm/java-7-openjdk-amd64/jre]:
Copy gerrit-2.13.4.war to /home/gerrit/review/bin/gerrit.war [Y/n]?
Copying gerrit-2.13.4.war to /home/gerrit/review/bin/gerrit.war
*** SSH Daemon
***
Listen on address [*]:
Listen on port [29418]:
*** HTTP Daemon
***
Behind reverse proxy [y/N]?
Proxy uses SSL (https://) [y/N]?
Subdirectory on proxy server [/]:
Listen on address [*]:
Listen on port [8080]:
*** Plugins
***
Installing plugins.
Install plugin download-commands version v2.11 [y/N]?
Install plugin reviewnotes version v2.11 [y/N]?
Install plugin singleusergroup version v2.11 [y/N]?
Install plugin replication version v2.11 [y/N]?
Install plugin commit-message-length-validator version v2.11 [y/N]?
Initializing plugins.
No plugins found with init steps.
Initialized /home/gerrit/review_site
...
安装完毕,Gerrit会自动启动,不过我们大概率会启动失败,因为默认的配置并不一定与你当前的环境相匹配。不过,没关系,我们可以根据系统环境对gerrit进行配置。
Gerrit配置
Gerrit安装完成后,会在review_site
目录下生成多个目录。
$ ll review_site
./
../
bin/
cache/
data/
db/
etc/
git/
index/
lib/
logs/
plugins/
static/
tmp/
其中etc/
目录下存放着gerrit的配置文件gerrit.config
,其中已有的内容是根据安装时的选择生成的。我们可以编辑gerrit.config
来进行配置更改。其中115.28.168.118
是服务器的公网IP地址。
[gerrit]
basePath = git
serverId = 084efaf9-3bf6-401c-a4b1-8778c998bde2
canonicalWebUrl = http://115.28.168.118 # 指定web访问Gerrit的网址或IP地址
[database]
type = h2
database = /home/gerrit/review_site/db/ReviewDB
[index]
type = LUCENE
[auth]
type = HTTP # 默认是OPENID,改成HTTP后,才能通过浏览器进行访问
[receive]
enableSignedPush = true
[sendemail]
smtpServer = localhost
[container]
user = gerrit
javaHome = /usr/lib/jvm/java-8-oracle/jre
[sshd]
listenAddress = *:29418
[httpd]
listenUrl = proxy-http://115.28.168.118:8081/ # HTTP代理地址及端口,这里我们配置成8081
[cache]
directory = cache
配置Apache
不同系统以及不同版本的Apache的配置文件可能会不一样,无外乎两种:httpd.conf
、apache2.conf
。本环境的配置文件是apache2.conf
。
$ cd /etc/apache2/
$ vim apache2.conf
在配置文件的末尾添加apache的端口转发配置。如下所示
...
# Blog相关配置
<VirtualHost *:80>
ServerName www.chuquan.me # 用于Apache过滤检测的域名
ServerAlias chuquan.me
ProxyPass / http://115.28.168.118:8082/ # Blog正向代理转发的端口
ProxyPassReverse / http://localhost:8082/ # Blog反向代理转发的端口
</VirtualHost>
# Gerrit相关配置
<VirtualHost *:80>
ServerName gerrit.chuquan.me # 用户Apache过滤检测的域名
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location /login/>
AuthType Basic
AuthName "Gerrit Code Review"
Require valid-user
AuthBasicProvider file
AuthUserFile /home/gerrit/review_site/etc/passwords
</Location>
AllowEncodedSlashes On
ProxyPass / http://115.28.168.118:8081/ # Gerrit正向代理转发的端口
ProxyPassReverse / http://115.28.168.118:8081/ # Gerrit反向代理转发端口,应该与ProxyPass一致
</VirtualHost>
服务重启
Apache和Gerrit配置(当然也包括blog的端口)完之后,我们需要重启服务,包括apache、gerrit,其重启命令分别如下:
$ /etc/init.d/apache2 restart
$ cd /home/gerrit/
$ ./bin/gerrit.sh restart
Gerrit启动失败
在执行重启Gerrit的命令后,shell很可能会出现如下的信息:
Starting Gerrit Code Review: FAILED
我在安装过程中页出现了这个问题,于是,我通过在./bin/gerrit.sh
脚本中的首行添加了一个-x
选项,以打印脚本执行的相关信息。
#!/bin/sh -x
...
然后再执行该脚本,发现打印信息是一组循环信息。其中,当TIMEOUT
的值递减至0时,启动失败。
经过调研发现:
Gerrit在有些发发行版本部署之后启动非常慢(可能与发行版本有关,也有可能是其他原因,此问题没找到解决方法),大概需要10分钟左右,而默认的超时时间(TIMEOUT)是90秒,导致一直提示“Starting Gerrit Code Review: FAILED”。
一种解决方案是:在gerrit.conf文件中的[container]
字段下增加`startupTimeout = 900。
经过进一步的探索发现:Gerrit启动慢是因为java程序启动慢。因此,得到第二种解决方案:修改java的java.security
文件。首先,根据gerrit.config
中配置javaHome = /user/lib/jvm/java-8-oracle/jre
,找到并进入该目录,然后再进入lib/security/
目录,修改java.security
文件。将securerandom.source=file:/dev/random
改为securerandom.source=file:/dev/urandom
。由此,解决gerrit启动慢的问题。
反向代理异常
当我们配置结束并重启之后,在浏览器中访问很有可能会得到如下的页面:
image
这个页面在安装过程中,出现次数不下于10次。主要是两种情况,一种是Gerrit配置文件和Apache配置文件可能配置有误。另一种情况是配置没有生效,需要多试试重启。
创建第一个Gerrit账户
当所有问题解决完之后,通过浏览器访问Gerrit,将不会出现上面的Error界面,而是会弹出输入对话框,需要你填写账户和密码。
这时候,我们需要为Gerrit创建一个账户,默认第一个创建的账户是管理员。
$ touch /home/gerrit/review_site/etc/passwords
$ htpasswd /home/gerrit/review_site/etc/passwords "admin"
New password:
Re-type new password:
Adding password for user root
重启服务后,再用浏览器打开,登录后就出现久违的界面了!
(完)