【VPS 自建应用大赏 02】在 VPS 上自建 Gitea 私有代码仓库:备份、CI 与团队协作
2026-08-15 · DevCraft Studio
厌倦了 GitHub 私有仓库限制?Gitea 轻量开源,一台便宜 VPS 就能跑。本文讲清部署(Docker)、数据备份、Actions/CI 集成与团队权限管理。
专题连载:VPS 自建应用大赏
本文是该系列第 2 篇。阅读该系列其他文章:
延伸阅读
更多相关攻略推荐:从 Git Push 到秒级上线:CI/CD 流水线与"无中断"发布、【VPS 进阶玩法精选 030】用 VPS 搭建云端 IDE(cod、连云厂商也看不到你的数据?机密计算(Confidential Com、被割裂的"云上互联网":数据主权(GDPR)、本地化存储与主权云(S、什么时候非得要独立 IPv4?便宜国外 VPS 独立 IP 适用场景。
为什么要在 VPS 上自建 Gitea?
说白了,GitHub 虽然好用,但免费账号的私有仓库数量和功能一直有各种限制,组织协作、CI 时长、包存储都要按量计费。对个人开发者和小团队来说,这些费用日积月累不是小数。Gitea 是 Go 语言写的单二进制开源 Git 服务,采用 MIT 许可证,没有付费档、没有功能阉割,全部能力免费开放。它是 Gogs 的社区分支,官方镜像 gitea/gitea 提供多架构支持,连 ARM64 的树莓派都能跑。
更重要的是数据主权。你的代码、Issue、PR、CI 产物全部躺在自己的磁盘上,不用担心第三方拿去做 AI 训练或者偷偷遥测。对那些有合规要求、网络访问受限、或者干脆想"我的代码我做主"的团队,这种掌控感是 GitHub 给不了的。而且 Gitea 极省资源,1 GB 内存的机器就能跑起来,跟动辄要 4 GB 的 GitLab CE 形成鲜明对比。
还有个很实用的功能叫镜像(Mirror)。你可以把 GitHub 上重要的仓库设成定时自动镜像到自己的 Gitea,作为"平台风险"的兜底。万一哪天某个平台出问题,你的代码副本始终在手上。对把鸡蛋放在多个篮子里的谨慎派来说,这招非常省心。
Gitea 到底吃多少资源?VPS 怎么选
先看真实占用数据。Gitea 空闲时大约吃 80 到 150 MB 内存,多数实测落在 100 到 120 MB;即使有负载,通常也就到 300 MB 上下。对比一下:GitLab CE 空闲就要 3 到 6 GB 内存,官方最低建议 4 GB,光机器成本一个月就要 20 美元往上。这差不多是 Gitea 的几十倍差距。
配置梯度建议是这样:最低配 1 核 1 GB 内存加 SSD,单人用、测试用、或者纯粹当镜像用途完全够;推荐配置是 2 核 2 GB,给小团队 5 到 15 人加基础 CI 留点余量;如果是更大团队或 CI 跑得凶,再往上加。
磁盘方面有个很多人容易忽略的点:必须上 SSD,最好 NVMe。Git 的本质是海量小文件的随机读写,机械硬盘会把 clone、push、代码搜索拖到怀疑人生。系统加 Gitea 本体大约占 200 MB,但仓库体积会随项目增长,建议 20 GB 起步并规划可扩容存储。说白了,选型时磁盘 I/O 比单纯堆 CPU 和内存更关键。
数据库选型:SQLite 还是 MySQL/PostgreSQL?
这是部署 Gitea 最关键的决策,没有之一。SQLite 的优势是单文件、零配置,备份直接拷文件就行。但官方文档明确标注它"不推荐用于生产环境"。原因很硬核:SQLite 只支持单写线程、没有行级锁,一旦多人同时 push、建 issue、或者 CI 并发跑 job,就会触发 database is locked 错误和锁等待。
实测数据很有说服力:4 个并发线程以上,SQLite 的锁等待时间就明显增长;超过 10 个并发 CI job 基本会崩。社区共识是,只有当仓库少于 200 个、用户少于 50 人、日活跃写入少于 200 次、单机低频的场景,SQLite 才勉强可用。个人练手或者极小团队短期用用还行。
生产环境强烈建议上 MySQL 或 PostgreSQL。它们支持 MVCC、行级锁、读写并发分离。在写操作并发高的场景,PostgreSQL 平均延迟比 SQLite 低大约 25% 到 40%,P95 也更稳。PostgreSQL 在复杂查询、审计、权限场景更强;MySQL 的运维工具生态更成熟。我们的建议是:哪怕只是个人项目,也花 5 分钟配个 MariaDB 或 Postgres,后面扩展省大事。
迁移时有两个高频坑必须提醒。一是字符集:Gitea 默认推荐 utf8mb4,迁移时务必强制把表级和库级校对设成 utf8mb4_unicode_ci,否则含 Emoji 或特殊符号的 commit message 会报 SQL 异常。二是时区:SQLite 时间处理比较随意,MySQL/PG 则敏感,跨时区务必在连接串里显式写 loc=UTC,否则界面可能显示"未来时间"。
Docker Compose 一键部署要点
官方推荐用 Docker Compose 部署:Gitea 和数据库分容器隔离,升级时 pull 新镜像就行,配置集中在 docker-compose.yml,数据用持久卷保存。关键端口有两个:Web 默认 3000,SSH 的 Git 操作默认 22(容器内)。这个 22 端口会跟宿主机自己的 SSH 抢,新手常被坑。常见做法是把宿主机 SSH 改到 2222,或者把容器 SSH 映射到宿主机 2222(ports 写 "2222:22"),克隆地址相应变成 ssh://git@host:2222/user/repo.git。
安全加固的标准姿势是:把 Web 端口绑到 127.0.0.1:3000(只本机访问),再用 Nginx 或 Caddy 反代加 HTTPS 对外。注意反代必须带上 X-Forwarded-Proto https 这类头,否则克隆地址和邮件链接会错成 localhost。还有一个高频踩坑点:ROOT_URL 必须和对外访问地址(含协议、域名或端口)完全一致,否则头像不显示、克隆地址错乱。首次启动有数据库迁移会慢几秒,之后冷启动大约 2 到 3 秒。
升级很简单,docker compose pull 然后 up -d,Gitea 启动时自动跑 schema 迁移。但大版本升级前务必看 release notes,偶尔有手动迁移步骤。研究期间 Gitea 稳定版大约停在 1.24.x,写文章时请核对最新版本号。
数据备份与恢复策略
内置 gitea dump 命令能把数据打包成 zip,里面含 repos、data(含 attachments、avatars、lfs、indexers)、app.ini 和数据库 SQL。但官方明确提醒:dump 不保证一致性,建议备份期间停掉 Gitea 实例,避免迁移中途仓库和数据库状态不一致。Docker 下执行类似 docker exec -u git gitea gitea admin dump 再指定输出文件,然后把 zip 拷出容器。
更稳妥的做法是数据库用原生工具单独 dump(pg_dump 或 mysqldump),仓库目录单独 tar,两份独立。恢复这块要重点提醒:官方没有一键 restore 命令,得手动解压还原文件加数据库,再执行 gitea admin regenerate hooks 重新生成 Git 钩子,否则 push 会失败。
自动化很简单:用 crontab 每天凌晨执行 dump 脚本,再用 find 清理 30 天前的旧备份。最关键的一步是备份集要异地或离线存储,比如扔到对象存储或 S3,别和源机器放一起,否则机器没了备份也跟着没了。
用 Gitea Actions 跑轻量 CI/CD
Gitea 从 1.19 版本起内置了 Actions,语法和 GitHub Actions 兼容——把 .github/workflows 复制到 .gitea/workflows 多数情况能直接跑。架构上,你在站点管理里创建 Runner 拿到注册 token,runner 是独立组件 gitea/act_runner,基于 nektos/act,用 Docker 跑 job,机制和 GitHub 的托管 runner 一样。
启用方式是在配置里加 [actions] ENABLED = true 或环境变量 GITEA__actions__ENABLED=true,再 docker run gitea/act_runner 注册。但得诚实说限制:依赖 GitHub 专属 API 的复杂 workflow(比如对接 GitHub cache 服务的 actions/cache)需要改写;act_runner 的条件判断确定性不强,建议做成事件驱动(push、PR、schedule),复杂逻辑拆成多个 workflow,而且手动 trigger 不支持。
资源隔离也要注意:runner 建议容器化并限制并发,别跟 Gitea 主进程抢资源,否则构建一多主服务就卡。
团队权限与协作管理
Gitea 的组织加团队权限模型很清晰:Owner 全管,Developer 能读写 push/pull,Contributor 只读用于外部审查,CI/CD 角色是只读加 deploy key。认证方面可以禁用注册(DISABLE_REGISTRATION = true)做成纯私有实例,也支持 LDAP、OAuth2/OIDC,内置的 OAuth2 provider 还能给 Nextcloud、Grafana 这类服务当登录源。
SSH key 在 Web UI 添加;LFS 需要开 LFS_START_SERVER=true 并配置存储路径,大 LFS 建议挂独立卷或者 S3/MinIO。另外 Gitea 内置了包仓库,支持 Docker、npm、PyPI、Maven、NuGet、Cargo 等,无需额外配置,对小团队做内部依赖分发很方便。
Gitea vs GitHub vs GitLab:什么时候该自建?
Gitea 约等于 GitHub 90% 的核心功能(仓库、PR、issue、代码审查、Actions CI、包仓库),但资源只用了 GitLab 的约 10%。你失去的是 GitHub 的社区网络效应、Copilot、GitHub Pages 和开源发现力;换来的却是数据完全自有、不按用户计费、没有使用上限、零软件成本(只付 VPS)。
适合自建的场景:有合规要求、按用户计费累积成大头的团队、云访问受限或空气隔离的环境。不适合的场景:重度依赖 GitHub 生态和 Copilot、需要内置容器 registry 加完整 DevOps 一体化的,那 GitLab CE(4 GB 起步)更合适。另外如果看重社区治理,可以了解一下 Forgejo,它是 Gitea 的社区治理分支。
💡 延伸阅读:关于架构与基础设施的更多深潜指南,请前往 VPS 主题导读中心 (Hub) 获取全盘策略。