使用 Gitea 与 Docker Compose 轻松自建你的私人 Git 服务器

简介

想要一个完全由你掌控的私人代码仓库吗?Gitea 是一个轻量级、高性能的自托管 Git 服务,功能强大且资源占用极低,甚至可以在树莓派上流畅运行。

本教程将指导你如何使用 Docker Compose 快速部署一个安全、私有的 Gitea 实例,让你在几分钟内拥有媲美 GitHub 的代码管理体验。

一、环境准备

在开始之前,需要拥有一个自己的 VPS 或是支持 Docker 容器的 NAS 系统。

1. 安装 Docker 和 Docker Compose

这是我们容器化部署的基础。如果你的服务器尚未安装,可以参考以下教程。

2. (可选)调整服务器 SSH 端口S

Gitea 需要使用 22 端口来处理 Git 的 SSH 操作 (如 git clone git@...)。为了避免与服务器自身的 SSH 服务端口冲突,建议将服务器的 SSH 端口修改为一个非标准端口(例如 2222)。

  • 编辑 SSH 配置文件:

    1
    vim /etc/ssh/sshd_config
  • 找到 #Port 22 这一行,取消 # 的注释,将 22 修改为新的端口数字。

  • 重启 SSH 服务使其生效:

    1
    systemctl restart sshd

    重要提示: 在断开当前连接之前,请务必打开一个新的终端窗口,尝试使用新端口号登录,确保可以成功登录。

3. 创建项目目录

为 Gitea 创建一个专用的目录,用于存放配置文件和数据。

1
mkdir -p /opt/gitea && cd /opt/gitea

二、使用 Docker Compose 部署 Gitea

创建 docker-compose.yml 文件

在项目目录 (/opt/gitea) 中,创建一个名为 docker-compose.yml 的文件。

1
vim docker-compose.yml

将以下内容粘贴到文件中:

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
# docker-compose.yml
networks:
gitea:
external: false

services:
gitea:
image: gitea/gitea:1.24.2 # 建议锁定版本以确保稳定性
container_name: gitea
restart: always
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea # 请在生产环境中替换为更强的密码
networks:
- gitea
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000" # Web 界面端口
- "22:22" # SSH Git 操作端口 (主机端口:容器端口)
depends_on:
- db

db:
image: postgres:15 # 建议锁定版本
container_name: gitea-db
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea # 请在生产环境中替换为更强的密码
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data

配置解析:

  • image: 我们为 Gitea 和 Postgres 数据库都指定了具体的版本,这有助于避免未来自动更新可能带来的兼容性问题。
  • environment: 用于配置 Gitea 和数据库之间的连接信息。请务C必将 GITEA__database__PASSWDPOSTGRES_PASSWORD 修改为强密码。
  • volumes: 将 Gitea 的数据(仓库、配置等)和数据库文件持久化存储在主机当前目录下的 datapostgres 文件夹中,确保容器重建后数据不丢失。
  • ports:
    • 3000:3000: 将 Gitea 的 Web 界面映射到主机的 3000 端口。
    • 22:22: 将 Git 的 SSH 操作端口映射到主机的 22 端口。

启动 Gitea 服务

docker-compose.yml 文件所在目录中,执行以下命令来拉取镜像并启动服务:

1
docker compose up -d

三、初始化 Gitea 设置

  1. 访问 Web 界面: 打开浏览器,访问 http://<你的服务器IP>:3000
  2. 完成安装: 你会看到 Gitea 的安装页面。
    • 数据库设置: Docker Compose 已经通过环境变量自动配置好了,你无需修改。
    • 通用设置: 这是你需要关注的部分。
      • 服务器域名: 填写你的域名,例如 git.yourdomain.com
      • Gitea 基本 URL: 填写完整的访问地址,例如 http://git.yourdomain.com/
  3. 点击“立即安装”,Gitea 会完成最后的设置并跳转到登录页面。请立即注册你的管理员账户。

四、安全加固

对于一个私有 Git 服务器,安全至关重要。

关闭用户注册

为了防止未经授权的用户注册,我们需要修改 Gitea 的配置文件。

1 编辑 app.ini 文件:

1
vim ./data/gitea/conf/app.ini

2[service] 部分,找到并修改或添加以下配置:

1
2
3
[service]
DISABLE_REGISTRATION = true ; 禁用注册功能
SHOW_REGISTRATION_BUTTON = false ; 从主页隐藏注册按钮

3 重启 Gitea 使配置生效:

1
docker compose restart gitea

2. (强烈推荐)使用反向代理

直接暴露 Web 端口到公网是不安全的。推荐使用 Nginx 或其他反向代理工具来提供 Web 服务,并且使用 HTTPS 访问。

1 修改端口映射: 将 Gitea 的 Web 端口限制为仅限本机访问。
修改 docker-compose.yml 文件中的 ports 部分:

1
2
3
ports:
- "127.0.0.1:3000:3000" # 仅允许本地访问
- "22:22"

2 重启服务:

1
2
docker compose down
docker compose up -d

3 配置反向代理: 在你的反向代理工具中,设置一个代理规则,将 git.yourdomain.com 的流量转发到 http://127.0.0.1:3000

Nginx 示例(仅反代部分)

以下示例将域名 git.example.com 的 HTTP 流量反代到本机的 127.0.0.1:3000。请先确保在 compose 中使用了 127.0.0.1:3000:3000 的端口映射,并在 Gitea 配置中将 ROOT_URL 设置为 http://git.example.com/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location / {
proxy_pass http://127.0.0.1:3000;

# 透传必要头部,确保生成正确克隆地址与日志 IP
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 支持(如通知、终端等)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置,避免大仓库推送中断
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 3600s;
}

测试并重载 Nginx 配置

1
2
nginx -t
nginx -s reload

结论

恭喜!你现在拥有了一个功能全面、安全可靠的私有 Git 服务器。相比于 GitLab 等重型方案,Gitea 在提供核心功能的同时保持了极低的资源消耗,是个人开发者与小团队的理想之选。通过 Docker Compose 进行部署,更让整个过程变得简单、高效且易于维护。