Gitea:自建Git新选择

前些年自建 Git 的首选应该是 Gitlab,印象中 Gitlab 是非常臃肿的,对内存的需求比较大,最好是 4G 以上内存的机器。相比之下,Gitea 就很轻量级了,能够很好的节约系统资源。另外 Go 程序部署起来也更方便。还有一个比较实用的功能是,Gitea 支持全文搜索,而 Gitlab 社区版本不支持。和 Gerrit 对比,Gitea 有着和 Github 体验类似的工单系统,也能很好的和CI工具集成,比如 Drone CI,获得和 Github 类似的使用体验。综合来看,使用 Gitea 是一个不错的选择。

安装

Go 程序基本都是把二进制跑起来就可以了,不论是直接二进制方式运行,还是跑到容器里,都比较省心。

二进制安装

提供 2 个基本的环境变量,用如下命令启动:

GITEA_WORK_DIR=/home/git USER=git gitea web

可以用 systemd 获取 supervisor 来管理,以下是 systemd 的例子。

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
After=mysqld.service
 
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/home/gitea
ExecStart=/home/gitea/gitea web
Restart=always
Environment=USER=git GITEA_WORK_DIR=/home/gitea
 
[Install]
WantedBy=multi-user.target

使用Kubernetes安装

使用 Kubernetes,可以很容易的实现高可用。参考 Github 项目 ops-itop/gitea-k8s。由于该项目是针对 iTop 的 kubernetes 插件来开发的,没有提供 Deployment 的 yaml 文件,但是仍然有一定的参考性。

镜像制作

Dockerfile 如下:

FROM alpine:3.10
RUN apk add --no-cache git curl sudo openssh-keygen bash busybox-suid coreutils file
RUN curl -s -L https://github.com/go-gitea/gitea/releases/download/v1.9.3/gitea-1.9.3-linux-amd64 -o /gitea
RUN curl -s -L https://github.com/aptible/supercronic/releases/download/v0.1.9/supercronic-linux-amd64 -o /supercronic
RUN chmod +x /gitea
RUN chmod +x /supercronic
RUN adduser -D git
RUN echo "git ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/git
USER git
ADD run.sh /
ADD dump.sh /
ENTRYPOINT ["/bin/sh", "/run.sh"]

启动脚本 run.sh 如下:

#!/bin/sh

[ "$GITEA_WORK_DIR"x == ""x ] && GITEA_WORK_DIR=/data
[ "$USER"x == ""x ] && USER=git

CONF=$GITEA_WORK_DIR/custom/conf

[ ! -d $CONF ] && sudo mkdir -p $CONF

# log 目录不存在时 dump 不成功
[ ! -d $GITEA_WORK_DIR/log ] && mkdir -p $GITEA_WORK_DIR/log

sudo cp -f $APP_CONFIG_PATH/CONFIG $CONF/app.ini

sudo chown -R git:git /data

export GITEA_WORK_DIR
export USER

sudo chmod +x /dump.sh
# 使用 supercronic 来执行定时任务,支持以非root账户运行,并且可以直接用容器环境变量
/supercronic $APP_CONFIG_PATH/CRON &

exec /gitea web

备份脚本 dump.sh 见下文。

SSH 代理

通过 ingress nginx 的 tcp 代理 功能来代理 ssh。

kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: intra
data:
  222: "intra/git:2222"

数据安全

除了做好备份,可以考虑更改 Gitea pv 的回收策略为 Retain

kubectl patch pv pvc-6782347e-cfa9-11e9-9dbf-e8631f143422 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

初始化

使用命令行添加管理员, 用户名不能为 admin

/gitea --work-path /data --custom-path /data/custom --config /data/custom/conf/app.ini admin create-user --username root --password admin19 --email=example@qq.com --admin

使用

以下是我的一些配置,供参考:

  • 配置 SMTP 和 ENABLE_NOTIFY_MAIL = true,让用户可以收到通知邮件
  • 配置代码搜索,[indexer] 下配置REPO_INDEXER_ENABLED = true
  • 禁用 gravatar DISABLE_GRAVATAR
  • 开启 OIDC 方便用户登录,如果公司没有 OIDC,可以用 dex 代理一下,实现一个 OIDC
  • 设置 LANDING_PAGE = explore
  • 使用 HTTPS,方便 Go 程序开发,对于私有仓库,可能还需要 ~/.gitconfig 中添加如下配置:
[url "ssh://user@git.com:222"]
	insteadOf = https://git.com/

备份与恢复

备份可以参考上文提到的备份脚本 dump.sh

#!/bin/bash

DATE=`date +%Y%m%d-%H%M%S`
FILE="gitea-dump-$DATE.zip"
TEMPDIR="/tmp"
[ "$GITEA_WORK_DIR"x == ""x ] && GITEA_WORK_DIR=/data
BACKUP=$GITEA_WORK_DIR/backups
CONFIG="$GITEA_WORK_DIR/custom/conf/app.ini"

cd $GITEA_WORK_DIR
/gitea dump --file $FILE --tempdir $TEMPDIR --config $CONFIG


CONTENT=`file $FILE`
echo $CONTENT |grep "Zip archive data" && r=SUCC || r=FAILED
CONTENT="$CONTENT<br>`du -sh $FILE`"

[ ! -d $BACKUP ] && mkdir -p $BACKUP
mv $FILE $BACKUP

# 删除过期备份
# 备份默认保留30天
[ "$RETAIN"x == ""x ] && RETAIN=30
cd $BACKUP

DELDAY=`date -d "$RETAIN day ago" +%Y%m%d`
FILE_DATE=`ls gitea-dump-*.zip |awk -F'-' '{print $3}'`

for f in ${FILE_DATE};do
	if [ $f -lt $DELDAY ];then
		del="gitea-dump-$f-*.zip"
		msg="delete $del"
		CONTENT="$CONTENT<br>$msg"
		echo $msg
		rm -f $del
	fi
done

# 通知
function notify() {
	# 使用邮件接口发送 https://github.com/ops-itop/mailer
	[ "$NOTIFYAPI"x == ""x ] && NOTIFYAPI="http://127.0.0.1/api/mail"
	[ "$TOS"x == ""x ] && echo "NEED param tos , exit ..." && exit 1
	curl -s $NOTIFYAPI -XPOST -d "tos=$TOS&subject=[$1] Gitea Dump Result($DATE)&content=$2&format=html"
}

notify $r "$CONTENT"

可以考虑用挂载 PV 的方式将备份移到另一个盘,或者如果有 minio 之类的 S3 服务,可以上传过去。

恢复目前需要手动,将备份包解压到目标目录即可,记得权限改为 Gitea 运行用户。

如果恢复的是一个启用了 OIDC 的 Gitea 实例,当 OIDC 不可用时,将导致 Gitea 无法启动,报错如下:

routers/init.go:105:GlobalInit() [F] Failed to initialize OAuth2 support: Get https://oidc.xxx.com/.well-known/openid-configuration: dial tcp 127.0.0.1:443: i/o timeout

处理方式一个是恢复 OIDC 服务,另外就是从数据库中禁用 OIDC:

update login_source set is_actived='false' where id=xxx;

参考资料

1. https://docs.gitea.io/en-us/
2. https://gitea.io/zh-cn/

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注