代码推上去还要手动登服务器拉、编译、重启,次数一多就烦,也容易漏步骤。CI(持续集成)就是让「推送代码」自动触发构建测试。Drone 是一个轻量开源 CI/CD,配置就是一个 .drone.yml,和 雨云搭建 Gitea 这套自建 Git 服务是绝配——Gitea 管代码,Drone 管流水线。本文用一台雨云 KVM 云服务器,把 Drone server + runner 拉起来,接上 Gitea 做「提交即构建」。
一、先准备一台雨云 KVM 云服务器
Drone server 很轻,1 核 1G 能跑,但需要 7×24 在线、有公网 IP、绑域名走 HTTPS(OAuth 回调要 https)。想低成本起一台可以看国产高性价比云服务器,比如雨云:KVM 虚拟化、Debian/Ubuntu 镜像任选,新用户用优惠码 admin01 享五折,入门版折后约 9 元/月,支持 7 天无理由退款。挑机器可参考 VPS 怎么选不踩坑。
我选 Debian 12。前提:你已有一台跑着 Gitea 的服务器(参考 雨云搭建 Gitea),且 Gitea 能用 https 域名访问。基础安全按 VPS 到手第一件事做什么 走一遍,本文明文默认已开 ufw。Drone 后台走 8080,放行即可。
二、在 Gitea 建 OAuth 应用
Drone 通过 Gitea 的 OAuth 登录并读取仓库,所以先在 Gitea 上建应用:
- Gitea「设置 → 应用」→「创建新的 OAuth2 应用程序」。
- 重定向 URI 填
https://drone.example.com/login。 - 建好记下 客户端 ID 和 客户端密钥。
三、用 Docker 拉起 Drone
装 Docker:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
建目录并写 docker-compose.yml:
mkdir -p /opt/drone && cd /opt/drone
version: "3"
services:
drone-server:
image: drone/drone:2
container_name: drone-server
restart: unless-stopped
ports:
- "8080:80"
environment:
- DRONE_GITEA_SERVER=https://git.example.com
- DRONE_GITEA_CLIENT_ID=填Gitea客户端ID
- DRONE_GITEA_CLIENT_SECRET=填Gitea客户端密钥
- DRONE_RPC_SECRET=随机长字符串
- DRONE_SERVER_HOST=drone.example.com
- DRONE_SERVER_PROTO=https
- DRONE_USER_CREATE=username:你的Gitea用户名,admin:true
drone-runner:
image: drone/drone-runner-docker:1
container_name: drone-runner
restart: unless-stopped
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_HOST=drone.example.com
- DRONE_RPC_PROTO=https
- DRONE_RPC_SECRET=和上面一致的随机长字符串
- DRONE_RUNNER_CAPACITY=2
DRONE_RPC_SECRET 在 server 和 runner 两边必须完全一致,用 openssl rand -hex 16 生成。DRONE_USER_CREATE 把你的 Gitea 账号设为 Drone 管理员。启动:
docker compose up -d
四、配 HTTPS 反代
OAuth 回调与 Runner 通信都要 https。用 Nginx 反代 8080:
server {
listen 80;
server_name drone.example.com;
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl;
server_name drone.example.com;
ssl_certificate /etc/letsencrypt/live/drone.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/drone.example.com/privkey.pem;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8080;
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 -d drone.example.com。放行端口:
ufw allow 80/tcp
ufw allow 443/tcp
ufw reload
打开 https://drone.example.com,用 Gitea 账号授权登录,左侧能看到 Gitea 里的仓库,点「ACTIVATE」启用。
五、写一条流水线
在仓库根目录加 .drone.yml:
kind: pipeline
type: docker
name: default
steps:
- name: build
image: golang:1.22
commands:
- go build -o app .
- name: test
image: golang:1.22
commands:
- go test ./...
推送到 Gitea,Drone 会自动拉起 runner 跑构建。绿了就是过,红了点开看日志。
六、踩过的坑与经验
- RPC_SECRET 两边不一致:server 和 runner 的
DRONE_RPC_SECRET必须相同,否则 runner 连不上 server,流水线永远排队。 - Gitea 回调域名要 https:重定向 URI 填
https://drone.example.com/login,且 Gitea 本身也得 https 可访问,否则授权来回跳。 - Runner 类型选 docker:
drone-runner-docker用容器跑每一步,干净隔离;记得挂/var/run/docker.sock,否则 runner 起不了构建容器。 - 仓库没出现:登录后去 Gitea 看仓库是否「私有」但没给 Drone 授权;点仓库的 ACTIVATE 并在 Drone 里 SYNC 同步一次。
- 构建容器权限:步骤里写文件到挂载卷时,注意容器内用户 UID 可能和宿主不一致,必要时在 step 加
user: root或用chown修正。 - 密钥别明文:Token、密码走 Drone 的 Secret(仓库设置里加),
.drone.yml里用from_secret,别写进仓库。
小结
CI 把「重复的手工部署」变成「推一下就完事」。Drone 配置极简、和 Gitea 自托管组合零月费(除服务器),很适合个人项目。常驻轻量流水线很适合雨云这类低价稳定 KVM——优惠码 admin01 五折、7 天无理由退款,跑构建服务很合适。
合规提醒:使用雨云及本文所述方案时,请遵守《网络安全法》《个人信息保护法》《数据安全法》等相关法律法规,仅用于合法合规的软件开发与持续集成,妥善保管 Gitea/Drone 账号与密钥、履行代码与个人信息保护义务,不得利用本服务构建或分发违法违规内容。






