Files
gitea/docs/lfs-cos-storage.md
tech d75f1a9ece docs: add LFS COS storage migration guide with DNS bucket lookup fix
Documents how to migrate Gitea LFS from local disk to Tencent Cloud COS,
including the required MINIO_BUCKET_LOOKUP_TYPE=dns setting for COS compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 01:37:42 +08:00

5.7 KiB
Raw Blame History

Gitea LFS 对接腾讯云 COS

本文档适用于已通过本项目 Docker Compose 部署 Gitea希望将 LFS 存储从本地磁盘迁移到腾讯云 COS 对象存储的场景。

腾讯云轻量应用服务器Lighthouse可以正常使用COS 通过 HTTPS 公网端点访问,无需额外网络配置。


一、腾讯云侧准备

1.1 创建 COS Bucket

进入 COS 控制台 → 存储桶列表 → 创建存储桶:

选项 建议值
地域 与服务器相同地域(降低延迟)
访问权限 私有读写
版本控制 关闭LFS 对象不需要)

创建后记录完整的 Bucket 名称,格式为 <name>-<appid>,例如 gitea-lfs-1234567890

1.2 创建 CAM 子账号并授权

进入 CAM 控制台 → 用户管理 → 新建用户:

  • 用户类型选编程访问(只需 API 密钥,无需登录控制台)
  • 直接关联策略:搜索并勾选 QcloudCOSDataFullControl

如需最小权限,自定义策略只需包含: GetObject PutObject DeleteObject HeadObject ListBucket

创建完成后保存 SecretIdSecretKey,页面关闭后无法再次查看。

1.3 地域 ID 参考

地域 ID
广州 ap-guangzhou
上海 ap-shanghai
北京 ap-beijing
深圳 ap-shenzhen
成都 ap-chengdu
中国香港 ap-hongkong
新加坡 ap-singapore

二、修改项目配置

2.1 修改 .env

将原来的本地 LFS 配置:

GITEA__lfs__START_SERVER=true
GITEA__lfs__PATH=/data/git/lfs

替换为:

# Git LFS 配置 - 腾讯云 COS
GITEA__lfs__START_SERVER=true
GITEA__lfs__STORAGE_TYPE=minio
GITEA__lfs__MINIO_ENDPOINT=cos.ap-guangzhou.myqcloud.com   # 改为你的地域
GITEA__lfs__MINIO_ACCESS_KEY_ID=AKIDxxxxxxxxxx              # CAM SecretId
GITEA__lfs__MINIO_SECRET_ACCESS_KEY=xxxxxxxxxx              # CAM SecretKey
GITEA__lfs__MINIO_BUCKET=gitea-lfs-1234567890               # Bucket 完整名称
GITEA__lfs__MINIO_LOCATION=ap-guangzhou                     # 改为你的地域
GITEA__lfs__MINIO_USE_SSL=true
GITEA__lfs__MINIO_BASE_PATH=lfs/
GITEA__lfs__MINIO_BUCKET_LOOKUP_TYPE=dns

GITEA__lfs__PATH 仅在本地存储模式下生效,切换到 minio 后删除该行即可。

2.2 修改 docker-compose.yml

gitea 服务的 environment 下,将原来的 LFS 条目:

- GITEA__lfs__START_SERVER=${GITEA__lfs__START_SERVER}
- GITEA__lfs__PATH=${GITEA__lfs__PATH}

替换为:

- GITEA__lfs__START_SERVER=${GITEA__lfs__START_SERVER}
- GITEA__lfs__STORAGE_TYPE=${GITEA__lfs__STORAGE_TYPE}
- GITEA__lfs__MINIO_ENDPOINT=${GITEA__lfs__MINIO_ENDPOINT}
- GITEA__lfs__MINIO_ACCESS_KEY_ID=${GITEA__lfs__MINIO_ACCESS_KEY_ID}
- GITEA__lfs__MINIO_SECRET_ACCESS_KEY=${GITEA__lfs__MINIO_SECRET_ACCESS_KEY}
- GITEA__lfs__MINIO_BUCKET=${GITEA__lfs__MINIO_BUCKET}
- GITEA__lfs__MINIO_LOCATION=${GITEA__lfs__MINIO_LOCATION}
- GITEA__lfs__MINIO_USE_SSL=${GITEA__lfs__MINIO_USE_SSL}
- GITEA__lfs__MINIO_BASE_PATH=${GITEA__lfs__MINIO_BASE_PATH}
- GITEA__lfs__MINIO_BUCKET_LOOKUP_TYPE=${GITEA__lfs__MINIO_BUCKET_LOOKUP_TYPE}

2.3 同步更新 .env.example

.env.example 是提交到 git 的模板,需同步更新(不填真实密钥):

# Git LFS 配置 - 腾讯云 COS
GITEA__lfs__START_SERVER=true
GITEA__lfs__STORAGE_TYPE=minio
GITEA__lfs__MINIO_ENDPOINT=cos.ap-guangzhou.myqcloud.com
GITEA__lfs__MINIO_ACCESS_KEY_ID=AKIDxxxxxxxxxx
GITEA__lfs__MINIO_SECRET_ACCESS_KEY=xxxxxxxxxx
GITEA__lfs__MINIO_BUCKET=your-bucket-name
GITEA__lfs__MINIO_LOCATION=ap-guangzhou
GITEA__lfs__MINIO_USE_SSL=true
GITEA__lfs__MINIO_BASE_PATH=lfs/
GITEA__lfs__MINIO_BUCKET_LOOKUP_TYPE=dns

三、迁移已有 LFS 数据(可选)

如果切换前本地 data/git/lfs/ 已有文件,需手动同步到 COS否则历史 LFS 对象会返回 404。

使用腾讯云官方 CLI 工具 coscli

# 安装 cosclimacOS 示例)
curl -o coscli https://github.com/tencentyun/coscli/releases/latest/download/coscli-darwin

chmod +x coscli

# 配置认证(交互式)
./coscli config init

# 上传本地 LFS 目录到 COS同步模式不重复上传
./coscli sync ./data/git/lfs/ cos://gitea-lfs-1234567890/lfs/ --recursive

同步完成后再重启 Gitea避免服务重启期间出现 LFS 对象丢失。


四、重启并验证

# 重启 Gitea 服务Compose 会自动检测 .env 变更并重建容器)
docker compose up -d gitea

# 查看启动日志,确认无报错
docker compose logs -f gitea

验证 COS 是否生效:推送一个包含 LFS 文件的提交,然后到 COS 控制台的 lfs/ 路径下确认对象是否出现。

# 本地测试推送
git lfs track "*.bin"
git add .gitattributes largefile.bin
git commit -m "test: lfs upload to cos"
git push

五、常见问题

QBucket 名称填什么格式?
填完整名称(含 AppId例如 gitea-lfs-1234567890。不含 .cos.ap-xxx.myqcloud.com 后缀。

Q轻量服务器能用 COS 内网端点吗?
轻量服务器使用独立的轻量网络,不在标准 VPC 内,默认无法访问 COS 内网端点。直接使用公网端点 cos.<region>.myqcloud.com 即可。若已通过云联网CCN打通网络可将端点改为 cos-internal.<region>.myqcloud.com 以节省公网流量费用。

Q推送 LFS 报 403 Forbidden
检查 CAM 子账号的策略是否包含目标 Bucket 的操作权限,以及 SecretId / SecretKey 是否填写正确。

Q推送 LFS 报 SignatureDoesNotMatch
确认 MINIO_LOCATION 与 Bucket 实际所在地域一致。