Gitea 部署教程:树莓派都能跑的自托管 Git 服务

想把代码托管在自己的服务器上?又不想折腾 GitLab 那种吃内存大户?Gitea 是一个值得考虑的选择。它用 Go 编写,二进制体积小,对架构的支持也非常广泛——按官方 README 的说法,能跑 Go 的平台它都能跑,包括 Linux、macOS、FreeBSD、OpenBSD、Windows,覆盖 x86、amd64、ARM(树莓派就在其中)、RISC-V 64 和 PowerPC。

这篇文章会用 Docker Compose 的方式,从零把一个带 PostgreSQL 的 Gitea 实例跑起来。部署形式独立但功能齐全,涵盖代码托管、Issue、PR、Wiki、Actions 等。

Gitea 用户仪表盘的总览界面,包含仓库、Issue、PR、团队动态等模块-1

为什么选 Gitea

  • 轻量:官方 README 提到实例可在小资源环境运行,社区常见的起步门槛是 256M 内存,这比 GitLab 友好得多。
  • 跨平台:ARM 设备(比如树莓派)和各种 Linux 发行版都能直接跑。
  • 一体化:除 Git 托管外,官方把代码审查、Issue 看板、Wiki、包注册表、CI/CD(兼容 GitHub Actions)都列为内置功能。
  • 可定制:动态配置可以在管理员面板直接改,静态选项则修改 app.ini 重启生效。

如果你不想自己部署,README 里还提到了官方的演示站 demo.gitea.com、有限的免费实例 gitea.com,以及商用化的 Gitea Cloud。

前置准备

  • 一台 Linux 服务器(Ubuntu、Debian、CentOS、openSULA 等都行)。
  • 安装好 Docker 和 Docker Compose。
  • 开放要用的端口(默认是 3000 网页和 22 SSH)。
  • 一个能解析到服务器的域名(用于 SSH 和 HTTPS 克隆)。

SSH 端口可以保持 22,也可以改成其他——重要的是容器外的端口要确定下来,避免和宿主已有的服务冲突。

docker-compose.yml 编写

在服务器上找个目录,新建 docker-compose.yml。下面是一份基础配置,包含 Gitea 和 PostgreSQL:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    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
    restart: unless-stopped
    volumes:
      - ./gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "127.0.0.1:2222:22"

  db:
    image: postgres:16
    container_name: gitea-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=gitea
      - POSTGRES_DB=gitea
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

几个值得说明的点:

  • 端口映射:Web 走 3000:3000;SSH 我故意把宿主端口设成 2222,并限制为 127.0.0.1,这样不直接暴露给外网,留给反向代理或宿主 SSH 服务共用。
  • 环境变量:Gitea 的环境变量遵循 GITEA__段__键 的格式,每两级下划线对应配置文件中 [段]键名,例如 GITEA__server__DOMAIN 对应 server.DOMAIN
  • 数据卷:Gitea 把仓库、配置、LFS、附件都放在 /data,挂载到宿主 ./gitea-data 即可持久化。
  • 时区:挂载本机的 /etc/timezone/etc/localtime,避免容器内时间和日志时区错乱。

> 具体的变量名和示例配置文件以 custom/conf/app.example.ini 和官方文档 docs.gitea.com/administration/config-cheat-sheet 为准,配置文件项很多,这里只挑了部署必须的。

执行 docker compose up -d 后终端显示两个容器 started 的状态输出-2

启动服务

docker-compose.yml 同目录执行:

docker compose up -d

观察日志:

docker compose logs -f gitea

当看到 Gitea 监听 0.0.0.0:30000.0.0.0:22(容器内)时,基本就绪。

首次安装向导

浏览器访问 http://服务器IP:3000,Gitea 会引导走一次性的安装向导。如果你在向导里手动配置过数据库,可能会提示冲突——这里有个小坑:Compose 文件里已经通过环境变量预填了数据库配置,所以推荐直接登录,不要再走到向导的数据库配置那一步,除非你想覆盖。

完成管理员账号的创建后,登录就能看到用户 Dashboard。

Gitea 首次安装向导中创建管理员账号的页面-3

数据持久化与备份

./gitea-data 目录下会包含:

  • gitea/conf/app.ini:配置文件
  • gitea/db.sqlite(如果用 SQLite)或连接的 PG 数据库
  • gitea/repositories:仓库裸仓库
  • gitea/lfs:Git LFS 对象
  • gitea/avatarsgitea/attachments:头像与附件

定期备份这两份数据即可。需要升级时,只需 docker compose pull && docker compose up -d,新容器会复用挂载的数据卷。

SSH 克隆的端口规划

容器内 SSH 仍然是 22,但宿主的 2222 也只是为了本机访问。生产环境通常有两种方案:

  1. 宿主 22 留给 SSH 登录(默认端口安全),把 Git SSH 改用一个不常用的高端口对外暴露。
  2. 通过 Nginx Stream 模块做四层反向代理:Web 走 443,SSH 转发到容器 22。

无论哪种,都要保证 环境变量 SSH_PORT 与实际对外暴露的端口一致,否则克隆时会报 “connection refused” 或 “port 22: connection timed out”。

反向代理与 HTTPS

下面是一段 Nginx 的最小可用配置(HTTP 先跑通,再加 HTTPS):

server {
    listen 80;
    server_name git.example.com;

    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;
    }
}

然后用 certbot --nginx 申请 Let’s Encrypt 证书即可。

如果还要在外网暴露 SSH 克隆,Nginx 需要 stream 模块:

stream {
    server {
        listen 2222;
        proxy_pass 127.0.0.1:2222;
    }
}

记得把对应的端口在防火墙和云厂商安全组里放行。

通过 Nginx 反向代理,浏览器以 HTTPS 访问 Gitea 仓库主页的效果-4

邮件(SMTP)配置

注册验证、Issue 通知、PR 提醒都依赖 SMTP。可以通过环境变量或 app.ini 配置。常见项包括:

  • [mailer] 段下的 PROTOCOLHOSTPORTUSERPASSWDFROM
  • 注意区分 25/465/587 端口:465 用 SMTPS,587 通常配 STARTTLS。

启动后到管理员面板 → 配置 → 邮件设置里”发一封测试邮件”验证连通性。

常见坑与排查

  • ROOT_URL 设错:克隆地址、通知邮件里的链接全部 404 或指向错误域名。该值要和浏览器实际访问的 URL 完全一致。
  • SSH 端口冲突:宿主已经装了 openssh-server 占用了 22,Compose 里再写 22:22 会启动失败。改成 2222:222222:2222 即可。
  • 时区不对:日志时间和提交时间对不上,挂载 /etc/timezone/etc/localtime 是最省事的方案。
  • 权限问题./gitea-data 的宿主属主和 USER_UID/USER_GID 不匹配,会出现写不了仓库的情况。调整 UID 或 chown 目录即可。
  • 首次启动数据库连不上:等几秒让 PostgreSQL 完成初始化,Compose 默认会一起拉起,理论上不需要重试。

收尾

到这里,一个带 PostgreSQL、反向代理、邮件配置和持久化的 Gitea 实例就基本可用。按官方 README 和文档站点 docs.gitea.com 的描述,下一步可以继续配置 OAuth 登录、备份策略、Actions Runner(act_runner)等。如果有安全问题需要上报,按 README 的说明写信到 [email protected] 即可。

日常运维就是关注 Release 页面的 SECURITY 关键字、留意升级公告、按需调整静态配置并重启容器。树莓派级别的机器也能撑起一个小型团队或个人全部的代码托管需求,这就是 Gitea 让人喜欢的地方。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。