结论先行:3 人以上团队、或有隐私合规要求的独立开发者,花 5 美元/月的小 VPS 用 Docker 自建 Gitea 就值得,1G 内存跑得动,数据完全在自己手里。个人或 1-2 人小团队直接用 GitHub 免费私有仓库更省心,别为自建掏维护时间。

想要代码完全自主可控?不想把私有项目放到 GitHub?这篇带你用 Gitea 搭建属于自己的 Git 服务器。

全景图解导览:Git服务器自建:Gitea实战部署完整指南 STAGE 01 · 问题起爆 写在前面 • 个人开发者:GitHub私有仓 库免费又省心 • 1-2人小团队:Git托管平台… 定位核心风险卡点 STAGE 02 · 机制拆解 期望目标 • ✅搭建自托管Git服务器: 完全自主可控,支持私有… • ✅配置域名访问+HTTPS:不… 理清底层因果逻辑 STAGE 03 · 方案对照 计划思考 • 为什么要自建Git服务 器?:先判断你是否真的需… • 为什么选Gitea而不是… 对齐量化实测标尺 STAGE 04 · 工程落地 操作步骤 • 推荐:Ubuntu 22.04 LTS/ 24.04 LTS • 其他:Debian 11+… 锁死生产确定性

0、写在前面

GitHub虽好,但有两个硬伤:跨国网络访问慢,私有代码终究在别人平台。

如果你遇到以下场景,值得自建:

✅ 3 人以上小团队:需要权限管理、私有仓库,但 GitLab CE 太重
✅ 公司合规要求:代码不能上第三方平台
✅ 学习 DevOps:想练手 Docker Compose、Nginx、SSL、CI 集成

❌ 这些场景没必要:

  • 个人开发者:GitHub 私有仓库免费又省心
  • 1-2 人小团队:Git 托管平台够用,维护成本 > 收益

这时候,考虑自建 Git 服务器吧。

你可能听过 GitLab,但它太重了,4G 内存起步,CPU 跑满,小 VPS 根本扛不住。

Gitea 是个更好的选择:轻量、功能全、社区活跃,1G 内存就能跑得很欢。

问题现场解剖:写在前面 ⚠️ 从问题出发:表面症状是如何一步步演变为生产故障或降权的? 独立开发者工具箱 · CH-57 · 核心卡点传导链 1. 个人开发者 GitHub私有仓库免费又省心 需通过真实环境实测核验 症结:认知偏差与配置盲区 2. 1-2人小团队 Git托管平台够用,维护成本收 益 传导:隐性劣化与边界失守 3. 缺乏验证流程 无量化观测指标与自动化止损防 线 破局:量化指标与工程验证 ✅ 破局核心原则(结论先行) 3人以上团队、或有隐私合规要求的独立开发者,花5美元/月的小VPS用Docker自 建Gitea就值得,1G内存跑得动,数据完全在自己手里。个人或1-2人小团队直接…

1、期望目标

这篇文章带你完成:

  • ✅ 搭建自托管 Git 服务器:完全自主可控,支持私有/公开仓库
  • ✅ 配置域名访问 + HTTPS:不用记 IP,SSL 证书自动续期
  • ✅ 设置邮件通知:Push/PR/Issue 时收到邮件提醒
  • ✅ 配置自动备份:数据安全有保障
  • ✅ 了解资源占用:知道需要多大 VPS 才够用

做完这些,你就有了一个功能完整的代码托管平台,可以给自己、小团队用,甚至作为内部 Git 服务器。

底层机制与架构拆解:期望目标 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 ✅搭建自托管Git服务… 完全自主可控,支持私有 /公开仓库 S2 ✅配置域名访问+… 不用记IP,SSL证书自动 续期 S3 ✅设置邮件通知 Push/PR/Issue时收到邮 件提醒 S4 ✅配置自动备份 数据安全有保障 底层规则强约束 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

2、计划思考

为什么要自建 Git 服务器?

先判断你是否真的需要自建:

适合自建的场景:

  • ✅ 3 人以上小团队:需要权限管理、私有仓库,但 GitLab CE 太重
  • ✅ 公司合规要求:代码不能上第三方平台
  • ✅ 学习 DevOps:想练手 Docker Compose、Nginx、SSL、CI 集成

不适合自建的场景:

  • ❌ 个人开发者:GitHub 私有仓库免费又省心
  • ❌ 1-2 人小团队:Git 托管平台够用,维护成本 > 收益

如果确定要自建,先了解差异:

| 谁能看到代码 | GitHub员工(理论上) | 只有你和团队成员 |
| 数据存在哪 | GitHub服务器(多地域备份) | 你的VPS(硬盘坏了可能丢数据) |
| 谁负责维护 | GitHub团队(24/7) | 你自己(周末出问题得自己修) |
| 成本 | 私有仓库免费 | VPS月费$5起 |

为什么选 Gitea 而不是 GitLab CE?

这俩是最流行的自托管 Git 平台,但定位不同:

对比项 Gitea GitLab CE
资源占用 1G 内存够用 建议 4G+
部署难度 Docker 一条命令 需要配置 Redis、PostgreSQL
功能完整性 85%(够用) 95%(更全)
CI/CD 需要配置 Drone/Jenkins 内置 GitLab CI
性能 轻量快速 较重
适合场景 个人/小团队 中大型团队

如果你只是想要一个 GitHub 替代品,不需要 GitLab CI 那些复杂功能,Gitea 够用且省资源。

Gitea vs Gogs vs Forgejo

Gogs 是这一系的鼻祖,2016 年 Gitea 从它 fork 出来,起因就是 Gogs 更新太慢。到现在 Gitea 的活跃度和功能早超过 Gogs,新项目别再选 Gogs。

Forgejo 是 2026 年选型绕不开的名字。2022 年底 Gitea 被悄悄转给一家盈利公司(Gitea Ltd.),社区对治理透明度不满,于 2022 年 12 月 fork 出 Forgejo,2024 年初正式成为硬分叉,交由德国非营利组织 Codeberg e.V. 托管。两者界面和功能几乎一样,Gitea 的镜像、配置 Forgejo 基本能直接套。

差别在哪:Gitea 背后有公司,Forgejo 坚持社区非营利;Forgejo 自带 Forgejo Actions(兼容 GitHub Actions 语法的 CI),而 Gitea 要跑 CI 得另接 Drone 或 Jenkins。介意「谁掌控这个项目」的,选 Forgejo;只想要轻量 Git 托管、不在意治理的,Gitea 用着没区别。

部署方式:Docker vs 二进制

推荐 Docker,原因:

  • 环境隔离,不会搞乱系统
  • 升级简单,换个镜像就行
  • 数据卷管理方便
  • 一键部署 PostgreSQL/Redis

二进制方式更灵活,但需要自己配置服务、数据库、权限,容易出错。

数据库选择:SQLite vs PostgreSQL vs MySQL

数据库 适用场景 优点 缺点
SQLite 个人使用、小团队 零配置,文件即数据库 并发性能差
PostgreSQL 推荐 性能好,功能强大 需要额外部署
MySQL/MariaDB 现有环境 兼容性好 性能略逊 PostgreSQL

推荐:小项目用 SQLite,生产环境用 PostgreSQL。

整体架构

开发者 Nginx (SSL/HTTPS) 端口 443/80 Gitea 端口 3000 Docker PostgreSQL 或 SQLite Git 仓库 SMTP 邮件 定期备份 cron 任务

架构说明:

这个架构是这样跑起来的:Nginx 在前面处理 HTTPS 和域名,Gitea 跑在 Docker 容器里负责核心功能,PostgreSQL 存数据,SMTP 发邮件,最后用 cron 定期备份保平安。

这就像你家小区的门卫:来访客人先到门卫登记,门卫确认没问题后才把你带到你要去的楼栋。

访问流程(简化版):

  1. 你 → 浏览器打开 https://git.yourdomain.com
  2. Nginx → 转发到 Gitea 容器(端口 3000)
  3. Gitea → 读写 PostgreSQL 数据库

其他(邮件/备份)是可选配置,后面章节再说。


3、操作步骤

3.1 前置准备

需要 VPS

推荐配置:

配置 最低 推荐
CPU 1 核 2 核
内存 1G 2G
磁盘 20G 40G+
带宽 1M 5M+

推荐 VPS 商(按预算选):

  • Vultr:全球节点多,按小时计费,支持高配
  • DigitalOcean:稳定,文档全
  • Linode:性能好,适合长期
  • 搬瓦工:CN2 线路快,适合国内访问

域名(可选)

如果你有域名,解析到 VPS IP 即可:

1
git.yourdomain.com  A  记录  →  你的 VPS IP

没有域名也可以,直接用 IP + 端口访问(但没有 HTTPS)。

系统要求

  • 推荐:Ubuntu 22.04 LTS / 24.04 LTS
  • 其他:Debian 11+、CentOS 8+ 也可以,命令略有差异

本文以 Ubuntu 为例。


3.2 安装 Docker + Docker Compose

Gitea 官方提供了 Docker 镜像,部署最方便。

💡 为什么用 Docker Compose?

Gitea + PostgreSQL + Nginx 三个服务,用 Compose 一个配置文件就能管起来,方便备份和迁移。

Docker 27.0+已内置 compose,低版本需单独安装 docker-compose plugin

一键安装 Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 更新系统
sudo apt update && sudo apt full-upgrade -y

# 安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 配置防火墙
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable

# 把当前用户加入 docker 组(免 sudo)
sudo usermod -aG docker $USER

# 重新登录后生效,或执行
newgrp docker

验证安装

1
2
3
4
5
docker --version
# 输出:Docker version 27.x.x, build xxx

docker compose version
# Docker 27+ 已内置 compose

💡 为什么用 Docker Compose?

Gitea + PostgreSQL + Nginx 三个服务,用 Compose 一个配置文件就能管起来,方便备份和迁移。


3.3 部署 Gitea 容器

创建项目目录

1
2
3
4
5
# 创建工作目录
mkdir -p ~/gitea && cd ~/gitea

# 创建数据目录(挂载到容器)
mkdir -p data/postgres data/gitea

编写 docker-compose.yml

1
nano docker-compose.yml

💡 版本说明:示例用的是 gitea/gitea:1.26(锁定版本,避免意外升级)。截至 2026 年 8 月最新稳定版是 1.27.1,建议把下面两处镜像都改成 gitea/gitea:1.27.1(或 latest,但锁版本更稳);升级时记得先 docker compose pull + up -d,数据卷不丢。

按 Ctrl+X 退出,Y 粘贴后保存,Enter 确认文件名

粘贴以下配置:

新手直接用 SQLite 版本(下面第一个),生产环境再用 PostgreSQL

SQLite 版本(适合个人使用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
services:
gitea:
image: gitea/gitea:1.26
container_name: gitea
environment:
- TZ=Asia/Shanghai # Change to your timezone, e.g. America/New_York, Europe/London
ports:
- "3000:3000"
- "222:22"
volumes:
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3

如果是 PostgreSQL 版本(生产环境推荐):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
services:
gitea:
image: gitea/gitea:1.26
container_name: gitea
environment:
- TZ=Asia/Shanghai # Change to your timezone, e.g. America/New_York, Europe/London
- DB_TYPE=postgres
- DB_HOST=db:5432
- DB_NAME=gitea
- DB_USER=gitea
- DB_PASSWD=your_password_here
ports:
- "3000:3000"
- "222:22"
volumes:
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
depends_on:
- db
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3

db:
image: postgres:15-alpine
container_name: gitea-db
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=your_password_here
- POSTGRES_DB=gitea
- TZ=Asia/Shanghai # Change to your timezone, e.g. America/New_York, Europe/London
volumes:
- ./data/postgres:/var/lib/postgresql/data
restart: always

⚠️ 重要:把两处 your_password_here 都换成强密码(DB_PASSWD 和 POSTGRES_PASSWORD)!

启动容器

1
2
3
4
5
# 启动
docker compose up -d

# 查看日志
docker compose logs -f gitea

看到包含 Listen on http://0.0.0.0:3000 的日志就说明启动成功了:

1
gitea  | 2026/07/02 12:00:00 ...  Listen on http://0.0.0.0:3000

访问测试

浏览器打开:http://YOUR_SERVER_IP:3000

应该能看到 Gitea 的初始化页面。

http://your-ip:3000 Gitea 初始化 数据库类型 管理员设置 立即安装

3.4 初始化 Gitea

首次访问会进入初始化向导,按步骤填写:

第一步:数据库设置

SQLite(选了这个就不用管其他的):

  • 数据库类型:SQLite3
  • 路径:/data/gitea/gitea.db

PostgreSQL(如果用了 compose 的 db 服务):

  • 数据库类型:PostgreSQL
  • 主机:db:5432
  • 用户:gitea
  • 密码:你设置的密码
  • 数据库名:gitea

第二步:基本设置

  • Gitea 基础设置:

    • 服务器域名:git.yourdomain.com(或你的 IP)
    • Gitea 运行端口:3000
    • Gitea 基础 URL:https://git.yourdomain.com/(或 http://YOUR_SERVER_IP:3000/)
  • 可选设置:

    • SSH 服务器域名:git.yourdomain.com 或 YOUR_SERVER_IP
    • SSH 端口:222(容器映射的 22)
    • Gitea SSH 端口:222

💡 SSH 端口说明

容器内部 SSH 是 22,映射到宿主机是 222,所以 clone 时用:
git clone ssh://[email protected]:222/user/repo.git

第三步:管理员账户

  • 用户名:admin(或其他)
  • 密码:设置强密码
  • 邮箱:你的邮箱

⚠️ 重要:管理员密码一定要用强密码,建议包含大小写字母+数字+符号

第四步:完成安装

点击「立即安装 Gitea」,几秒后跳转到登录页。

用刚才创建的管理员账户登录,你就能看到类似 GitHub 的界面了!

接下来可以开始创建仓库、邀请团队成员,或者配置更多高级功能(邮件通知、CI 集成等)。

Gitea A 仪表板 仓库 问题 Pull Requests 欢迎, Admin! 还没有仓库 点击「新建仓库」创建你的第一个代码仓库 新建仓库 快速开始 创建组织 团队协作 导入仓库 从其他平台迁移 探索仓库 发现开源项目

3.5 配置 Nginx 反向代理 + HTTPS

现在你已经可以通过 http://YOUR_SERVER_IP:3000 访问,但:

  • 没有域名,不方便
  • 没有 HTTPS,不安全
  • 端口号太难记

没有域名?跳过本节,直接用 http://YOUR_SERVER_IP:3000 访问

用 Nginx 解决这些问题。

为什么需要 Nginx?

现在你能通过http://YOUR_SERVER_IP:3000访问 Gitea,但有 3 个问题:

  1. 没有 HTTPS,密码和代码是明文传输(不安全)
  2. 端口 3000 太难记,每次都要输入
  3. 没有域名,换个 VPS IP 又要重新配置

Nginx 作为反向代理帮你解决这些问题。

安装 Nginx

1
sudo apt install -y nginx certbot python3-certbot-nginx

创建站点配置

1
sudo nano /etc/nginx/sites-available/git.yourdomain.com

粘贴以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 80;
server_name git.yourdomain.com;

# Let's Encrypt 验证路径
location /.well-known/acme-challenge/ {
root /var/www/html;
}

location / {
proxy_pass http://127.0.0.1:3000;
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;

# WebSocket 支持(浏览器中执行 Git 操作等功能需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}

⚠️ 把 git.yourdomain.com 换成你的域名。

启用站点

1
2
3
4
5
6
7
8
# 创建软链接
sudo ln -s /etc/nginx/sites-available/git.yourdomain.com /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo systemctl reload nginx

申请 Let’s Encrypt SSL 证书

1
sudo certbot --nginx -d git.yourdomain.com

按提示:

  1. 输入邮箱
  2. 同意服务条款
  3. 选择「Redirect HTTPS」(自动重定向到 HTTPS)

完成后,访问 https://git.yourdomain.com 应该能看到小绿锁了!

💡 证书自动续期:Let’s Encrypt 证书有效期 90 天,Certbot 会自动配置续期任务,不用担心过期。

修改 Gitea 配置

登录 Gitea,进入 Site Administration → Configuration:

1
2
3
4
5
6
7
[server]
PROTOCOL = https
ROOT_URL = https://git.yourdomain.com/
DOMAIN = git.yourdomain.com
SSH_DOMAIN = git.yourdomain.com
HTTP_PORT = 3000
SSH_PORT = 222

或者在服务器上编辑:

1
nano ~/gitea/data/gitea/conf/app.ini

找到 [server] 段,修改:

1
ROOT_URL = https://git.yourdomain.com/

重启容器:

1
2
cd ~/gitea
docker compose restart gitea

3.6 配置邮件通知

没有邮件通知,Push/Issue/PR 都会「静默」,容易错过更新。

注意:以下邮箱服务需要你有域名。如果没有域名,暂时跳过这一节,先用 Gmail

获取 SMTP 信息

推荐邮件服务商:

推荐方案(按场景选)

  • 国内用户:QQ 企业邮箱(免费,配置简单)
  • 海外用户:Gmail(每天 500 封,免费)
  • 需要大量发信:SendGrid/Mailgun(付费)

新手从 QQ 企业邮箱开始,5 分钟搞定。

服务商 免费额度 适合场景
Gmail 每天 500 封 个人使用
QQ 企业邮箱 无限免费 国内用户
SendGrid 每天 100 封 海外开发者
Mailgun 前 5000 封免费 需要 API 调用

QQ 企业邮箱示例(免费,推荐):

  1. 注册 腾讯企业邮箱
  2. 创建邮箱(如 [email protected])
  3. 获取 SMTP 信息:
    • 服务器:smtp.exmail.qq.com
    • 端口:465(SSL)或 587(STARTTLS)
    • 用户:你的完整邮箱地址
    • 密码:客户端专用密码(不是登录密码,需在邮箱设置中生成)

配置 Gitea 邮件

方式一:Web 界面配置

登录 Gitea → 右上角头像 → Site Administration → Configuration → Email

填写:

勾选 Enable Email Service 和 Use SMTP

路径说明:点击右上角头像 → 管理员面板 → 配置 → 邮件

方式二:编辑 app.ini

1
nano ~/gitea/data/gitea/conf/app.ini

找到 [email] 段(没有就添加):

1
2
3
4
5
6
7
8
9
10
[email]
ENABLED = true
FROM = Gitea <[email protected]>
PROTOCOL = smtp
SMTP_ADDR = smtp.exmail.qq.com:465
SMTP_USER = [email protected]
SMTP_PASSWD = your_password
USE_SSL = true
HELO_HOSTNAME = yourdomain.com
SKIP_VERIFY = false

重启容器:

1
2
cd ~/gitea
docker compose restart gitea

测试邮件

在 Gitea 中:Site Administration → Email → Send Test Email

填一个收件地址,发一封试试。

Gitea 用户 Push 通知 PR 更新提醒

3.7 创建仓库和组织

创建第一个仓库

点击右上角 + → New Repository:

  • 仓库所有者:你的用户名
  • 仓库名:my-first-repo(或其他)
  • 可见性:Private(私有)或 Public(公开)
  • 初始化:勾选「添加 README」

点击「创建仓库」。

克隆仓库

HTTPS 方式(推荐):

1
git clone https://git.yourdomain.com/YOUR_USERNAME/test-repo.git

SSH 方式:

先生成 SSH 密钥(如果还没有):

1
2
3
4
5
6
# 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "[email protected]"
# 一路回车即可(或设置密码短语)

# 查看公钥
cat ~/.ssh/id_ed25519.pub

复制公钥内容,在 Gitea 中添加:

  • 点击右上角头像 → Settings → SSH Keys → Add Key
  • 粘贴公钥,点击「Add Key」

然后克隆仓库:

1
git clone ssh://[email protected]:222/YOUR_USERNAME/test-repo.git

⚠️ SSH 端口说明

clone 时用端口 222(宿主机映射端口),不用管容器内部的 22。

如果不想每次都加端口,在 ~/.ssh/config 中配置:

1
2
Host git.yourdomain.com
Port 222

创建组织

如果是团队使用,可以创建组织:

+ → New Organization:

  • 组织名称:my-team 或 dev
  • 组织描述:团队描述

创建后,可以在组织内创建仓库、添加成员。

组织的好处:

  • 统一管理多个仓库
  • 团队成员权限统一配置
  • 便于项目分组和权限控制
组织结构 公司/团队 成员A 成员B 成员C 成员D 前端项目 后端API 文档

3.8 配置备份策略

数据很重要,定期备份是必须的。

备份什么

Gitea 的数据主要在:

目录/文件 说明
/srv/gitea/data 仓库数据、配置文件、附件
/srv/gitea/db PostgreSQL 数据库(如果用了)

手动备份

1
2
3
4
5
6
7
8
9
10
11
12
# 停止容器
cd ~/gitea
docker compose down

# 打包数据
tar -czf gitea-backup-$(date +%Y%m%d).tar.gz data/

# 重启容器
docker compose up -d

# 拷贝到本地(在你的电脑上)
scp youruser@yourvps:~/gitea/gitea-backup-*.tar.gz ./

💡 更安全的方案

  • 用 rclone 同步到云存储(Google Drive / Dropbox / S3)
  • 推荐用 Wasabi(对象存储便宜)或 Backblaze B2(有免费额度)
  • 定期测试恢复流程,确保备份可用

自动备份(cron)

1
2
# 编辑 crontab
crontab -e

添加:

1
2
# 每天凌晨 3 点备份
0 3 * * * cd ~/gitea && mkdir -p data/backup && docker compose exec -T gitea gitea dump -l /data/backup/ && tar -czf /tmp/gitea-backup-$(date +\%Y\%m\%d).tar.gz data/ && mv /tmp/gitea-backup-*.tar.gz ~/backups/

💡 更安全的方案

  • 用 rclone 同步到云存储(Google Drive / Dropbox / S3)
  • 定期测试恢复流程

4、收尾

关键配置文件位置

文件/目录 用途
~/gitea/docker-compose.yml Docker Compose 配置
~/gitea/data/gitea/conf/app.ini Gitea 主配置
/etc/nginx/sites-available/git.yourdomain.com Nginx 站点配置
/etc/letsencrypt/live/git.yourdomain.com/ SSL 证书路径

常用管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入 Gitea 容器
docker exec -it gitea bash

# 查看日志
docker compose logs -f gitea

# 重启 Gitea
docker compose restart gitea

# 更新 Gitea(拉取最新镜像)
docker compose pull && docker compose up -d

# 重置管理员密码
docker exec -it gitea gitea admin user change-password --username yourname --password newpassword

安全检查清单

  • [ ] SSH 密钥登录已配置(禁用密码登录)
  • [ ] HTTPS 已启用(小绿锁)
  • [ ] 防火墙只开放 80/443/SSH 端口
  • [ ] Gitea 管理员密码够强
  • [ ] PostgreSQL 密码够强
  • [ ] 邮件通知已测试通过
  • [ ] 定期备份已设置
  • [ ] 数据卷权限正确

这些都是我踩过的坑,列出来帮你省时间。

性能参考

基于实际使用经验:

场景 VPS 配置 用户体验
个人使用 1核1G 流畅
2-5 人团队 2核2G 流畅
5-20 人团队 2核4G 良好
20+ 人团队 4核8G+ 推荐
落地执行与验证流水线:收尾 按序执行以下四步流程,把定性经验转化为可自动巡检的工程防线 STEP 01 关键配置文件位置 |文件/目录|用途| 可复现验收标准 STEP 02 常用管理命令 bash 可复现验收标准 STEP 03 安全检查清单 SSH密钥登录已配置(禁 用密码登录) STEP 04 性能参考 基于实际使用经验: 可复现验收标准

5、异常记录

Q1:SSH 克隆失败,提示「Permission denied」

排查步骤:

  1. 确认 SSH 端口:
1
2
3
# 检查容器映射端口
docker ps | grep gitea
# 应该看到 0.0.0.0:222->22/tcp
  1. clone 时指定端口:
1
git clone ssh://[email protected]:222/username/repo.git
  1. 或者配置 ~/.ssh/config:
1
2
3
4
5
6
7
# 如果文件不存在,先创建:
mkdir -p ~/.ssh && nano ~/.ssh/config
chmod 600 ~/.ssh/config

# 粘贴以下内容
Host git.yourdomain.com
Port 222

Q2:邮件发不出去

常见原因:

  1. SMTP 密码错误:QQ 企业邮箱要用「客户端专用密码」,不是登录密码(需在邮箱设置中生成)
  2. 端口/协议错误:SSL 用 465,STARTTLS 用 587
  3. 证书验证失败:测试时可以临时设置 SKIP_VERIFY = true
  4. 防火墙阻止:确保 VPS 能访问 SMTP 端口(465/587)

查看日志:

1
docker compose logs gitea | grep -i email

Q3:Gitea 升级后打不开

回滚版本:

1
2
3
4
5
6
7
cd ~/gitea

# 编辑 docker-compose.yml,改回旧版本
# image: gitea/gitea:1.26

# 重新部署
docker compose up -d

如果数据库损坏:

  1. 停止容器
  2. 恢复之前的备份
  3. 检查 PostgreSQL 日志:docker compose logs db

Q4:迁移到新服务器

步骤:

  1. 旧服务器备份:
1
2
3
cd ~/gitea
docker compose down
tar -czf gitea-migration.tar.gz data/
  1. 拷贝到新服务器:
1
scp gitea-migration.tar.gz user@newserver:/tmp/
  1. 新服务器恢复:
1
2
3
4
5
6
7
cd ~
mkdir -p gitea && cd gitea
tar -xzf /tmp/gitea-migration.tar.gz

# 拷贝 docker-compose.yml(或重新创建)
# 启动
docker compose up -d
  1. 修改域名解析(DNS 指向新 IP)

Q5:性能优化

如果 Gitea 变慢:

何时需要优化:如果你同时有 20+人活跃使用、仓库数 100+,再考虑这些优化。大部分独立开发者和小团队用不到。

  1. 检查资源占用:
1
docker stats gitea
  1. 启用缓存(在 app.ini):
1
2
3
[cache]
ENABLED = true
ADAPTER = memory
  1. 数据库优化(PostgreSQL):
1
2
[database]
POOL_RECYCLE = 3600
底层机制与架构拆解:异常记录 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 SMTP密码错误 QQ企业邮箱要用「客户端 专用密码」,不是登录密… S2 端口/协议错误 SSL用465,STARTTLS用 587 S3 证书验证失败 测试时可以临时设置 SKIPVERIFY=true S4 防火墙阻止 确保VPS能访问SMTP端口 (465/587) 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

6、一键部署脚本(完整版)

**想快速部署?**用这个脚本一键搞定。**想学习每个步骤?**跟着上面 3.1-3.8 手动操作一遍。

如果你想快速部署,用这个脚本:

⚠️ 新手建议:先手动跑一遍第 3.2-3.5 节,熟悉流程后再用脚本。

执行前请先看懂这 6 步在做什么:

  1. 安装 Docker
  2. 安装必要工具(nginx, certbot)
  3. 创建工作目录
  4. 创建 docker-compose.yml
  5. 启动容器
  6. 配置 Nginx + SSL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/bin/bash
# Gitea 一键部署脚本
# 使用方法:sudo bash gitea-setup.sh

set -e

# === 配置区域(根据你的需求修改)===
DOMAIN="git.yourdomain.com" # 你的域名
EMAIL="[email protected]" # SSL 证书邮箱
GITEA_USER="gitea" # Gitea 运行用户
DB_PASSWORD="change_me_strong_password" # 数据库密码
TIMEZONE="Asia/Shanghai" # 时区
# =====================================

echo "=== Gitea 一键部署脚本 ==="
echo ""

# 1. 安装 Docker
if ! command -v docker &> /dev/null; then
echo "[1/6] 安装 Docker..."
curl -fsSL https://get.docker.com | sh
usermod -aG docker $USER
else
echo "[1/6] Docker 已安装,跳过"
fi

# 2. 安装必要工具
echo "[2/6] 安装必要工具..."
apt update && apt install -y git nginx certbot python3-certbot-nginx

# 3. 创建工作目录
echo "[3/6] 创建工作目录..."
mkdir -p ~/gitea/{data/{gitea,postgres},backups}
cd ~/gitea

# 4. 创建 docker-compose.yml
echo "[4/6] 创建 Docker Compose 配置..."
cat > docker-compose.yml <<EOF
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- TZ=$TIMEZONE
- DB_TYPE=postgres
- DB_HOST=db:5432
- DB_NAME=gitea
- DB_USER=gitea
- DB_PASSWD=$DB_PASSWORD
ports:
- "127.0.0.1:3000:3000"
- "222:22"
volumes:
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
depends_on:
- db
restart: always

db:
image: postgres:15-alpine
container_name: gitea-db
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=$DB_PASSWORD
- POSTGRES_DB=gitea
- TZ=$TIMEZONE
volumes:
- ./data/postgres:/var/lib/postgresql/data
restart: always
EOF

# 5. 启动容器
echo "[5/6] 启动 Gitea 容器..."
docker compose up -d

# 等待服务就绪
echo "等待服务启动..."
sleep 15

# 6. 配置 Nginx
echo "[6/6] 配置 Nginx..."
cat > /etc/nginx/sites-available/$DOMAIN <<EOF
server {
listen 80;
server_name $DOMAIN;

location /.well-known/acme-challenge/ {
root /var/www/html;
}

location / {
proxy_pass http://127.0.0.1:3000;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
EOF

ln -sf /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

# 申请 SSL
echo "申请 SSL 证书..."
certbot --nginx -d $DOMAIN --non-interactive --agree-tos --email $EMAIL --redirect

echo ""
echo "=========================================="
echo " ✅ Gitea 部署完成!"
echo "=========================================="
echo ""
echo " 访问地址: https://$DOMAIN"
echo " 管理员: 首次访问时创建"
echo " SSH 克隆端口: 222"
echo ""
echo " ⚠️ 重要:请立即访问并完成初始化配置!"
echo ""

保存为 gitea-setup.sh,执行:

1
2
chmod +x gitea-setup.sh
sudo bash gitea-setup.sh
问题整改前后解剖:一键部署脚本(完整版) ⚠️ 整改前:常见踩坑与失分现场 • 盲区 1:忽视「首屏与入口响应」边界约束 • 盲区 2:缺乏「边界容错与防线」实测核验 • 盲区 3:遗漏「可验证证据链」兜底监控 后果:线上隐性故障频发 / 评估等级下调 ✅ 整改后:高确定性工程实践 • 动作 1:首屏与入口响应:剥离冗余阻塞,核心功能与结… • 动作 2:边界容错与防线:显式设置超时熔断与异常输入… • 动作 3:可验证证据链:配备实机压测指标、日志与可复… 收益:指标可观测、配置可复现、风险可阻断

7、最后说两句

自建 Git 服务器不是必须的,但对于想要数据自主可控的独立开发者来说,这是走向技术独立的一小步。

数据自主可控,从自建 Git 开始。

Gitea 的优势在于轻量,小 VPS 也能跑得欢,功能也够用。如果你需要 GitLab CI 那些高级功能,再去折腾 GitLab 也不迟。

下一步?用 Gitea + Drone CI 搭建完整的 DevOps 流水线,让你的出海项目真正跑起来。


什么情况下不要自建 Git? 如果你的项目少于 5 个仓库、团队少于 3 人、或者你没有运维经验,用 GitHub 更省心。自建 Git 是给有明确需求(隐私、合规、延迟)的人准备的。

底层机制与架构拆解:最后说两句 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 输入识别与场景分流 明确核心业务诉求与上下 文边界条件 S2 底层协议与规则校验 对照核心规范与真实负载 指标逐项核验 S3 瓶颈隔离与风险阻断 剔除干扰链路、单点隐患 与高危配置 S4 确定性架构标准输出 沉淀为可一键复现的工程 配置基线 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

8、FAQ(自建 Gitea 高频疑问)

Q1:自建 Gitea 一个月大概花多少钱?
1 核 1G 的小 VPS 就够个人和 3-5 人团队跑,Vultr、DigitalOcean 这类 5-6 美元/月的入门套餐足够;仓库上 GB 或 20+ 人再升到 2 核 4G。域名一年 10 美元左右,SSL 证书 Let’s Encrypt 免费。

Q2:SQLite 和 PostgreSQL 怎么选?
个人、小团队、仓库不多,直接用 SQLite,零配置、文件即数据库,省一个容器。等并发上来(多人同时 push/PR、仓库几百个)再换 PostgreSQL,数据可以导出迁移,不算大工程。

Q3:GitHub 上的老仓库怎么搬过来?
新建仓库时选「Migrate / 迁移」,填 GitHub 仓库地址和 access token,Gitea 会把代码、Issues、PR、Wiki 一起拉过来。只想搬代码不搬 Issue,本地 git remote set-url origin [email protected]:user/repo.git && git push -u origin --all 改个远端 push 上去就行。

Q4:Gitea 免费吗?商业上有没有风险?
Gitea 本体 MIT 开源、完全免费。但 2022 年它转给盈利公司 Gitea Ltd. 后,社区分叉出 Forgejo(Codeberg e.V. 非营利托管,自带 Forgejo Actions CI)。两者高度兼容。介意项目被一家公司掌控的,选 Forgejo;无所谓就用 Gitea,功能没差别。

Q5:日常维护要花多少时间?
Docker 跑起来后基本免维护,每月 docker compose pull && docker compose up -d 升级一次、确认 cron 备份在跑就行。真正费时间的是硬盘坏了或升级翻车那几次,所以备份加定期演练恢复,比日常盯服务更重要。

问题整改前后解剖:FAQ(自建Gitea高频疑问) ⚠️ 整改前:常见踩坑与失分现场 • 盲区 1:忽视「首屏与入口响应」边界约束 • 盲区 2:缺乏「边界容错与防线」实测核验 • 盲区 3:遗漏「可验证证据链」兜底监控 后果:线上隐性故障频发 / 评估等级下调 ✅ 整改后:高确定性工程实践 • 动作 1:首屏与入口响应:剥离冗余阻塞,核心功能与结… • 动作 2:边界容错与防线:显式设置超时熔断与异常输入… • 动作 3:可验证证据链:配备实机压测指标、日志与可复… 收益:指标可观测、配置可复现、风险可阻断

数据与引用

  • Gitea 与 GitLab 的定位差异:Gitea 单一二进制,资源占用约 200-400MB 内存;GitLab Omnibus 推荐 4GB 起步,CI 跑起来要 8GB+。独立开发者和小团队(< 20 人)跑 Gitea 更省心。
    来源:Gitea 官方文档 - Requirements;GitLab 官方文档 - Requirements
    含义:选型时按团队规模+机器配置取舍,5 人以下小团队没必要上 GitLab。

  • Gitea 1.27 vs Forgejo v9 的功能差异:Gitea 1.27 仍在持续维护,企业版(EE)拆分为独立产品;Forgejo v9 同步 Gitea v1.22 的代码基础后独立演进。Forgejo 自带 Forgejo Actions(兼容 GitHub Actions 语法),Gitea 需外接 Drone 或 Act Runner。
    来源:Gitea 1.27 Release Notes;Forgejo 项目声明
    含义:自带 CI 选 Forgejo,CI 用 Drone/Jenkins 选 Gitea 也无压力。

  • SQLite vs PostgreSQL 在 Gitea 上的实际表现:SQLite 适合 < 50 仓库、< 10 并发 push 的场景;超过这个量级单文件锁会成为瓶颈。PostgreSQL 14+ 支持 JSONB 索引,Gitea 的 Issue/PR 全文搜索在 PostgreSQL 上明显更快。
    来源:Gitea 文档 - Database Support;Gitea 社区 issue #tracking 的多次 benchmark 讨论(2024-2025)
    含义:个人/小团队直接 SQLite 起步;并发上来再迁 PostgreSQL,迁移工具官方提供。

  • Gitea → Gitea Ltd. 的治理变更(2022-11):原 Gitea 团队联合成立 Gitea Ltd. 负责商业开发,社区担忧后由部分核心维护者 fork 出 Forgejo,由德国非营利组织 Codeberg e.V. 托管。
    来源:Forgejo 项目起源公告;Codeberg e.V. 关于 Forgejo 的声明
    含义:选 Gitea 还是 Forgejo 是「公司主导 vs 社区非营利」路线选择,技术差异已近乎消失。

  • Gitea 1.27+ 内置 Package Registry:从 1.19 起支持 Cargo / Composer / npm / NuGet / PyPI / RubyGems 多种包仓库,Docker OCI 镜像仓库从 1.20 起内置;不需要单独跑 Nexus 或 Artifactory。
    来源:Gitea 1.19 Release Notes;Gitea Package Registry 文档
    含义:个人/小团队自建包仓库省一个容器;想要更复杂的功能(权限分级、扫描)再上 Nexus/Artifactory。

  • Forgejo Actions 与 GitHub Actions 兼容性:Forgejo Actions 完全复用 GitHub Actions 的 workflow 语法(.github/workflows → .forgejo/workflows),只是运行器从 GitHub-hosted runner 换成自托管 runner。
    来源:Forgejo Actions 文档;GitHub Actions 文档
    含义:迁移 GitHub Actions workflow 到 Forgejo 几乎零改动,自托管 runner 用 act-runner 即可。

  • 自建 Gitea 的最小 VPS 配置:1 核 1GB 内存可起 SQLite 版 Gitea,仓库 < 50 个、用户 < 20 人流畅;切到 PostgreSQL 后内存建议 2GB 起。Gitea 1.27 镜像约 150MB,单进程常驻 200-400MB。
    来源:Gitea 官方硬件建议 + 社区实测(2024-2025 多个 self-hosted 案例)
    含义:5-6 美元/月入门 VPS(Vultr/DigitalOcean/Linode)跑 Gitea 完全够用,扩展成本低。

  • SSH over HTTPS 自定义端口支持:Gitea 同时支持 SSH(默认 22)和 HTTPS(默认 3000)两种 clone 协议,SSH 走 git 用户权限隔离,HTTPS 走 Access Token。
    来源:Gitea SSH 文档;Gitea Access Token 文档
    含义:CI 用 SSH deploy key、自动化脚本用 HTTPS token,两者并存按场景选。


💡 透明声明:本文包含 8 处推广链接(5 个独立服务,如 Vultr / DigitalOcean / Linode / Cloudflare / Bandwagonhost 等)。每次点击我会收到一笔佣金,不影响你的购买价格,也不影响我的内容判断,工具好不好用我自己用了才知道。完整推广政策见 ittinker.com/about。

底层机制与架构拆解:数据与引用 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 Gitea与GitLab的定… Gitea单一二进制,资源 占用约200-400MB内存… S2 Gitea 1.27 vs… Gitea 1.27仍在持续维 护,企业版(EE)拆分为… S3 SQLite vs… SQLite适合<50仓库、< 10并发push的场景;超过… S4 Gitea→Gitea Ltd.… 原Gitea团队联合成立 Gitea Ltd.负责商业开… 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

💼 推荐工具

  • Gitea 主机(按小时计费,全球节点):Vultr Cloud VPS,1GB 内存 5 美元/月跑 SQLite 版 Gitea 足够。
    https://ittinker.com/go/vultr
  • Gitea 主机(文档完善,新用户赠费):DigitalOcean,Snapshots 备份免费,升级前后打个快照保平安。
    https://ittinker.com/go/do
  • Gitea 主机(按小时计费,稳定):Linode,现已并入 Akamai 网络,全球节点稳定。
    https://ittinker.com/go/linode
  • Forgejo(社区非营利分叉):如果更在意项目治理而非商业支持,Forgejo 是 Gitea 的硬分叉。
    https://forgejo.org
  • Drone CI(Gitea 搭档):轻量 CI/CD 平台,原生支持 Gitea Webhook,跑 .drone.yml。
    https://drone.io
  • 反向代理(Nginx):HTTPS + 域名访问的标准组合,配 Let’s Encrypt 自动续签。
    https://nginx.org
  • Caddy:自动 HTTPS 反代,比 Nginx 配置简单,单文件就能跑。
    https://caddyserver.com
  • Cloudflare:免费 CDN + 反代,隐藏 Gitea 服务器真实 IP。
    https://ittinker.com/go/cloudflare

本文最后更新:2026年8月

独立开发者工具箱系列,欢迎关注!

问题整改前后解剖:💼推荐工具 ⚠️ 整改前:常见踩坑与失分现场 • 盲区 1:忽视「Gitea主机(按小时计费…」边界约束 • 盲区 2:缺乏「Gitea主机(文档完善,新…」实测核验 • 盲区 3:遗漏「Gitea主机(按小时计费…」兜底监控 后果:线上隐性故障频发 / 评估等级下调 ✅ 整改后:高确定性工程实践 • 动作 1:Gitea主机(按小时计费,全球节点):Vultr… • 动作 2:Gitea主机(文档完善,新用户赠费)… • 动作 3:Gitea主机(按小时计费,稳定):Linode… 收益:指标可观测、配置可复现、风险可阻断