- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
Woodpecker 的 Local 后端让 agent 直接在宿主机上以普通进程方式执行流水线命令,无需任何容器运行时,是 macOS、OpenBSD 等无法运行 Docker/Kubernetes 后端的平台上的唯一选择。本文围绕 30-local.md 展开,结合仓库源码深入讲解其安全模型、运行机制、Shell 与插件配置以及环境变量,帮助你在可信的私有环境中正确启用并安全使用这一后端。
:::dangerLocal 后端在本地系统上执行流水线,没有任何隔离(isolation)。:::
:::note当前该后端不支持 services(详见 Woodpecker 仓库 issue #3095)。 :::
Local 后端的定位与适用场景
与 Docker 或 Kubernetes 后端不同,Local 后端不创建容器,而是把流水线中的每条命令作为宿主机上的普通进程直接执行。由于命令运行在与 agent 完全相同的上下文中——同一个用户、同一个文件系统——一个恶意的流水线完全有能力读取 agent 的配置,尤其是WOODPECKER_AGENT_SECRET变量,从而伪造 agent 身份、接管整个 CI 系统。
因此官方文档给出明确的使用边界:
- 只建议在私有环境中使用,且必须保证提交的代码和流水线本身可信;
- 不应部署在允许任何人提交代码或添加新仓库的公共实例上;
- agent 不应以特权用户(如 root)运行,以尽量缩小命令执行时的权限范围。
一句话总结:Local 后端是"用安全换便捷"的取舍,适合个人自托管、本机调试以及无法使用容器的平台,不适合多租户或面向不可信输入的场景。
工作机制:临时目录、工作区与生命周期
Local 后端会在$TMPDIR(系统临时目录)中创建一个随机目录来存放克隆的代码并执行命令。从源码看,这一过程由 pipeline/backend/local/local.go 完整实现:
- SetupWorkflow:调用
os.MkdirTemp(e.tempDir, "woodpecker-local-*")为每个 workflow 创建独立临时目录baseDir,并在其下创建权限为0o700的home目录与workspace目录(local.go#L98-L140); - StartStep:根据步骤类型(
clone/commands/plugin)分派到对应的执行函数,并为步骤进程注入环境变量,其中CI_WORKSPACE被固定设置为该 workflow 的workspaceDir(local.go#L142-L176); - WaitStep / TailStep:通过
exec.Cmd的进程状态获取退出码,并通过StdoutPipe向 agent 回传实时日志; - DestroyWorkflow:任务结束后
os.RemoveAll(state.baseDir)清理整个临时目录(local.go#L263-L296)。
值得注意的细节:所有步骤命令都会通过newCmd创建独立的进程组(Setpgid: true),取消步骤时向整个进程组发送SIGKILL,避免步骤的 kill 信号传播回 agent,同时防止产生孤儿进程(见 pipeline/backend/local/cmd_unix.go)。对应的回归测试 process_group_test.go 专门验证了"步骤信号不会传播到 agent"这一行为。
另外,在 agent 环境中,Local 后端只有在检测到WOODPECKER_IN_CONTAINER环境变量未设置时才会被IsAvailable判定为可用——也就是说,如果 agent 自身运行在容器里,Local 后端不会被自动选中(local.go#L70-L78)。
启用 Local 后端
使用 Local 后端需要先在宿主机上下载(或自行构建)agent,配置好与 server 的连接后直接运行。启用方式是通过 agent 的backend-engine参数指定:
# 环境变量方式 WOODPECKER_BACKEND=local woodpecker-agent # 或命令行参数方式 woodpecker-agent --backend-engine local从 cmd/agent/core/flags.go 可以看到,backend-engine的默认值是auto-detect;FindBackend会依次检查每个后端的IsAvailable并选择第一个可用的引擎(pipeline/backend/backend.go#L24-L33)。在无法使用 Docker/Kubernetes 的平台上,Local 后端通常会作为 auto-detect 的结果被选中。
步骤配置:Shell
在 Local 后端中,步骤的image字段不再表示容器镜像,而是指定用来执行命令的 shell,例如bash或fish:
steps: - name: build image: bash commands: - go build ./...执行前后端会先通过exec.LookPath(shell)校验该 shell 是否存在于$PATH(command.go#L76-L79)。随后genCmdByShell会根据 shell 类型生成不同的调用参数(command.go#L81-L142):
| Shell | 生成的调用方式 | 说明 |
|---|---|---|
sh/bash/zsh | -e -c <script> | 以-e模式运行,命令失败即中断 |
| 其他未知 shell | 先执行probeShellIsPosix探测 | 通过探测则按 POSIX 方式处理,否则报ErrNoPosixShell |
fish | -c <script> | 每条命令后追加\|\| exit $status |
nu | --commands <script> | Nushell 风格 |
powershell/pwsh | -noprofile -noninteractive -c ... | 以$ErrorActionPreference = "Stop"开头,错误即停止 |
cmd(Windows) | /D /C <临时 .cmd 文件> | 生成批处理脚本,每条命令后检查%ERRORLEVEL% |
每条命令在拼接进脚本前都会以echo + <command>的形式回显,便于在日志中区分输出归属。POSIX 兼容性探测的具体逻辑(probeShellIsPosix)在 command.go#L145-L159,而针对各种 shell 参数生成的单元测试可参考 command_test.go,其中覆盖了cmd.exe的 Base64 转义脚本、PowerShell 参数、fish 的exit $status等场景。
步骤配置:Plugins
Local 后端下的插件就是普通的可执行二进制文件。如果步骤没有提供commands,后端会将其按插件处理:
steps: - name: build image: /usr/bin/tree插件二进制可以通过名称定位(前提是它列在$PATH中),也可以使用绝对路径。实现上,execPlugin调用exec.LookPath(step.Image)找到二进制后直接执行(plugin.go#L26-L51)。这与 Docker 后端"拉取镜像并运行"的插件机制完全不同——没有镜像层、没有依赖打包,插件必须预先安装在宿主机上。
克隆步骤与凭据处理
Local 后端使用 plugin-git 的二进制版本完成仓库克隆,而不是容器镜像:
- 后端启动时先检查宿主机上是否存在全局
plugin-git二进制(loadClone,见 clone.go#L40-L47); - 如果不存在,
setupClone会根据当前操作系统与架构从 GitHub API 下载最新 release 的plugin-git二进制到 workflow 的home目录(clone.go#L50-L62); - 克隆前还会检查宿主机是否装有
git(checkGitCloneCap)。
凭据方面,当流水线需要访问私有仓库时,后端会基于CI_NETRC_MACHINE/CI_NETRC_USERNAME/CI_NETRC_PASSWORD环境变量在隔离的home目录中生成~/.netrc(Windows 下为_netrc)文件,权限为0o600,并在克隆完成后立即删除(clone.go#L121-L141)。需要注意的是,.netrc的写入依赖isolated home功能处于开启状态(详见下文环境变量)。此外,CI_NETRC_*、HOME、CI_WORKSPACE等关键变量被列入notAllowedEnvVarOverwrites,流水线无法通过步骤环境变量覆盖它们(const.go#L21-L30)。
环境变量与配置项
WOODPECKER_BACKEND_LOCAL_TEMP_DIR
- 对应 CLI 参数:
--backend-local-temp-dir - 默认值:系统临时目录(
os.TempDir())
用于指定创建工作流目录的临时文件夹。后端通过os.MkdirTemp在此目录下生成woodpecker-local-*前缀的随机目录(local.go#L101)。如果你的系统临时目录空间不足、或希望把克隆的仓库放到特定磁盘,可以通过该变量调整。
WOODPECKER_BACKEND_LOCAL_ISOLATED_HOME
- 对应 CLI 参数:
--backend-local-isolated-home - 默认值:
true
开启后,后端会把步骤的HOME(以及 Windows 的USERPROFILE)设置为 workflow 专属的隔离目录(<baseDir>/home),避免流水线读写 agent 用户真实的 home 目录;同时这也是写入.netrc凭据文件的前提。如果将其设为false,后端会忽略 netrc 凭据注入(见 flags.go#L31-L36 与 local.go#L159-L162)。两个参数的说明同样出现在 version-3.16 CLI 参考 中。
完整参数定义位于 pipeline/backend/local/flags.go,其中Value: os.TempDir()与Value: true分别对应上述两个默认值。
平台支持
Local 后端支持 Windows、macOS、FreeBSD 和 OpenBSD;在 macOS 与 OpenBSD 上,它是唯一可用的执行后端。完整的组件与后端支持矩阵见 Supported platforms,其中明确标注:
| 后端 | Linux | Windows | macOS | FreeBSD | OpenBSD |
|---|---|---|---|---|---|
| Docker | ✅ | ✅(经 WSL2/Windows 容器) | – | WIP | – |
| Kubernetes | ✅ | – | – | – | – |
| Local | ✅ | ✅ | ✅ | ✅ | ✅ |
另外,plugin-git为各平台发布了独立二进制(Windows/macOS/FreeBSD/OpenBSD 均提供 Binary),这正对应 Local 后端"下载并执行二进制插件"的克隆方案。在无法使用 Docker/Kubernetes 后端的宿主机上,也可以选择禁用默认克隆步骤、在流水线里手动克隆。
局限与注意事项
- 无隔离:命令与 agent 同用户、同文件系统执行,恶意流水线可读取 agent 配置(尤其是
WOODPECKER_AGENT_SECRET),只适用于可信私有环境; - 不支持 services:不能在流水线中声明数据库、缓存等服务容器(见 60-services.md 与 issue #3095);
- 插件需预装:插件不再是镜像而是宿主机二进制,必须存在于
$PATH或使用绝对路径; - shell 依赖:所选 shell 必须已安装,且未知 shell 需通过 POSIX 兼容性探测;
- 不推荐以 root 运行 agent,以降低命令执行的潜在危害。
深入阅读
- 后端官方文档:30-local.md
- 后端核心实现:pipeline/backend/local/local.go、command.go、clone.go、plugin.go
- 配置参数定义:flags.go
- 后端选择与 auto-detect 逻辑:pipeline/backend/backend.go
- agent 参数(
--backend-engine):cmd/agent/core/flags.go - 平台支持矩阵:05-supported-platforms.md
- 相关测试:local_test.go、command_test.go、cmd_unix_test.go、process_group_test.go
- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
相关推荐
Woodpecker Local 后端实战指南:在宿主机上无容器运行流水线的原理、配置与安全边界
Woodpecker Local 后端实战指南:在宿主机上无容器运行流水线的原理、配置与安全边界 Woodpecker 的 Local(本地)后端 允许 Age
CI/CDDevOpsWoodpecker Local 后端完全指南:在 Agent 主机上直接执行流水线
Woodpecker Local 后端完全指南:在 Agent 主机上直接执行流水线 Local 是 Woodpecker 提供的三种执行后端之一,它让 woo
CI/CDDevOpsKustomize 本地配置(Local Configuration)深入指南:用 config.kubernetes.io/local-config 注解隔离构建期资源
Kustomize 本地配置(Local Configuration)深入指南:用 config.kubernetes.io/local config 注解隔离
CLI开发工具云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考