Skip to content

基于 S3 的 Gitea LFS 搭建实践

前情提要

游戏团队需要一个部署有 Git LFS 服务的服务器,但 GitHub 网络不稳定且要钱,遂考虑自建 Gitea 服务。

Gitea 轻量化做的很不错,很适合这一场景,唯一问题就是:带宽.

由于这台小水管只有 4 Mbits 的带宽,作云盘或者 Git LFS 服务器显然不太合适。而国内的云服务商的运营环境,带宽费自然是极其贵的。

不过正好,之前腾讯云买服务器送了两年的 COS(对象存储) 50G 的免费额度,于是选择了使用它作为 Gitea LFS 的存储后端。

S3 是什么?

S3 (Simple Storage Service) 原本是亚马逊 AWS 推出的一种对象存储服务。但由于其极高的普及度,S3 协议已经成为了对象存储行业的事实标准。

在本文的语境下,只需要理解以下两点:

  • 它是一种通用的“接口语言”:虽然我们使用的是 腾讯云 COS (Cloud Object Storage),但腾讯云完美兼容 S3 协议。这意味着,Gitea 不需要专门去适配腾讯云的私有接口,只要 Gitea 支持 S3,它就能顺滑地连接到腾讯云 COS。
  • 它能解决“小水管”带宽问题:
    • 传统的 Git 方式是:用户 <--> Gitea服务器 <--> 硬盘。所有的流量都要经过只有 4Mbps 带宽的服务器。
    • 配置了 S3 后端并未开启直传/重定向功能时,流量依然会经过服务器。但,如果配置得当(使用预签名 URL 重定向),数据流可以变成:用户 <--> 腾讯云 COS。
    • 这样,上传下载大文件时,利用的是腾讯云 COS 的超大带宽(有CDN加速),而 Gitea 服务器只负责鉴权和元数据管理,彻底绕过了 4Mbps 的瓶颈。

Gitea搭建

参考 Gitea Docker 部署教程:使用 Docker 安装 | Gitea Documents

Docker配置文件需要添加如下:

yaml
environment:
  - USER_UID=2000
  - USER_GID=2000
volumes:
  - /home/git/.ssh/:/data/git/.ssh
ports:
  - "127.0.0.1:2222:22"

其中需要注意的是配置 SSH 容器直连,需要创建一个 git 账号,UID 和 GID 设置为与容器配置一致。

bash
sudo groupadd -g 2000 git
sudo useradd -u 2000 -g 2000 -m -s /bin/bash git
# 确认是否正确
id git
sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key"

在下一步中,需要在主机上创建一个名为 /usr/local/bin/gitea 的文件(具有可执行权限)。该文件将发出从主机到容器的 SSH 转发。

bash
touch /usr/local/bin/gitea
chmod +x /usr/local/bin/gitea

将以下内容添加到 /usr/local/bin/gitea:

bash
ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"

并将 Gitea 密钥添加到 /home/git/.ssh/authorized_keys 中:

bash
echo "$(cat /home/git/.ssh/id_rsa.pub)" >> /home/git/.ssh/authorized_keys

云服务配置

创建子账号

为确保安全性,应配置一个专门用于 COS 操作的子用户,并在控制台授予相关(含COS字样)权限。

记录子账号的 SecretId 和 SecretKey,后续配置 Gitea LFS 时需要使用。

创建 COS 桶

这里可以用 LighthouseCOS,也可以用常规的 COS 服务。

确保桶的目录的完全控制权限交给了子账号。

image

Gitea 环境配置

修改 app.ini

ini
[lfs]
STORAGE_TYPE = minio
MINIO_BASE_PATH = /lfs # 桶的文件目录

[storage.minio]
STORAGE_TYPE = minio
SERVE_DIRECT = true # 这样才可以客户端直接请求 COS 加速
MINIO_ENDPOINT = cos.ap-shanghai.myqcloud.com # 不要把前缀写上去
MINIO_ACCESS_KEY_ID = # 填入 SecretId
MINIO_SECRET_ACCESS_KEY = # 填入 SecretKey
MINIO_BUCKET = # 填入桶的名字(含数字ID)
MINIO_LOCATION = ap-shanghai
MINIO_BUCKET_LOOKUP_TYPE = dns

尔后,应重启 Gitea 容器服务。