Featured image of post Gitea + Drone 整合:打通 CI 全流程, ARM 架构真是个“坑王”

Gitea + Drone 整合:打通 CI 全流程, ARM 架构真是个“坑王”

从 runner 卡在 pending 到架构不兼容,我在树莓派上跑 Drone 的血泪史

“为什么 CI 跑不起来?”
“Webhook 发过来了,任务却一直 pending…”
“Runner 明明启动了,Drone 却像看不见它?”

这就是我在树莓派上配置 Drone 的第一感觉。作为 CI/CD 工具,Drone 本身很轻量,逻辑也很清晰。但架不住我用的是 ARM64 架构的树莓派,而 Drone 的世界默认是为 amd64 构建的。

这一篇文章,我就来记录我在 Drone + Gitea 打通 CI 流程时遇到的三个大坑。


🛠️ 前置准备:Gitea + Drone 启动成功

这一部分比较顺利,我使用 Docker 启动了:

 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
services:
  drone-server:
    image: drone/drone:2
    container_name: drone-server
    ports:
      - "3080:80"
    volumes:
      - ./data:/data
    restart: always
    environment:
      - DRONE_GITEA_SERVER=${GITEA_SERVER}
      - DRONE_GITEA_CLIENT_ID=${GITEA_CLIENT_ID}
      - DRONE_GITEA_CLIENT_SECRET=${GITEA_CLIENT_SECRET}
      - DRONE_RPC_SECRET=${RPC_SECRET}
      - DRONE_SERVER_HOST=${SERVER_HOST}
      - DRONE_SERVER_PROTO=${SERVER_PROTO}
      - DRONE_USER_CREATE=username:${ADMIN_USER},admin:true

  drone-runner:
    image: drone/drone-runner-docker:1
    container_name: drone-runner
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone-server
      - DRONE_RPC_SECRET=${RPC_SECRET}
      - DRONE_RUNNER_NAME=drone-runner
      - DRONE_RUNNER_CAPACITY=4
  • Gitea:私有 Git 服务,监听 3000 端口(docker-compose配置在上一篇)
  • Drone Server:监听 Gitea webhook,负责接任务
  • Drone Runner Docker:负责执行任务

我在 Gitea 中创建了 OAuth 应用、设置好回调地址,Drone UI 页面也成功显示了项目。

看起来万事俱备,只差 .drone.yml 一推。

结果就是——第一坑来了。


❌ 第一个坑:任务卡在 pending,runner 完全不接活

我配置好 .drone.yml 后推送了第一条 commit,Gitea 成功发出 webhook,Drone 收到了,任务出现在 UI 中。

但它就这样一直停留在:

1
pending...

查看了日志也没什么发现, 最后在 ChatGPT 的帮助下,发现了蛛丝马迹:

Drone 的默认平台是 linux/amd64,但我在树莓派上运行的是 linux/arm64 的 runner,两者架构不匹配,runner 根本不会接这个任务。

✅ 正确做法:在 .drone.yml 指定平台

正确的写法是:在整个 .drone.yml 文件的顶层指定平台,runner 才能正确匹配任务。

1
2
3
4
5
6
7
8
9
platform:
  os: linux
  arch: arm64

steps:
  - name: say hello
    image: alpine
    commands:
      - echo "Hello from Drone on ARM64"

一保存、一推送,CI pipeline 秒启动,runner 成功接活。

🎉 成功解决第一个卡死问题。


🐌 第二个坑:镜像拉取巨慢,甚至失败

虽然 runner 能正常执行了,但每次执行第一个 step,总是要卡十几分钟:

1
pulling image: alpine

网络不佳,导致拉镜像非常慢。CI 本应该是高效的,卡在镜像上简直无法接受。

于是我想了个“旁门左道”:

✅ 解决办法:离线拉镜像 → Mac 下载 → 拷贝到树莓派导入

  1. 在我的 Mac 上执行:

    1
    2
    3
    
    docker pull --platform linux/arm64 alpine:latest
    docker save alpine:latest > alpine-arm64.tar
    scp alpine-arm64.tar pi@raspberrypi:/home/pi/
    
  2. 在树莓派上导入:

    1
    
    docker load < alpine-arm64.tar
    

Drone runner 再执行构建时,发现本地已有镜像,就不会再去拉了,直接开始执行。

CI 时间从几分钟缩短到几秒。


🧬 第三个坑:Mac 拉下来的镜像架构不对!

但事情远没结束。

我第一次用 Mac 拉镜像 + 导入树莓派,结果执行时报错:

1
exec /bin/sh: exec format error

因为我的 Mac 是 intel 芯片, 默认拉的是 amd64 架构镜像,而树莓派是 arm64,架构不兼容,容器一启动就崩。

✅ 正确姿势:拉取指定平台的镜像

使用 docker pull --platform linux/arm64明确指定:

1
2
docker pull --platform linux/arm64 alpine:latest
docker save alpine:latest > alpine-arm64.tar

导入之后,在树莓派上执行镜像就一切正常了。


🧩 总结:架构这件事,Drone 真挑剔

默认平台是 amd64,而我部署的是 arm64,需要手动干预平台一致性。

问题表现解决方式
Drone runner 不接任务一直 pending.drone.yml 顶层设置 platform: linux/arm64
拉镜像慢 / 超时CI 卡很久Mac 上预拉镜像 + 导入到树莓派
导入镜像后运行失败exec format errorMac 拉镜像时指定 --platform linux/arm64

📌 下一篇预告

《我的博客不是部署在云上,而是藏在家里的树莓派里》

我会介绍如何用 Hugo + Drone 实现:

  • 自动生成博客内容
  • 自动构建镜像
  • 自动部署到本地服务(Nginx 或独立容器)

这是我真正用 Drone 做的第一个“实用业务”。


💬 最后

Drone 在树莓派上能不能跑?能,但要提前对好架构节奏; CI/CD 是不是就是写个 .yml 就能搞定?不是,得熟悉 runner、平台、镜像行为; 但当它成功跑起来,能自动发布、自动部署,你会觉得这一切都值了。

我们下篇见 👋

使用 Hugo 构建
主题 StackJimmy 设计