小型团队场景:轻量完整的 Gitea 开源版本
除非配置
ENABLE_PUSH_CREATE_USER = true,否则仓库要先在WEB中创建,才能使用。

为 Go 语言编写,从 Gogs fork 后独立发展,社区驱动,是目前最主流的轻量自托管 Git 方案。同时,Web 界面做日常管理非常方便。
- Forgejo 是22 年从 Gitea fork 的完全社区驱动版本,坚持 100% 开源,不设商业公司控制,但文档只有英文。
- Gitea 架构是单机优先、轻量化,没有 GitLab CE 那种面向大规模团队的后台任务集群、分布式队列设计,人数上去后体验会明显下滑。
| v1.27.1 实际内存180M | 权限能力 |
|---|---|
| – 轻量且功能均衡:空闲约 80-150 MB,远轻于 GitLab – 社区极其活跃,版本迭代快,中文文档完善 – 功能全面:组织、团队、分支保护、Wiki、Issue、PR、包注册表、Actions CI – 部署方式多:二进制、Docker、包管理器均可 – 支持 SQLite 单机模式,也支持 MySQL/PostgreSQL 扩缩容 | – 组织级 + 仓库级双层权限 – 支持角色:所有者、管理员、写入者、读取者 – 分支保护规则:可限制谁能推送、是否需要 PR 审核 – 支持私有仓库、内部仓库、公开仓库三种可见性 |
安装
- 官方:使用二进制文件安装、Gitea 下载
- 环境准备:见 Git Server for Bare,Git 版本 >= 2.0
下载 bin 文件
# 下载 120M
$ sudo mkdir -p /opt/gitea
$ sudo wget https://dl.gitea.com/gitea/1.27.1/gitea-1.27.1-linux-amd64
# SHA-256 验证 86a7ac26e7f9c9cca0f56c4fac07fff205d5fc3bca0e54af23a204f07b833bc9
$ sha256sum gitea-1.27.1-linux-amd64
$ sudo chmod +x gitea-1.27.1-linux-amd64
git用户与路径准备
# 删除已有的 git 用户
ps -u git
userdel -r git
groupdel git
# 创建用户:useradd 是底层工具,adduser 是debian上层封装
# --system 创建系统账户:UID 从系统范围分配(通常 <1000),无密码过期策略,不创建 /home 下的用户目录(除非手动指定)
# --group 创建一个与用户同名的组
# --disabled-password 禁用密码登录
adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
#useradd --system --shell /bin/bash --comment 'Git Version Control' --create-home --home-dir /home/git --user-group --password '!' git
# 可选,当前用户加入git组,方便后面看文件;注意:要退出会话,重新才生效。
$ sudo gpasswd -a $USER git
# 创建工作路径,按你的实际情况来,官方文档是 /var/lib/gitea/{custom,data,log}
$ sudo mkdir -p /data/www/gitea/{custom,data,log}
$ sudo chown -R git:git /data/www/gitea/
$ sudo chmod -R 750 /data/www/gitea/
# Linux 目录权限规则:**要进入一个子目录,必须对路径上每一级父目录都拥有 `x`(execute/search)权限**,所以也要注意上级目录的权限。否则,服务启动失败。
$ sudo chmod o+x /data
# 创建配置文件路径
$ sudo mkdir /etc/gitea
$ sudo touch /etc/gitea/app.ini
$ sudo chown root:git -R /etc/gitea
$ sudo chmod g+w /etc/gitea/app.ini
创建 systemd 服务
# /usr/local/bin 创建链接
$ sudo ln -s /opt/gitea/gitea-1.27.1-linux-amd64 /usr/local/bin/gitea
$ sudo vim /usr/lib/systemd/system/gitea.service
# 修改 user,home 目录以及其他必须的初始化参数,如果使用自定义端口,则需修改 PORT 参数,反之如果使用默认端口则需删除 -p 标记。
# 激活 gitea 并将它作为系统自启动服务:
$ sudo systemctl enable gitea
$ sudo systemctl start gitea && sudo systemctl status gitea
# 运行成功后,查看日志
$ sudo journalctl -u gitea --no-pager -n 50
没有 /data 与 /data/www 的 other 执行权限,服务启动报错。
- 原因:Linux 目录权限规则:要进入一个子目录,必须对路径上每一级父目录都拥有
x(execute/search)权限,
Aug 07 16:44:33 vps260315 systemd[1]: Started gitea.service - Gitea (Git with a cup of tea).
Aug 07 16:44:33 vps260315 (gitea)[133658]: gitea.service: Changing to the requested working directory failed: Permission denied
Aug 07 16:44:33 vps260315 systemd[1]: gitea.service: Main process exited, code=exited, status=200/CHDIR
Aug 07 16:44:33 vps260315 systemd[1]: gitea.service: Failed with result 'exit-code'.
gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
[Service]
# 如果你的仓库包含大量文件并因此遇到 HTTP 500 错误,请取消下面这行的注释
# LimitNOFILE=524288:524288
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/data/www/gitea
# 如果使用 Unix 套接字:告知 systemd 创建 /run/gitea 目录,其中将存放 gitea.sock 文件(手动创建 /run/gitea 不可行,因为该目录在重启后不会保留)
#RuntimeDirectory=gitea
# Web 的默认端口是 3000,建议到 /etc/gitea/app.ini 中配置,而不是使用 gitea web --port 8080 参数
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/data/www/gitea
[Install]
WantedBy=multi-user.target
配置
Nginx 反代:独立域名
- 反向代理 | Gitea Documentation
app.ini配置
[server]
# 需要使用对外服务的URL,比如Nginx反代的URL,注意以/结尾
ROOT_URL = https://git.t725.cn/
nginx站点配置
server {
...
location / {
client_max_body_size 512M;
proxy_pass http://127.0.0.1:3000;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
配置生效:
$ sudo nginx -t && sudo nginx -s reload
$ sudo systemctl restart gitea && sudo systemctl status gitea
$ sudo journalctl -u gitea --no-pager -n 50
app.ini
在配置禁用很多功能后,观察并不能将内存占用降下来,约180M没有变化;所以,不需要去特意关闭功能。
附录
systemd 服务配置文件的目录与区别
| 优先级 | 目录 | 来源 | 用途 |
|---|---|---|---|
| 🥇 最高 | /etc/systemd/system/ | 管理员手动创建/修改 | 系统级自定义配置,永久生效,且不会被包管理器覆盖。 |
| 🥈 | /run/systemd/system/ | 运行时动态生成 | 临时覆盖,重启后丢失 |
| 🥉 | /usr/lib/systemd/system/ | 软件包安装 (RHEL/Fedora/Arch) | 发行版提供的默认单元文件,永远不要直接修改这里的文件,更新会被覆盖。 |
| 🥉 | /lib/systemd/system/ | 软件包安装 (Debian/Ubuntu) | 同上,Debian 系的路径 |
| 🔻 最低 | /usr/local/lib/systemd/system/ | 本地编译安装的软件 | 第三方/自编译软件的单元文件,在 Ubuntu 24.04 无此目录 |
/var/lib/gitea/{custom,data,log}
Gitea 的运行时数据根目录(由 GITEA_WORK_DIR 或 APP_DATA_PATH 指定),各自职责严格分离:
/var/lib/gitea/
├── custom/ ← 自定义配置与静态资源覆盖
├── data/ ← 核心业务数据存储
└── log/ ← 运行日志
🎨 custom/ — 自定义层
设计哲学:所有用户自定义内容集中于此,升级 Gitea 二进制时不会被覆盖。
💡custom/的内容在 Gitea 启动时会被”叠加”到内置资源之上,相当于一个透明的覆盖层。
| 子路径 | 内容 | 说明 |
|---|---|---|
conf/app.ini | 主配置文件 | 若未通过 --config 另行指定,则从这里读取 |
templates/ | 模板覆盖 | 放置同名模板文件即可覆盖内置模板,无需改源码 |
public/ | 静态资源覆盖 | 自定义 CSS/JS/图片/logo,优先级高于内置 public/ |
options/ | 选项文件覆盖 | 如 locale/、gitignore/、license/、readme/ 模板 |
mail/ | 邮件模板 | 自定义通知邮件的 HTML/文本模板 |
💾 data/ — 业务数据
⚠️ 这是备份的核心目标,丢失即丢失仓库和用户数据。
| 子路径 | 内容 | 说明 |
|---|---|---|
gitea-repositories/ | Git 裸仓库 | 每个仓库一个 .git 目录,按 {owner}/{repo}.git 组织 |
lfs/ | Git LFS 对象 | LFS 指针指向的实际大文件,按 OID 哈希分目录存储 |
attachments/ | 附件存储 | Issue/PR 上传的文件、头像、仓库归档包等 |
avatars/ | 用户/组织头像 | 上传的自定义头像文件 |
repo-archive/ | 仓库归档缓存 | 生成的 zip/tar.gz 下载包缓存 |
packages/ | 包注册表数据 | Container Registry / npm / PyPI 等包的存储 |
actions/ | Gitea Actions | Runner 日志、Artifact、Secrets 加密数据 |
sessions/ | 会话数据 | 当 session provider 为 file 时的会话文件 |
queues/ | 持久化队列 | 异步任务队列的磁盘持久化数据(LevelDB) |
indexers/ | 搜索索引 | Bleve/Elasticsearch 的代码搜索和 Issue 搜索索引 |
tmp/ | 临时文件 | 上传中转、导出任务等产生的临时文件 |
⚠️ 注意:如果使用外部数据库(MySQL/PostgreSQL),用户、Issue、PR 等元数据存在数据库中,但上述文件系统数据不会存入数据库,两者必须同时备份。
📝 log/ — 日志
| 文件/子路径 | 内容 | 说明 |
|---|---|---|
gitea.log | 主应用日志 | Web 请求、内部操作、错误信息 |
gitea.log.1 / .gz | 轮转历史日志 | 由内置 logger 自动轮转 |
http.log | HTTP 访问日志 | 仅在 [log] ENABLE_ACCESS_LOG=true 时生成 |
router.log | 路由日志 | 请求路径、状态码、耗时 |
xorm.log | SQL 查询日志 | 仅在 [database] LOG_SQL=true 时生成(⚠️ 性能影响大) |
mailer.log | 邮件发送日志 | SMTP 发送记录与错误 |
console.log | 控制台输出副本 | 当同时配置了文件和控制台输出时 |
💡 日志行为完全由
app.ini的[log]段控制,可配置级别、格式、轮转策略、独立输出器等。生产环境建议至少保留Info级别的主日志 + 独立的Error级别日志。
示例 gitea.service
只有注释行翻译为中文了
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
###
# 别忘了添加数据库服务的依赖项
#Wants=mysql.service / mariadb.service / postgresql.service / memcached.service / redis.service
#After=mysql.service / mariadb.service / postgresql.service / memcached.service / redis.service
#
###
# 如果主 HTTP/HTTPS 使用套接字激活(Socket Activation)
#After=gitea.main.socket
#Requires=gitea.main.socket
#
###
# (你也可以为 Gitea 提供 HTTP 回退套接字和/或 SSH 套接字)
# /etc/systemd/system/gitea.main.socket 示例如下
###
##
## [Unit]
## Description=Gitea Web 套接字
## PartOf=gitea.service
##
## [Socket]
## Service=gitea.service
## ListenStream=<某个端口>
## NoDelay=true
##
## [Install]
## WantedBy=sockets.target
##
###
[Service]
# 如果你的仓库包含大量文件并因此遇到 HTTP 500 错误,请取消下面这行的注释
# LimitNOFILE=524288:524288
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
# 如果使用 Unix 套接字:告知 systemd 创建 /run/gitea 目录,其中将存放 gitea.sock 文件 (手动创建 /run/gitea 不可行,因为该目录在重启后不会保留)
#RuntimeDirectory=gitea
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# 如果你将 Git 安装到了默认 PATH 以外的目录前缀下(例如,当你与发行版自带的 Git 并行安装了其他版本的 Git 时),请取消下面这行的注释,并将该前缀添加到 PATH 中
# 如果你想启用 Git LFS 支持,别忘了把 git-lfs 二进制文件也放到下面的 PATH 中
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
#
###
# 如果你想让 Gitea 绑定到 1024 以下的端口,请取消下面两行的注释,或者像上面那样使用套接字激活来向 Gitea 传递端口
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE
###
# 在某些情况下,当同时使用 CapabilityBoundingSet 和 AmbientCapabilities 选项时,你可能需要将下面的值设为 false,以允许将能力(capabilities)应用到 gitea 进程上。
# 如果下面的值设为 true,将会对 gitea 服务进行沙箱隔离,阻止任何进程在宿主用户命名空间中以特权身份运行。
###
#PrivateUsers=false
###
[Install]
WantedBy=multi-user.target
发表回复
要发表评论,您必须先登录。