☰
轻量级CI部署:Drone CI + Docker Compose 实现外网访问
2026/10/22 20:29:23 网站建设 项目流程

1. 项目概述:为什么选 Drone CI 而不是 Jenkins?本地轻量部署的真实价值在哪?

如果你最近在查“jenkins持续集成测试”“docker安装部署”“ubuntu安装docker compose”,大概率正被 Jenkins 的 Java 进程吃掉 1.2GB 内存、插件更新失败、Groovy 脚本报错、Jenkinsfile 语法调试两小时却卡在NoClassDefFoundError上——我试过三次重装 Jenkins,最后一次是在一台 2核4G 的阿里云轻量服务器上,刚跑完一个 Maven 构建,系统负载就飙到 8.3,top里java进程稳居 CPU 占用榜首。而 Drone CI 不同:它原生基于 Go 编写,单二进制可执行文件 + 官方镜像启动后常驻内存仅 35–60MB,CPU 占用常年低于 0.3%,同一台机器上还能并行跑 Redis、PostgreSQL 和前端预览服务。这不是理论值,是我用stress-ng --cpu 4 --timeout 60s压测时实测的监控截图数据。

标题里“本地部署轻量级持续集成工具 Drone CI 并实现外部访问”,核心关键词是Drone CI、Docker、Docker Compose、外网访问——注意,这里说的“本地”不是指你笔记本的 localhost,而是指你可控的私有环境:可能是公司内网的一台 Ubuntu 物理机、阿里云/腾讯云的轻量应用服务器(非 ECS 标准版)、甚至树莓派 4B(实测 4GB 版本可稳定运行)。它解决的是三类人的真实痛点:

  • 小团队开发者:没专职 DevOps,但需要每天合并 PR 后自动构建 Docker 镜像、推送到私有仓库、再滚动更新测试环境;
  • 个人开源维护者:想给 GitHub 仓库加 CI 状态徽章,又不想把敏感凭证(如 Docker Hub Token)暴露在公开.github/workflows/里;
  • 企业内网项目组:代码不能出内网,但 Jenkins 又太重,运维不愿开新虚拟机,需要一个能塞进现有 Docker 主机、配置文件不到 100 行的方案。

Drone CI 的本质不是“另一个 Jenkins”,而是把 CI 流水线逻辑彻底下沉到 Git 仓库本身——它不解析 Jenkinsfile,而是直接读取你项目根目录下的.drone.yml(YAML 格式),这个文件和你的源码一起提交、一起评审、一起回滚。你改一行构建命令,下次 push 就生效,不用登录后台点“立即构建”。这种设计让它的学习曲线极陡峭地变平:我带过的两个实习生,第一天下午配好 Drone,第二天就能独立给 Vue 项目加单元测试 + E2E 自动化部署到 Nginx 容器。

至于“外部访问”,很多人误以为只是加个nginx -p 80:3000就完事。实际踩坑发现:90% 的失败案例源于 DNS 解析链断裂(比如你绑了ci.yourdomain.com,但本地/etc/hosts没配,浏览器直连 IP 又被 Drone 的 OAuth 重定向拦截)、HTTPS 证书未透传(Drone UI 强制跳转https://,但反向代理只转发 HTTP)、或 GitHub OAuth App 的Authorization callback URL填错协议。这些细节我会在后续章节逐条拆解,包括如何用openssl s_client -connect ci.yourdomain.com:443 -servername ci.yourdomain.com快速验证证书链是否完整。

现在你可以明确判断:这个项目适合谁——如果你的服务器已装好 Docker(Ubuntu 下sudo apt install docker.io docker-compose两行搞定),且你愿意花 40 分钟认真读完本文(而不是复制粘贴就跑),那么今天就能拥有一套比 Jenkins 更快、更省资源、配置更透明的 CI 系统。它不追求功能大而全,但每一步都经得起生产环境拷问。

2. 整体架构设计与选型逻辑:为什么必须用 Docker Compose?Nginx 反向代理为何不可替代?

2.1 Drone CI 的三种部署模式对比:为什么放弃单机二进制和 Kubernetes

Drone 官方提供三种部署方式:单机二进制、Docker 容器、Kubernetes Helm。但标题明确要求“轻量级”,这就直接排除了后两者中的陷阱选项:

  • Kubernetes Helm 部署:虽然官方文档写得漂亮,但 Helm chart 默认启用drone-server的replicaCount: 2,意味着至少要调度两个 Pod,每个 Pod 都需挂载 PVC 存储卷(用于保存构建日志和元数据)。在 2核4G 的轻量服务器上,光是kubectl get nodes就可能因 etcd 内存不足卡住。我实测过,在 4GB 内存的 K3s 集群里部署 Drone,drone-server的 readiness probe 会反复失败,日志里全是context deadline exceeded——因为 K3s 自身已占掉 1.8GB,Drone 启动时抢不到足够内存。

  • 单机二进制部署:看似最轻量,但问题在于升级和依赖管理。Drone 从 v2.10 升到 v2.12 时,Go 运行时从 1.21 升到 1.22,旧二进制文件直接报./drone-server: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found。而 Docker 镜像天然隔离运行时环境,docker pull drone/drone:2.12.0拉下来就能跑,libc 版本由镜像内建的 Alpine Linux 基础层保证。

所以最终选择Docker Compose,原因有三:

  1. 声明式配置即文档:docker-compose.yml文件里volumes映射哪几个路径、environment里哪些变量必填、depends_on依赖关系一目了然,新同事接手时不用翻十页文档猜配置逻辑;
  2. 重启策略可控:热词里高频出现docker compose restart always,这正是关键——Drone Server 必须设置restart: always,否则服务器断电重启后 CI 服务就静默宕机,而docker-compose up -d启动后,docker-compose ps一眼可见所有容器状态;
  3. 网络模型天然适配:Docker Compose 默认创建 bridge 网络,drone-server和drone-agent在同一网络内可通过服务名直接通信(如http://drone-server:3000),无需手动配置--network host或复杂 iptables 规则。

提示:不要用docker run手动启多个容器!我见过最惨的案例是某团队用 7 条docker run命令分别启 Server、Agent、PostgreSQL、Redis、Nginx、Let's Encrypt、Certbot,结果某天docker ps | grep -v "Up"发现 Agent 容器莫名退出,排查 3 小时才发现是docker run启动时没加--restart=always,而docker-compose一条restart: always就全局生效。

2.2 外部访问的三层穿透结构:Nginx 是唯一可靠选择

标题中“实现外部访问”绝非简单端口映射。Drone CI 的访问链路是:用户浏览器 → 公网 IP/DNS → 反向代理(Nginx)→ Drone Server 容器 → Drone Agent 容器。其中 Nginx 不是可选项,而是必选项,理由如下:

  • HTTPS 终止必须由 Nginx 完成:Drone Server 容器本身不处理 TLS,它只监听:3000的 HTTP 端口。若你直接docker run -p 443:3000,Drone 会因收不到X-Forwarded-Proto: https头而拒绝 OAuth 重定向,GitHub 登录页永远卡在redirect_uri_mismatch。Nginx 作为 HTTPS 终止点,解密流量后以纯 HTTP 转发给 Drone,同时注入必要头信息。

  • Host 头透传不可绕过:Drone 的 Web UI 生成的所有链接(如构建日志 URL、仓库列表跳转)都依赖Host请求头。如果用docker run -p 80:3000直连,浏览器访问http://yourip/,Drone 收到的 Host 是yourip,但 UI 里所有按钮链接却写成http://localhost:3000/xxx——因为容器内没有 DNS 解析yourip。Nginx 的proxy_set_header Host $host;一句就解决。

  • 静态资源缓存提升体验:Drone 的前端 JS/CSS 文件默认无 Cache-Control,每次刷新都重新下载。Nginx 可配置location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; },实测页面二次加载时间从 2.3s 降到 0.4s。

因此,整个架构图可简化为:

[Internet] ↓ (HTTPS 443) [Nginx Proxy] ←→ [Let's Encrypt Certbot] ↓ (HTTP 80, with X-Forwarded-* headers) [Drone Server:3000] ↓ (HTTP internal network) [Drone Agent:3000]

注意:Nginx 和 Drone Server 必须在同一台物理机(或同一 Docker 网络),否则跨主机通信会引入额外延迟和防火墙风险。这也是为什么我不推荐用 Cloudflare Tunnel 或 frp 等第三方隧道——它们无法保证X-Forwarded-For和X-Real-IP的准确透传,导致 Drone 日志里所有构建记录的 IP 都显示为127.0.0.1。

3. 核心组件配置详解:从 docker-compose.yml 到 .drone.yml 的每一行含义

3.1 docker-compose.yml:12 行配置背后的 7 个关键决策

以下是我在线上环境稳定运行 11 个月的docker-compose.yml,已去除所有注释(注释版见文末附录),先看精简版:

version: '3.8' services: drone-server: image: drone/drone:2.12.0 ports: [3000] volumes: [/var/lib/drone:/data] restart: always environment: - DRONE_SERVER_HOST=ci.yourdomain.com - DRONE_SERVER_PROTO=https - DRONE_GITHUB_CLIENT_ID=xxx - DRONE_GITHUB_CLIENT_SECRET=xxx - DRONE_RPC_SECRET=xxx - DRONE_DATABASE_DRIVER=sqlite3 - DRONE_DATABASE_DATASOURCE=/var/lib/drone/drone.sqlite drone-agent: image: drone/agent:2.12.0 restart: always depends_on: [drone-server] volumes: [/var/run/docker.sock:/var/run/docker.sock] environment: - DRONE_RPC_SERVER=http://drone-server:3000 - DRONE_RPC_SECRET=xxx - DRONE_RUNNER_CAPACITY=4 - DRONE_RUNNER_NAME=${HOSTNAME}

现在逐行解释这 12 行背后的专业判断:

第 1 行version: '3.8':必须用 3.8 或更高。低版本不支持restart: always在docker-compose up后持久生效(Docker Desktop 4.19+ 已强制要求 3.8+)。我曾因用 2.4 版本,服务器重启后docker-compose ps显示所有容器Exit 0,查了 2 小时才发现是 Compose 版本 bug。

第 4 行ports: [3000]:注意是[3000]而非["3000:3000"]。前者表示只在 Docker 内部网络暴露 3000 端口,不映射到宿主机,避免被扫描器探测到未授权访问。所有外部流量必须经 Nginx 代理,这是安全基线。

第 6 行volumes: [/var/lib/drone:/data]:Drone 官方文档写/data,但实际 SQLite 数据库文件默认生成在/var/lib/drone(Alpine 镜像内路径)。若写成/data:/data,容器内/var/lib/drone仍是空目录,导致首次启动时数据库初始化失败,日志报no such file or directory: /var/lib/drone/drone.sqlite。这个路径映射错误是新手最高频的启动失败原因。

第 9 行DRONE_SERVER_HOST=ci.yourdomain.com:必须填域名,不能填 IP。Drone 的 OAuth 重定向 URL 会拼接为此值,GitHub App 要求Authorization callback URL必须是https://ci.yourdomain.com/login。若填192.168.1.100,GitHub 会拒绝回调。

第 10 行DRONE_SERVER_PROTO=https:强制 Drone 生成的所有链接用https://。即使 Nginx 是 HTTP 反向代理,这一项也必须设为https,否则 UI 里点击“Build Logs”会跳转到http://ci.yourdomain.com/...被浏览器拦截(Mixed Content)。

第 11–12 行 GitHub Client ID/Secret:在 GitHub Settings → Developer settings → OAuth Apps 创建,Homepage URL填https://ci.yourdomain.com,Authorization callback URL填https://ci.yourdomain.com/login。注意:Client Secret 是一次性显示,务必立刻复制,丢失后只能重置。

第 13 行DRONE_RPC_SECRET=xxx:这是 Server 和 Agent 之间的通信密钥,必须 32 位以上随机字符串(用openssl rand -hex 32生成)。若 Server 和 Agent 的 secret 不一致,Agent 日志会疯狂刷rpc: cannot connect to server,但docker-compose ps显示状态正常,极易误判。

第 16 行DRONE_RUNNER_CAPACITY=4:控制并发构建数。设为 4 意味着最多同时跑 4 个构建任务。若服务器是 2核4G,建议不超过 3(留 1 核给 Nginx 和系统);4核8G 可设为 6。超过阈值的任务会排队,UI 显示pending。

第 17 行DRONE_RUNNER_NAME=${HOSTNAME}:让 Agent 在 Drone UI 的 Runner 列表里显示真实主机名(如web01),而非默认的容器 ID。方便多台服务器部署时区分 Agent 来源。

注意:DRONE_DATABASE_DRIVER=sqlite3是轻量部署的关键。官方文档虽推荐 PostgreSQL,但 SQLite 在单机场景下性能足够(实测 500+ 仓库、日均 200 次构建,查询延迟 <5ms),且无需额外部署数据库服务。若强行用 PostgreSQL,docker-compose.yml需增加 15 行配置,还得多开一个容器,违背“轻量”初衷。

3.2 Nginx 配置:11 行解决 99% 的 HTTPS 访问问题

Nginx 配置文件/etc/nginx/sites-available/ci.yourdomain.com:

server { listen 443 ssl http2; server_name ci.yourdomain.com; ssl_certificate /etc/letsencrypt/live/ci.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ci.yourdomain.com/privkey.pem; 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; } } server { listen 80; server_name ci.yourdomain.com; return 301 https://$server_name$request_uri; }

关键点解析:

  • listen 443 ssl http2:启用 HTTP/2,减少 TCP 连接数。Drone UI 加载大量小图标和 JS,HTTP/2 的多路复用能显著提速。
  • ssl_certificate路径:必须指向 Let's Encrypt 生成的证书,不能是自签名证书(GitHub OAuth 会拒绝)。
  • proxy_set_header X-Forwarded-Proto $scheme:这是 Drone 识别 HTTPS 的唯一依据。若漏掉,Drone 会认为自己跑在 HTTP 下,所有重定向链接都变成http://。
  • return 301:强制 HTTP 跳转 HTTPS,避免用户手输http://导致 OAuth 失败。

提示:Nginx 配置后必须执行sudo nginx -t && sudo systemctl reload nginx。nginx -t会检查语法,reload不中断现有连接。我曾因忘记reload,改完配置后等了 10 分钟以为配置无效,其实是旧进程还在跑。

3.3 .drone.yml:用 15 行 YAML 实现完整的 CI 流水线

在你的 GitHub 仓库根目录新建.drone.yml,这是 Drone 的“构建说明书”:

--- kind: pipeline type: docker name: default steps: - name: build image: golang:1.22-alpine commands: - go build -o myapp . - ./myapp --version - name: test image: golang:1.22-alpine commands: - go test -v ./... - name: publish image: plugins/docker:24 settings: username: ${DOCKER_USERNAME} password: ${DOCKER_PASSWORD} repo: yourname/myapp tags: ${DRONE_COMMIT_SHA:0:7} when: event: [push] branch: [main] trigger: branch: - main

逐段说明:

  • kind: pipeline:定义这是一个构建流水线(非 cron 或 signature 类型)。

  • type: docker:指定使用 Docker Runner(即 drone-agent),而非 SSH 或 Kubernetes。

  • steps下的三个阶段:

    • build步骤用golang:1.22-alpine镜像(体积仅 150MB,比golang:1.22的 900MB 快 3 倍拉取)编译二进制;
    • test步骤复用同一镜像运行单元测试;
    • publish步骤用官方plugins/docker:24插件构建并推送 Docker 镜像,tags: ${DRONE_COMMIT_SHA:0:7}取前 7 位 commit hash 作 tag,确保镜像唯一性。
  • when和trigger:when.event: [push]表示仅在 push 事件触发,trigger.branch: [main]表示只对 main 分支生效。若你想 PR 时也跑测试,改为event: [push, pull_request]即可。

  • 环境变量${DOCKER_USERNAME}:在 Drone UI 的仓库设置页 → Secrets 中添加,名称必须完全匹配(大小写敏感)。Drone 会自动注入,不会泄露在日志中。

实操心得:.drone.yml修改后无需重启 Drone 服务,下次 push 自动生效。但首次提交时,需手动在 Drone UI 的仓库开关页点击 “Activate Repository”,否则不监听该仓库事件。这个按钮藏在https://ci.yourdomain.com/repos/yourname/yourrepo页面右上角,很小,容易忽略。

4. 实操全流程:从服务器初始化到第一个构建成功的 22 分钟记录

4.1 环境准备:Ubuntu 22.04 下的 6 步初始化(含避坑清单)

我以全新 Ubuntu 22.04 服务器为例,记录完整操作过程(所有命令均实测通过):

步骤 1:安装 Docker 和 Docker Compose

# 卸载旧版(如有) sudo apt remove docker docker-engine docker.io containerd runc # 安装依赖 sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 添加稳定版仓库 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装 Docker Engine sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 验证 sudo docker run hello-world # 应输出欢迎信息

注意:热词中常搜ubuntu安装docker compose,但 Ubuntu 22.04 官方源的docker-compose包是 1.x 版本(已废弃),必须用docker-compose-plugin(即docker compose命令)。若你看到docker-compose: command not found,请确认是否执行了sudo apt install docker-compose-plugin。

步骤 2:创建 Drone 工作目录并赋权

sudo mkdir -p /opt/drone sudo chown $USER:$USER /opt/drone cd /opt/drone

步骤 3:编写 docker-compose.yml(粘贴前文 12 行版)

nano docker-compose.yml # 粘贴内容,修改 DRONE_GITHUB_CLIENT_ID/SECRET 和 DRONE_RPC_SECRET

步骤 4:生成 RPC Secret 并保存

# 生成 64 字符密钥(32 字节 hex) RPC_SECRET=$(openssl rand -hex 32) echo "DRONE_RPC_SECRET=$RPC_SECRET" >> .env # .env 文件会被 docker-compose 自动加载

步骤 5:启动服务并验证日志

# 启动(-d 后台运行) docker-compose up -d # 查看 Server 日志(等待 10 秒,直到出现 "server listening on address") docker-compose logs -f drone-server | grep "listening" # 查看 Agent 日志(应出现 "connected to server") docker-compose logs -f drone-agent | grep "connected"

常见问题:若docker-compose logs drone-server一直刷database is locked,说明 SQLite 文件被其他进程占用。执行sudo lsof /var/lib/drone/drone.sqlite查看谁在用,通常是前一次启动失败的残留进程,sudo killall drone-server后重试。

步骤 6:配置 Nginx 和 Let's Encrypt

# 安装 Nginx sudo apt install -y nginx # 获取证书(需提前将 ci.yourdomain.com DNS 解析到此服务器 IP) sudo snap install core; sudo snap refresh core sudo snap install --classic certbot sudo certbot --nginx -d ci.yourdomain.com # 启用配置 sudo ln -sf /etc/nginx/sites-available/ci.yourdomain.com /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

此时访问https://ci.yourdomain.com,应看到 Drone 登录页。用 GitHub 账号登录,首次会跳转到 GitHub 授权页,同意后回到 Drone,自动创建用户。

4.2 第一个构建实战:Vue 项目从零到自动部署的完整链路

以一个 Vue 3 项目为例,演示端到端流程:

1. 在 GitHub 创建新仓库vue-demo,初始化 README.md

2. 本地克隆并添加.drone.yml

git clone https://github.com/yourname/vue-demo.git cd vue-demo nano .drone.yml

填入 Vue 专用配置:

--- kind: pipeline type: docker name: build-and-deploy steps: - name: install image: node:18-alpine commands: - npm ci - name: build image: node:18-alpine commands: - npm run build - ls -la dist/ - name: deploy image: appleboy/scp-action:latest settings: host: your-server-ip username: your-username key: ${SSH_KEY} from: dist/** to: /var/www/vue-demo/ when: event: [push] branch: [main]

3. 添加 SSH Key Secret
在 Drone UI 的https://ci.yourdomain.com/repos/yourname/vue-demo/settings→ Secrets,添加名为SSH_KEY的密钥,值为你的私钥内容(cat ~/.ssh/id_rsa),注意开头是-----BEGIN OPENSSH PRIVATE KEY-----。

4. 提交并触发构建

git add .drone.yml git commit -m "add drone ci" git push origin main

5. 实时观察构建过程
打开https://ci.yourdomain.com/repos/yourname/vue-demo,点击最新构建,看到三步状态:

  • install:拉取node:18-alpine(约 12 秒)→ 运行npm ci(约 28 秒);
  • build:运行npm run build(约 45 秒),日志末尾显示dist/目录大小;
  • deploy:用scp-action将dist/下所有文件推送到服务器/var/www/vue-demo/(约 3 秒)。

6. 验证部署结果
在服务器上执行:

ls -la /var/www/vue-demo/ # 应看到 index.html, assets/ 等 sudo nginx -t && sudo systemctl reload nginx # 若 Nginx 已配好此目录

访问https://vue-demo.yourdomain.com(需提前配好 Nginx server block),即可看到构建好的 Vue 页面。

实操心得:第一次构建失败率高达 70%,主因是npm ci报ENOTFOUND registry.npmjs.org。这是因为国内网络访问 npm 官方源慢,需在install步骤前加一行:

- npm config set registry https://registry.npmmirror.com

阿里云镜像源https://registry.npmmirror.com响应时间 <100ms,实测提速 5 倍。

5. 常见问题与排查技巧实录:那些文档里不会写的 11 个致命坑

5.1 启动阶段:docker-compose up 后服务不响应的 5 种原因

现象日志线索根本原因解决方案
docker-compose ps显示drone-serverUp,但curl http://localhost:3000超时docker-compose logs drone-server无输出DRONE_DATABASE_DATASOURCE路径错误,SQLite 文件未创建检查volumes映射,确认/var/lib/drone目录存在且可写
drone-agent日志反复刷rpc: cannot connect to serverdial tcp 172.20.0.2:3000: connect: connection refuseddrone-server容器未完全启动,Agent 启动太快在drone-agent服务下加healthcheck,或depends_on改为condition: service_healthy
drone-server日志报failed to ping database: no such table: buildsdatabase is lockedSQLite 文件被其他进程占用(如前次崩溃残留)sudo lsof /var/lib/drone/drone.sqlite找出 PID,sudo kill -9 PID
drone-server启动后立即退出,docker-compose ps显示Exit 1invalid value "https" for flag -server-protoDRONE_SERVER_PROTO值写成https://(多了://)改为https(纯协议名)
drone-agent启动后docker-compose ps显示Restartinglevel=error msg="runner registration failed" error="rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 172.20.0.2:3000: connect: connection refused\""drone-server的ports写成["3000:3000"],导致端口被宿主机占用改为ports: [3000],确保只在 Docker 网络内暴露

提示:用docker network inspect drone_default查看drone-server的 IP(如172.20.0.2),然后docker exec -it <agent_container_id> sh进入 Agent 容器,执行telnet 172.20.0.2 3000测试连通性。若不通,说明网络或 Server 未就绪。

5.2 访问阶段:能登录但构建失败的 4 类典型故障

故障 1:GitHub 登录后跳转https://ci.yourdomain.com/login?error=redirect_uri_mismatch

  • 原因:GitHub OAuth App 的Authorization callback URL填了http://ci.yourdomain.com/login(少s),或DRONE_SERVER_HOST值与域名不一致(如填了www.ci.yourdomain.com但 DNS 解析的是ci.yourdomain.com)。
  • 排查:在浏览器开发者工具 Network 标签页,找login?error=请求,看Location响应头里的 redirect_uri 是什么。
  • 修复:严格按https://ci.yourdomain.com/login填写 GitHub 设置,并确保DRONE_SERVER_HOST=ci.yourdomain.com(无www,无https://)。

故障 2:构建日志里go test报cannot find module providing package github.com/xxx/yyy

  • 原因:Go Module 依赖未下载,go mod download未执行。
  • 修复:在test步骤前加go mod download,或在install步骤统一执行:
    - name: setup image: golang:1.22-alpine commands: - go mod download - go mod verify

故障 3:plugins/docker步骤报denied: requested access to the resource is denied

  • 原因:Docker Hub 的DOCKER_USERNAME和DOCKER_PASSWORDSecret 值错误,或账号未开启 2FA(Docker Hub 要求 2FA 才允许 API 推送)。
  • 验证:在服务器上手动执行docker login -u $USER -p $PASS,看是否成功。
  • 修复:在 Drone UI Secrets 里重新添加正确的凭据,并确认 Docker Hub 账号已启用 2FA。

故障 4:构建成功但scp-action报Permission denied (publickey)

  • 原因:SSH_KEYSecret 值是公钥(id_rsa.pub)而非私钥(id_rsa),或私钥格式错误(如 Windows 换行符\r\n)。
  • 修复:用cat ~/.ssh/id_rsa \| tr -d '\r'去除回车,再复制到 Secret 值中;或用ssh-keygen -p -f ~/.ssh/id_rsa重新输入密码(若私钥有密码,scp-action不支持,需用ssh-keygen -p -P "oldpass" -N "" -f ~/.ssh/id_rsa清空密码)。

5.3 性能优化:让 Drone 构建速度提升 300% 的 2 个硬核技巧

技巧 1:复用 Docker 构建缓存(BuildKit)
默认plugins/docker使用 Legacy Builder,不共享层缓存。在docker-compose.yml的drone-server服务下加:

environment: - DRONE_DOCKER_ENABLED=true - DRONE_DOCKER_NETWORKS=[bridge] # 并在 .drone.yml 的 publish 步骤加: settings: dockerfile: Dockerfile context: . cache_from: yourname/myapp:latest cache_to: type=inline

这样docker build会复用上次构建的 layer,实测 Node.js 项目构建从 82 秒降到 24 秒。

技巧 2:Agent 本地缓存 npm/yarn 包
在docker-compose.yml的drone-agent服务下加:

volumes: - /var/run/docker.sock:/var/run/docker.sock - /opt/drone/cache:/cache # 新增缓存卷 environment: - DRONE_RUNNER_CACHE=/cache

并在.drone.yml的install步骤加:

- npm config set cache /cache/npm - yarn config set cache-folder /cache/yarn

首次构建后,/opt/drone/cache会存下所有依赖包

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询