最稳妥的部署方式是二进制部署,因其省资源、免编译、高安全性;必须创建专用低权限用户(如git)并严格限定目录所有权,避免root运行导致权限泛滥,同时需正确配置GITEA_WORK_DIR、WorkingDirectory、Environment及端口监听等关键参数。

直接用二进制方式部署 Gitea 是最稳妥的选择,尤其在资源有限的云服务器(比如 1GB 内存)上,比 Docker 更省资源、比源码编译更省事,也比直接跑在 root 下更安全。
为什么不用 root 用户运行 gitea
root 运行会带来权限泛滥风险:一旦 Web 界面或 SSH 入口被利用,攻击者可能直接拿到系统最高权限。Gitea 官方文档明确建议使用专用低权限用户。常见错误现象包括:
- 启动后
gitea web报错permission denied,其实是日志目录或数据库文件被 root 创建、git 用户无权写入 - Web 界面能打开,但创建仓库失败,提示
failed to init repository,根源常是/home/git/data所有者不是 git - systemd 服务启动成功但状态显示
inactive (dead),多半是User=git配置了,但目录权限没同步改
正确做法是创建隔离用户并严格限定路径所有权:
- 运行
sudo adduser --system --shell /bin/bash --gecos 'Gitea' --disabled-password --home /home/git git - 立即执行
sudo chown -R git:git /home/git,别等后续步骤 - 所有 Gitea 相关目录(
custom、data、log)必须由git用户完全拥有,不能只靠chmod 755补救
gitea web 启动失败的三个高频原因
即使用户和目录都对了,gitea web 仍可能静默退出或监听失败。核心问题往往不在 Gitea 本身,而在环境变量和工作路径。
-
GITEA_WORK_DIR必须显式设置,否则 Gitea 会默认用当前 shell 的$HOME—— 如果你用sudo -u git bash进入,$HOME可能仍是/root,导致配置和数据写到错地方 -
-c指定的配置文件路径必须存在且可读,推荐统一放在/home/git/custom/conf/app.ini,首次启动前手动创建空文件并chown git:git - 端口被占是隐形杀手:
netstat -tuln | grep :3000查一下,Ubuntu 默认可能有 snap 版的 lxd 或其他服务占着 3000 端口;换端口可在app.ini中改HTTP_PORT = 3001
验证是否真启动:不要只看终端输出,用 sudo -u git ss -tuln | grep :3000 确认监听状态,再 curl 测试:curl -I http://localhost:3000 应返回 200 OK 或重定向。
systemd 服务里 WorkingDirectory 和 Environment 怎么配才不踩坑
很多教程抄来就用,但实际中 WorkingDirectory 设错会导致 gitea web 找不到 custom/conf/app.ini,Environment 缺失会让 SQLite 初始化失败。
-
WorkingDirectory=/home/git是底线,不能写成/home/git/custom或留空;Gitea 会从这里向上找custom/conf/app.ini -
Environment=HOME=/home/git USER=git必须写全,否则 SQLite 数据库路径(默认HOME/data/gitea.db)会变成/root/data/gitea.db - 别信 “
Type=simple就够了”——如果 Gitea 启动慢(比如首次初始化数据库),要加TimeoutSec=300,否则 systemd 会误判为启动失败并反复重启
改完服务文件记得 sudo systemctl daemon-reload && sudo systemctl restart gitea,然后用 sudo journalctl -u gitea -f 实时盯日志,比盲猜高效得多。
Docker 方式部署时 /data 挂载点权限容易被忽略
Docker 跑 Gitea 最大的陷阱不是镜像拉取失败,而是容器内进程(以 git 用户身份运行)无法写入宿主机挂载的 /var/lib/gitea 目录。
- 宿主机上先执行
sudo mkdir -p /var/lib/gitea/{custom,data,log},再sudo chown 1001:1001 /var/lib/gitea(Gitea 官方镜像固定用 UID/GID 1001) - 别用
docker run -v /var/lib/gitea:/data就完事——必须确认/data在容器内是git用户可写,否则初始化页面卡在 “Creating database…” - SQLite 默认路径是
/data/gitea.db,如果挂载后权限不对,Gitea 会静默降级到内存数据库,重启即丢数据,这种故障极难排查
最保险的验证方式:启动容器后,docker exec -u 0 -it gitea ls -l /data 看属主,再 docker exec -u 1001 -it gitea touch /data/test 测试写入权限。
真正麻烦的从来不是“怎么装”,而是“谁在哪个路径下以什么身份读写了什么”。Gitea 本身很轻,但 Linux 权限模型不会因为你用的是 Go 就网开一面。











