自托管代码仓库与 CI/CD 流水线搭建:Gitea + Drone 整合实践
  1. 需求场景
    平时写一些小项目和脚本,放在 GitHub 上虽然方便,但私有仓库在免费版有一些限制,而且 Actions 的构建时长对个人项目来说有时会超限。一直想在自己拥有的服务器上搭一套轻量级的 Git 托管服务,顺便接上 CI/CD,实现 push 代码后自动构建镜像或执行测试。

我使用了手头的一台阿贝云的云服务器已安装 Docker 和 Docker Compose已绑定域名 git.example.com 用于 Gitea 访问

  1. 安装 Gitea(轻量级 Git 服务)
    Gitea 是用 Go 编写的 Git 托管平台,资源占用极低,非常适合 1GB 内存的小型服务器。

首先创建数据存放目录:

bash
mkdir -p /opt/gitea/{data,config}
chown -R 1000:1000 /opt/gitea
编写 docker-compose.yml:

yaml
version: ‘3’

services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: always
ports:
- “3000:3000”
- “2222:22”
volumes:
- /opt/gitea/data:/data
- /opt/gitea/config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
启动服务:

bash
docker-compose up -d
访问 http://服务器IP:3000,进入 Gitea 安装页面。首次访问会提示配置,数据库选择 SQLite(够用),然后设置管理员账号和站点名称。安装完成后,就可以在页面上创建仓库了。

  1. 配置 Nginx 反向代理与 HTTPS
    为了更正式地使用,用域名访问并加上 SSL。安装 Nginx:

bash
apt install nginx certbot python3-certbot-nginx -y
配置 Nginx 站点 /etc/nginx/sites-available/gitea:

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

}
启用配置并申请 SSL 证书:

bash
ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
systemctl restart nginx
certbot --nginx -d git.example.com
完成后即可通过 https://git.example.com 安全访问 Gitea。

  1. 部署 Drone CI/CD
    Drone 是一个基于容器构建的 CI/CD 工具,与 Gitea 集成度很好。

4.1 创建 OAuth 应用
在 Gitea 中,进入用户设置 → 应用 → 创建 OAuth2 应用,填入以下信息:

应用名称:Drone

回调地址:https://git.example.com/login/authorize(替换为你的 Drone 域名)

记下生成的 Client ID 和 Client Secret。

4.2 编写 Drone 服务配置
创建 /opt/drone/docker-compose.yml:

yaml
version: ‘3’

services:
drone-server:
image: drone/drone:latest
container_name: drone-server
restart: always
ports:
- “8080:80”
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/drone/data:/data
environment:
- DRONE_GITEA_SERVER=https://git.example.com
- DRONE_GITEA_CLIENT_ID=你的ClientID
- DRONE_GITEA_CLIENT_SECRET=你的ClientSecret
- DRONE_RPC_SECRET=自定义随机字符串
- DRONE_SERVER_HOST=drone.example.com
- DRONE_SERVER_PROTO=https
- DRONE_DATABASE_DRIVER=sqlite3
- DRONE_DATABASE_DATASOURCE=/data/drone.sqlite

drone-runner:
image: drone/drone-runner-docker:latest
container_name: drone-runner
restart: always
ports:
- “8081:3000”
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=drone.example.com
- DRONE_RPC_SECRET=与上面相同的随机字符串
- DRONE_RUNNER_NAME=runner-1
- DRONE_LOGS_DEBUG=true
启动 Drone 服务:

bash
docker-compose up -d
同样配置 Nginx 反向代理将 drone.example.com 指向 8080 端口,并申请 SSL 证书。

  1. 配置流水线示例
    在 Gitea 仓库根目录创建 .drone.yml,Drone 会自动执行流水线。下面是一个简单的示例,用于检测代码语法并输出构建信息:

yaml
kind: pipeline
type: docker
name: default

steps:

  • name: 打印构建信息
    image: alpine
    commands:

    • echo “开始构建…”
    • echo “仓库名称: ${DRONE_REPO_NAME}”
    • echo “提交哈希: ${DRONE_COMMIT_SHA}”
    • echo “构建完成!”
  • name: 检查 Shell 语法(仅示例)
    image: alpine
    commands:

    • apk add bash
    • echo “语法检查通过(示例步骤)”
      推送到仓库后,Drone 会自动触发流水线,并在界面上显示执行日志。
  1. 资源占用与使用感受
    Gitea 和 Drone 服务同时运行,内存占用大约在 500MB 左右(含 Docker 后台进程),CPU 基本空闲。阿贝云这台免费云服务器的 1GB 内存完全可以支撑这套组合,磁盘 I/O 也满足日常 Git 操作。

对于开发者来说,有了一台自己的代码托管服务器,可以省去 GitHub 私有仓库的数量限制,同时也体验了企业级 CI/CD 流程的搭建过程。相比免费虚拟主机,云服务器的可扩展性确实高很多。

  1. 踩坑记录
    端口冲突:如果服务器已有其他服务占用 3000 或 8080,记得修改映射端口。

OAuth 回调地址:必须使用 HTTPS 协议,否则 Gitea 不会正常跳转,Drone 登录会失败。

Drone RPC_SECRET:server 和 runner 必须保持一致,否则 runner 无法连接到 server。

SELinux/AppArmor:Debian 默认未开启,无需额外处理。如果使用 CentOS,需要注意关闭 SELinux 或配置相关规则。

  1. 结语
    以上是一个完整的自托管代码仓库 + CI/CD 解决方案。所有组件均运行在阿贝云云服务器实例上,实测稳定可用。如果你也对自建开发工具链感兴趣,可以参考本教程动手实践。