Gitea安装失败主因是用户、权限和路径配置不当;必须创建专用系统用户(如git),确保所有数据目录及配置文件归属该用户并具备读写权限,Docker部署需完整挂载/data卷、指定UID 1001,并在首次访问前预置custom/conf/app.ini基础配置,否则网页向导将写死默认值导致后续自定义失效。

gitea 安装不难,但直接跑起来就出问题——90% 的失败不是因为不会装,而是没处理好用户、权限和路径这三件事。
二进制部署必须用专用用户运行
gitea 不是脚本工具,它会读写 SSH 密钥、生成日志、创建仓库目录,所有这些操作都依赖明确的文件所有权。用 root 或普通用户硬起,大概率遇到:
- failed to load SSH public key
- upload failed: permission denied
- 日志里反复出现 open /data/gitea/log/gitea.log: permission denied正确做法是:
- 创建系统用户:
sudo adduser --system --home /home/git git - 所有数据目录(
/home/git/data、/home/git/log、/home/git/custom)必须由该用户完全拥有:sudo chown -R git:git /home/git - 配置文件若放在
/etc/gitea/app.ini,需确保git用户能读:sudo chmod 640 /etc/gitea/app.ini且sudo chgrp git /etc/gitea/app.ini
Docker 启动必须挂全 /data 卷,不能只挂子目录
docker run -p 3000:3000 gitea/gitea 看似简单,实则危险:容器一删,所有用户、仓库、配置全丢。根本原因在于 Gitea 默认把一切存在 /data 下,而 Docker 默认使用临时文件系统。
必须显式挂载:
-
-v /var/lib/gitea:/data(完整映射,不是/var/lib/gitea/data) -
-u 1001:1001(官方镜像固定 UID,不是 root) -
-v /etc/localtime:/etc/localtime:ro(否则 Web 界面时间错乱)
首次启动前,还得预建目录并设权:
sudo mkdir -p /var/lib/gitea/{custom,data,log}sudo chown -R 1001:1001 /var/lib/gitea
app.ini 配置必须在首次访问前就位,否则网页向导写死默认值
第一次打开 http://IP:3000 进安装向导,它会自动生成 /data/gitea/conf/app.ini 并写入数据库地址、管理员密码等。一旦生成,后续挂载的 /var/lib/gitea/custom/conf/app.ini 就被忽略——Gitea 优先读 /data/gitea/conf/app.ini。
解决办法只有两个:
- 启动前手动创建
/var/lib/gitea/custom/conf/app.ini,至少包含[database]和[server]段(哪怕只是空占位) - 或者跳过向导:容器启动后
docker exec -it gitea bash,手动跑gitea migrate和gitea admin create-user,再停容器、拷出/data/gitea/conf/app.ini修改,重新挂载启动
关键项别漏:
DOMAIN = git.example.com-
ROOT_URL = <a href="https://www.php.cn/link/48388b43175c3c7bc2c83a6225387a1a">https://www.php.cn/link/48388b43175c3c7bc2c83a6225387a1a</a>(必须和反向代理或实际访问地址一致,否则 clone 地址错) -
SSH_PORT = 2222(对应 Docker 的-p 2222:22)
启动失败常见原因和验证点
gitea web 命令退出无声?先查这三项:
- 端口冲突:sudo ss -tlnp | grep :3000,若被占,改 HTTP_PORT = 3001 并同步更新 app.ini
- Git 版本太旧:git --version 必须 ≥ 2.20;CentOS 7、统信 UOS 默认是 1.8.x,得手动升级
- SQLite 路径不可写:检查 APP_DATA_PATH 指向的目录是否属 git 用户且有写权限,ls -ld /home/git/data 看一眼就知道
真正麻烦的不是第一次跑起来,而是改域名、开 HTTPS、换数据库时,app.ini 里一堆关联项要同步更新——比如 ROOT_URL、SSH_DOMAIN、OFFLINE_MODE,漏一个,clone 或 push 就报错。


















