- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
本指南以 Woodpecker v3.17 官方文档 10-docker.md 为核心,系统讲解 Docker 这一 Woodpecker 最原始、最成熟的 CI 执行后端的配置与运维方法。你将掌握:如何通过 Docker 凭据助手接入私有镜像仓库、如何为单个步骤指定运行用户、如何用环境变量为流水线容器设置网络、卷与 CPU/内存资源上限,以及镜像清理、Podman 兼容等实战技巧;同时结合仓库源码,理解每一项配置在底层是如何落到 Docker 容器上的。
Docker 后端:每个步骤一个独立容器
Docker 是 Woodpecker 最早使用的执行后端(original backend),也是默认与最常用的后端。它的核心模型是:Agent 收到的每一个流水线步骤(step)都会启动一个独立的 Docker 容器来执行,步骤之间彼此隔离,执行环境由镜像决定。
从源码看,该后端位于 pipeline/backend/docker/,入口实现New()返回名为docker的引擎(见 docker.go)。其完整的生命周期由以下方法构成:
SetupWorkflow:为整个流水线创建工作卷(volume,驱动为local)和隔离网络(Linux 上为bridge驱动,Windows 上为nat),并可启用 IPv6(见 docker.go);StartStep:拉取镜像 → 创建容器 → 将容器接入流水线网络及额外指定网络 → 启动容器(见 docker.go);WaitStep/TailStep:等待容器退出并读取退出码、是否 OOM 被杀,同时实时跟随容器 stdout/stderr 日志;DestroyStep/DestroyWorkflow:按「先优雅停止 → 超时强制kill -9→ 删除容器」的顺序清理步骤容器,再移除卷和网络(见 docker.go)。
容器命名统一为wp_<step.UUID>(见 convert.go),默认日志驱动为json-file。掌握这一生命周期,有助于理解后文各项配置分别作用于哪个阶段。
私有镜像仓库:Docker 凭据助手与 WOODPECKER_DOCKER_CONFIG
当流水线步骤使用私有镜像时,Woodpecker 支持通过 Docker 官方凭据助手(docker-credential-helpers,如docker-credential-ecr-login、docker-credential-gcr等)安全地保存仓库凭据,而不是把密码明文写进配置。
使用步骤
- 在运行 Woodpecker Server 的容器中安装对应的凭据助手。文档给出的官方做法是构建一个自定义镜像:
FROM woodpeckerci/woodpecker-server:latest-alpine RUN apk add -U --no-cache docker-credential-ecr-login- 在 Server 的 Docker 配置文件(
config.json)中为相应镜像仓库配置该凭据助手; - 通过环境变量
WOODPECKER_DOCKER_CONFIG把这个配置文件传给 Server,例如:
WOODPECKER_DOCKER_CONFIG=/home/user/.docker/config.jsonWOODPECKER_DOCKER_CONFIG的完整说明见 10-server.md:其作用是「为所有流水线配置一个特定的私有仓库配置」(Configures a specific private registry config for all pipelines),默认值为空。
底层解析逻辑
Server 端在启动时会读取该配置文件,将其中的凭据转换为只读的全局 Registry 供流水线拉取镜像使用。实现位于 server/services/registry/filesystem.go:
- 解析 Docker 的
config.json,遍历CredentialHelpers中的凭据助手并调用其获取认证信息; - 对
AuthConfigs中 base64 编码的Auth字段进行解码还原出用户名密码; - 最终把每个 registry 地址转换为
model.Registry{Address, Username, Password, ReadOnly: true}。
Agent 侧在StartStep拉取镜像时,也会把步骤携带的认证信息 base64 编码为RegistryAuth附加到ImagePull请求(见 convert.go 与 docker.go)。
Step 级配置:指定运行用户(Run user)
默认情况下,Docker 后端启动步骤容器时不传--user标志,因此容器使用镜像自身的默认用户(通常是root)。如果需要以特定用户/组运行步骤,可以在步骤的backend_options.docker中设置user,其语法与docker run --user完全一致:
steps: - name: example image: alpine commands: - whoami backend_options: docker: user: 65534:65534上面的例子以 UID/GID 均为65534(即nobody用户)的身份执行whoami,实际输出会是nobody。
源码实现
该选项由 backend_options.go 定义:
type BackendOptions struct { User string `mapstructure:"user"` }parseBackendOptions通过mapstructure.WeakDecode把 YAML 中的backend_options.docker映射到该结构体;随后在 convert.go 的toConfig中,options.User被写入容器配置的User字段,最终对应docker create/run --user参数。若不设置,该字段为空字符串,容器即使用镜像默认用户。
运维技巧:镜像与卷的清理
Agent不会自动清理宿主机上的镜像。镜像的累积会持续占用磁盘,因此官方建议由宿主机系统自行管理清理任务,例如通过 cron 定期执行。
⚠️ 以下命令具有破坏性且不可逆。官方文档强烈建议先在测试系统上验证这些命令,再通过 cron 或其他自动化手段投入到生产环境。
- 删除所有悬空(未被任何容器引用的)镜像:
docker image rm $(docker images --filter "dangling=true" -q --no-trunc)- 删除 Woodpecker 遗留的卷(以
wp_前缀命名、且处于悬空状态):
docker volume rm $(docker volume ls --filter name=^wp_* --filter dangling=true -q)wp_前缀与源码中的命名约定一致:步骤容器名为wp_<step.UUID>(convert.go),流水线工作卷同样以wp_开头创建。
Podman 兼容尝试
Woodpecker官方不提供对 Podman 的正式支持,但可以通过将DOCKER_HOST环境变量指向 Podman 的 socket 来尝试使用 Podman 作为 Docker API 的实现。官方措辞是"might work"(也许可以工作),即不保证完全兼容。之所以可行,是因为 Docker 后端本身就是通过 Docker Engine API 与守护进程通信的——源码中WOODPECKER_BACKEND_DOCKER_HOST的取值会回退到标准的DOCKER_HOST环境变量(见 flags.go),因此任何实现了 Docker API 的守护进程(如 Podman 的兼容 socket)都有可能被驱动。生产使用前务必充分测试。
环境变量总览:Docker 后端的全部配置项
Docker 后端的所有配置均以WOODPECKER_BACKEND_DOCKER_为前缀,作用于 Agent。下表逐项列出官方文档中的配置:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
WOODPECKER_BACKEND_DOCKER_NETWORK | 无 | 把流水线所有步骤容器额外接入一个已存在的Docker 网络 |
WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6 | false | 为流水线步骤使用的网络启用 IPv6,需先保证 Docker daemon 支持 IPv6 |
WOODPECKER_BACKEND_DOCKER_VOLUMES | 无 | 逗号分隔的默认卷列表,挂载到所有步骤容器 |
WOODPECKER_BACKEND_DOCKER_APPARMOR_PROFILE | 无 | 为步骤容器设置 AppArmor 安全配置文件;不设置则由 Docker 采用默认 AppArmor 行为 |
WOODPECKER_BACKEND_DOCKER_LIMIT_MEM_SWAP | 0 | 单个步骤容器允许换到磁盘的最大内存(字节),0表示不限 |
WOODPECKER_BACKEND_DOCKER_LIMIT_MEM | 0 | 单个步骤容器可使用的最大内存(字节),0表示不限 |
WOODPECKER_BACKEND_DOCKER_LIMIT_SHM_SIZE | 0 | /dev/shm允许的最大内存(字节),0表示不限 |
WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_QUOTA | 0 | 每个 CPU 周期内容器被限流前可使用的微秒数,0表示不限 |
WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SHARES | 0 | 与其他容器相比的相对 CPU 权重 |
WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SET | 无 | 逗号分隔的 CPU 列表,限制步骤容器可使用的 CPU/核心 |
各配置的详细说明如下。
WOODPECKER_BACKEND_DOCKER_NETWORK
设置后,每个流水线步骤容器在启动时除了加入流水线自建的隔离网络外,还会被额外接入这个已有网络。请务必小心:这会让不同流水线的容器之间互相可达,破坏隔离性,仅在确实需要跨流水线通信时才使用。从源码看,该网络的接入发生在StartStep阶段(docker.go),且仅当步骤未指定network_mode时生效。
WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6
启用后,SetupWorkflow创建流水线网络时会传入EnableIPv6标志(见 docker.go)。前提是宿主机 Docker daemon 已配置 IPv6 支持,否则网络创建可能失败。
WOODPECKER_BACKEND_DOCKER_VOLUMES
逗号分隔的卷列表,每个条目格式为宿主路径:容器路径[:读写模式],会挂载到所有步骤容器。官方文档给出的典型用例是让流水线容器使用宿主机自签 CA 证书与主机时区:
WOODPECKER_BACKEND_DOCKER_VOLUMES=/etc/ssl/certs:/etc/ssl/certs:ro,/etc/timezone:/etc/timezone源码会在 Agent 启动时校验每个卷定义是否合法,非法条目直接报错退出,错误信息形如invalid volume '...' provided in WOODPECKER_BACKEND_DOCKER_VOLUMES(见 config.go)。生效时这些默认卷会与步骤自身声明的卷去重合并后写入HostConfig.Binds(见 docker.go)。
WOODPECKER_BACKEND_DOCKER_APPARMOR_PROFILE
为步骤容器指定 AppArmor 配置文件。源码在构造HostConfig时,若该值非空,会追加SecurityOpt: ["apparmor=<profile>"](见 convert.go)。留空则由 Docker 按自身默认 AppArmor 策略处理。
资源限制(LIMIT_* 系列)
六个LIMIT_配置共同构成对单个步骤容器的资源上限,在toHostConfig中被一一映射到 Docker 的container.Resources字段(见 convert.go):
LIMIT_MEM→MemoryLIMIT_MEM_SWAP→MemorySwapLIMIT_SHM_SIZE→ShmSizeLIMIT_CPU_QUOTA→CPUQuotaLIMIT_CPU_SHARES→CPUSharesLIMIT_CPU_SET→CpusetCpus
它们分别对应docker run的--memory、--memory-swap、--shm-size、--cpu-quota、--cpu-shares、--cpuset-cpus参数。示例:
WOODPECKER_BACKEND_DOCKER_LIMIT_MEM=1073741824 # 1 GiB 内存上限 WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SET=1,2 # 仅允许使用 CPU 1 和 2注意所有内存类配置单位为字节,0表示不设限;CPU 相关限制作用于容器调度,可组合使用以达到精确的资源配额。
未在文档中单列但源码支持的相关配置
此外,flags.go 还声明了以下同属 Docker 后端的 Agent 环境变量,可与上文配置组合使用:
WOODPECKER_BACKEND_DOCKER_HOST(回退到DOCKER_HOST):Docker socket 路径或 Docker 服务器 URL;WOODPECKER_BACKEND_DOCKER_API_VERSION(回退到DOCKER_API_VERSION):Docker API 版本,留空表示最新;WOODPECKER_BACKEND_DOCKER_CERT_PATH(回退到DOCKER_CERT_PATH):连接 Docker 服务器的 TLS 证书目录;WOODPECKER_BACKEND_DOCKER_TLS_VERIFY(回退到DOCKER_TLS_VERIFY):是否校验 TLS,默认true;WOODPECKER_BACKEND_DOCKER_STOP_TIMEOUT:等待容器优雅停止的秒数,默认20秒,超时后强制kill -9(对应 docker.go 中"先 Stop 再 Kill"的清理流程)。
TLS 证书加载逻辑见 docker.go:当指定了backend-docker-cert时,会读取ca.pem、cert.pem、key.pem构建带校验的 HTTPS 客户端,并把InsecureSkipVerify设为!verifyTLS。
小结
Docker 后端以「一步骤一容器」的模型,为 Woodpecker 提供了成熟稳定的隔离执行环境。实践中的要点可以归纳为:
- 私有镜像:用 Docker 凭据助手 +
WOODPECKER_DOCKER_CONFIG安全接入,Server 端会自动解析为只读全局 Registry; - 步骤定制:通过
backend_options.docker.user以非 root 身份运行敏感步骤; - 资源治理:用
WOODPECKER_BACKEND_DOCKER_LIMIT_*系列限制单个容器的内存、swap、/dev/shm与 CPU,防止个别步骤拖垮 Agent; - 运维兜底:Agent 不自动清理镜像,需宿主侧定时执行清理命令;
WOODPECKER_BACKEND_DOCKER_NETWORK与 Podman(DOCKER_HOST)属于高风险/非官方支持的尝试,务必在可控环境验证。
延伸阅读
- 官方配置文档:10-docker.md
- Server 端
WOODPECKER_DOCKER_CONFIG说明:10-server.md - 后端实现:pipeline/backend/docker/docker.go、pipeline/backend/docker/convert.go
- 配置解析:pipeline/backend/docker/flags.go、pipeline/backend/docker/config.go
- 步骤级选项:pipeline/backend/docker/backend_options.go
- 私有仓库配置解析:server/services/registry/filesystem.go
- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
相关推荐
Woodpecker Docker 后端(Backend)完全指南:从私有镜像仓库到资源限制的配置实战
Woodpecker Docker 后端(Backend)完全指南:从私有镜像仓库到资源限制的配置实战 Woodpecker 是一个简单而强大的 CI/CD 引
CI/CDDevOpsWoodpecker Docker 后端(Backend)完全指南:镜像执行、凭据配置、Podman 兼容与镜像清理
Woodpecker Docker 后端(Backend)完全指南:镜像执行、凭据配置、Podman 兼容与镜像清理 导读 Docker 是 Woodpecke
CI/CDDevOpsWoodpecker 容器镜像仓库(Registry)配置完全指南:私有镜像拉取、全局仓库与本地镜像构建
Woodpecker 容器镜像仓库(Registry)配置完全指南:私有镜像拉取、全局仓库与本地镜像构建 本篇指南以 Woodpecker CI/CD 引擎 v
CI/CDDevOps
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考