我用两台VPS分别部署了Gitea 1.24.4和Forgejo 15.0.3 LTS,用了一个月,踩了5个真实陷阱。这篇文章分享踩坑过程和对比结论,帮你少走弯路。
本文中提到VPS服务的链接为联盟推广链接,如果你通过链接购买,我可能获得少量佣金,不影响你的价格。
Gitea还是Forgejo?先说背景
2022年底,Gitea宣布成立商业公司Gitea Ltd,社区担忧项目走向商业化。部分核心贡献者fork出Forgejo,走社区治理路线。两套代码同源,但2023年后逐渐分化:
| 维度 | Gitea 1.24.4 | Forgejo 15.0.3 LTS |
|---|---|---|
| 开源协议 | MIT | MIT |
| 治理模式 | Gitea Ltd公司主导 | 社区治理(Codeberg托管) |
| CI/CD | Gitea Actions(兼容GitHub Actions) | Forgejo Actions(兼容GitHub Actions) |
| 包仓库 | Container/PyPI/NPM等 | Container/PyPI/NPM等 |
| 联邦协议 | 无 | ActivityPub(实验性) |
| 最低RAM | 512MB基本可用 | 512MB基本可用 |
| 语言 | Go | Go |
| 二进制 | 单文件部署 | 单文件部署 |
一句话总结差异:功能层面两者几乎持平;决策点在治理模式——你信任公司主导的迭代节奏,还是社区驱动的方向?
陷阱一:SSH克隆报Permission denied
这是最常见也是最让人崩溃的问题。你明明上传了SSH公钥,但git clone git@your-server:user/repo.git就是报错:
Permission denied (publickey).
fatal: Could not read from remote repository.
**原因**:Docker部署时,Gitea/Forgejo容器内的SSH服务(端口22)和宿主机SSH冲突。大多数人把容器SSH映射到2222端口,但忘了在~/.ssh/config里配置:
Host your-server.com
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519
**另一个常见原因**:容器内/data/git/.ssh/authorized_keys文件权限不对。Docker挂载的volume如果用了root创建,容器内git用户(UID 1000)读不到:
# 修复:在宿主机上修正权限
sudo chown -R 1000:1000 /path/to/gitea/data/git/.ssh
sudo chmod 600 /path/to/gitea/data/git/.ssh/authorized_keys
验证方法:
ssh -T git@your-server.com -p 2222
# 成功会返回:Hi username! You've successfully authenticated...
陷阱二:Docker网络导致反向代理502
Gitea/Forgejo放在Docker里,前面放Nginx或Caddy做HTTPS终止。最常见的问题是Nginx报502 Bad Gateway。
**原因一**:Nginx和Gitea不在同一个Docker网络里。如果你用docker compose部署Gitea,它默认创建一个名为gitea_default的网络。Nginx如果单独部署或用系统安装,根本找不到Gitea容器:
# docker-compose.yml 关键配置
services:
server:
image: gitea/gitea:1.24.4
networks:
- gitnet
nginx:
image: nginx:1.28
networks:
- gitnet # ← 必须在同一网络
networks:
gitnet:
driver: bridge
**原因二**:Nginx的proxy_pass用了IP地址而不是容器名。Docker容器重启后IP会变:
# ❌ 错误写法
proxy_pass http://172.18.0.3:3000;
# ✅ 正确写法
proxy_pass http://server:3000; # server是docker-compose中的服务名
陷阱三:SQLite在高并发时database is locked
Gitea/Forgejo默认用SQLite,对于个人或小团队够用。但当你说"够用",往往会遇到意外——比如CI/CD同时推送多个仓库时:
database is locked (5) (SQLITE_BUSY)
解决方案一:切换到PostgreSQL。这是最彻底的解决方式:
services:
db:
image: postgres:17
environment:
POSTGRES_DB: gitea
POSTGRES_USER: gitea
POSTGRES_PASSWORD: your-strong-password
volumes:
- ./postgres:/var/lib/postgresql/data
**解决方案二**:如果坚持用SQLite,在app.ini里加wal模式和超时:
[database]
DB_TYPE = sqlite3
PATH = /data/gitea/gitea.db
SQLITE_JOURNAL_MODE = WAL
SQLITE_BUSY_TIMEOUT = 5000
WAL模式允许读写并发,BUSY_TIMEOUT让等待锁的超时到5秒。这能缓解大部分轻量场景的锁问题。
陷阱四:自动化备份恢复踩坑
自建Git服务的核心理由是"数据在自己手里"。但有了数据不代表能恢复——我实测发现备份恢复有三个坑:
坑1:只备份了仓库,忘了备份数据库和LFS
完整的备份应包括:
#!/bin/bash
# gitea-backup.sh
GITEA_HOME="/path/to/gitea"
BACKUP_DIR="/backups/gitea/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# 1. 使用内置备份命令(Gitea 1.24+)
docker exec -u git server gitea dump -c /data/gitea/conf/app.ini
# 2. 或者手动备份关键目录
cp -r "$GITEA_HOME/data/git/repositories" "$BACKUP_DIR/repositories"
cp -r "$GITEA_HOME/data/gitea/lfs" "$BACKUP_DIR/lfs"
cp "$GITEA_HOME/data/gitea/gitea.db" "$BACKUP_DIR/" # SQLite
cp -r "$GITEA_HOME/data/gitea/conf" "$BACKUP_DIR/conf"
坑2:恢复时UID/GID不匹配
在新服务器恢复时,如果容器内git用户的UID变了,SSH和仓库权限全崩:
# 恢复前确保UID一致
docker exec server id git
# uid=1000(git) gid=1000(git)
# 如果不一致,在docker-compose.yml里指定
services:
server:
user: "1000:1000"
坑3:Gitea内置dump命令在rootless模式下路径不同
# root模式
docker exec -u git server gitea dump -c /data/gitea/conf/app.ini
# rootless模式(注意路径差异)
docker exec server gitea dump -c /data/gitea/conf/app.ini
# 输出文件在容器内 /app/gitea/gitea-dump-*.zip
陷阱五:Forgejo Actions Runner连接失败
Forgejo Actions与GitHub Actions语法兼容,但Runner首次部署经常连不上Forgejo实例:
**原因一**:Runner注册时用了localhost,但Runner在另一个容器:
# ❌ Runner容器内访问不到localhost:3000
forgejo-runner register --instance http://localhost:3000
# ✅ 使用容器间通信
forgejo-runner register --instance http://server:3000
**原因二**:忘了在app.ini里启用Actions:
[actions]
ENABLED = true
这是一个Gitea和Forgejo都需要的配置,默认关闭。很多人配完Runner才发现服务端没开。
我的最终选择
部署一个月后,我选了Forgejo 15.0 LTS,理由:
1. LTS支持到2027年7月,不用频繁升级
2. 社区治理让我对未来方向更有信心
3. 两者功能差异小到可以忽略,选哪个都不会错
但如果你更看重"跟GitHub最接近的上游",Gitea是更稳妥的选择。两者都是成熟项目,没有错误答案。
快速部署参考
最简Docker Compose(Forgejo + PostgreSQL):
version: "3"
services:
forgejo:
image: codeberg.org/forgejo/forgejo:15.0
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
volumes:
- ./forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
depends_on:
- db
db:
image: postgres:17
restart: always
environment:
- POSTGRES_DB=forgejo
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=change-me-now
volumes:
- ./postgres:/var/lib/postgresql/data
部署命令:
docker compose up -d
# 访问 http://your-server:3000 完成初始配置
# SSH克隆时记得指定端口2222
如果你的VPS配置宽裕(2GB+ 内存),可以考虑同时跑OpenClaw做AI Agent自动化——👉 立即参与:https://platform.minimaxi.com/subscribe/token-plan?code=E5yur9NOub&source=link
常见问题
Q: Gitea和Forgejo能互相迁移吗?
A: 可以。两者数据库格式兼容。从Gitea迁移到Forgejo,只需备份Gitea数据,用Forgejo相同版本启动指向同一数据库即可。建议先在测试环境验证。
Q: 个人开发者需要Actions功能吗?
A: 取决于你的自动化需求。如果你用GitHub Actions做CI/CD,自建Git服务的Actions可以无缝迁移workflow文件。如果只是存代码、做代码审查,不开Actions也完全够用。
Q: 512MB内存的VPS能跑吗?
A: 基本可用(SQLite + 关闭Actions),但建议至少1GB。如果开PostgreSQL,2GB更安心。推荐Vultr $2.5/月起的高性能NVMe实例:https://www.vultr.com/?ref=9890714
📌 本文由 AI 辅助生成并经人工审核发布 | TechPassive — AI 驱动的内容测试站点,专注于效率工具与 SaaS 真实评测
🔗 精选推荐工具
使用以下链接支持我们持续产出高质量内容(点击可直接前往购买):