Dokku Nixpacks Builder 完全指南:用 Nixpacks 替代 Buildpack 构建应用
[!NOTE] 本文基于当前仓库 plugins/builder-nixpacks 插件的真实实现与官方文档 nixpacks.md 撰写。Nixpacks builder 是 Dokku 在 0.32.0 版本中新增的构建器,它借助 Nixpacks 这套 buildpack 替代方案,为应用提供另一种自动检测语言、自动生成 Dockerfile 的构建路径。读完本文,你将掌握:如何安装与启用 Nixpacks builder、它的自动检测规则与手动切换方式、构建期环境变量的安全处理办法、如何自定义
nixpacks.toml的查找位置(含 monorepo 场景)、如何禁用构建缓存,以及如何用builder-nixpacks:report排查配置问题。
背景:为什么 Dokku 需要 Nixpacks
Dokku 的构建系统通过 builder 插件抽象出统一的构建接口,由 builder-detect 触发器在部署时判定使用哪个构建器。传统的 builder-herokuish 依赖 Heroku buildpack 体系,而 Nixpacks 则是另一种思路:它通过扫描应用源码的语言特征与包管理文件,自动推导出构建与启动命令,并生成对应的 Dockerfile。
从源码结构看,Dokku 的构建器家族(plugins/builder-* 目录)各自独立成插件,builder-nixpacks 插件仅负责把 Dokku 的部署流程桥接到 nixpacks CLI 上。对于希望绕开 buildpack 体系、直接控制镜像构建细节的开发者,Nixpacks 提供了一条更贴近 Docker 原生体验的路径。
安装要求
Nixpacks 与 Herokuish 不同:nixpacks CLI 工具既不随 Dokku 一起安装,也不是 Dokku 的依赖项。因此启用该 builder 前必须先在宿主机上手动安装 nixpacks CLI,官方文档建议参考 Nixpacks 的 Debian(及其衍生版如 Ubuntu)安装页面。
这一要求在源码中有直接体现——builder-build 触发器中,构建开始前会先检查 CLI 是否存在:
if ! command -v "nixpacks" &>/dev/null; then
dokku_log_fail "Missing nixpacks, install it"
fi
安装完成后,构建会从该次部署起一直使用 nixpacks CLI 进行。
Builder 检测与手动选择
Nixpacks builder 遵循 Dokku 标准的构建器自动检测机制(builder-detect 触发器)。其检测规则非常明确,见 builder-detect:
if [[ -f "$SOURCECODE_WORK_DIR/nixpacks.toml" ]]; then
echo "nixpacks"
return
fi
即满足以下任一条件时启用:
- 应用仓库根目录存在
nixpacks.toml文件(自动检测)。
也可以跳过自动检测,用 builder:set 命令显式指定:
dokku builder:set node-js-app selected nixpacks
[!NOTE]
builder:set设置的是“选定构建器”,与builder-nixpacks:set(设置 nixpacks 插件的属性)是两个不同层级的命令,注意区分。
支持的语言
Nixpacks 对语言/框架的支持范围由上游项目维护,会随 Nixpacks 版本演进持续扩展(包括 Node.js、Python、Go、Rust、Ruby、Java 等主流生态)。具体支持清单与各语言的默认构建/启动命令,请以 Nixpacks 官方文档为准——Dokku 侧并不维护语言支持列表,而是把语言检测逻辑完全委托给 nixpacks CLI。
构建期环境变量:为何默认只在运行时可用
Nixpacks 构建有特殊的安全约束:构建阶段默认不注入应用的环境变量,只有运行时才能使用。这一设计遵循 Docker 社区关于不要在镜像构建期泄露敏感变量的建议(参见 docker/docker#13490),避免密钥、Token 等被烘焙进镜像层。
如果确实需要在 build 阶段注入自定义变量,官方推荐通过 docker-options 插件 添加构建参数:
dokku docker-options:add node-js-app build '--env NODE_ENV'
这里有个关键细节:所有由 config 插件设置的环境变量都会被自动导出到 nixpacks 构建环境中,因此 --env 只需要写键名(不带值)即可,Dokku 会把运行时配置的值注入进去:
dokku docker-options:add node-js-app build '--env NODE_ENV=production'
当然,也可以直接写成 --env KEY=VALUE 的完整形式,显式指定值。
从 builder-build 的源码可以看到,Dokku 会在调用 nixpacks 前执行 eval "$(config_export app "$APP" --merged)",将 config 插件的合并配置导出到当前环境,这正是“config 变量自动进入构建环境”的实现基础;随后 --env 参数会被解析进 NIXPACKS_ARGS 数组,透传给 nixpacks build。
自定义 nixpacks.toml 的位置
默认查找位置
nixpacks.toml 的默认查找位置取决于部署方式(见 core-post-extract 的实现逻辑):
| 部署方式 | 默认查找位置 |
|---|---|
git:from-image、git:load-image |
所生成 Docker 镜像的 WORKDIR |
其他方式(git push、git:from-archive、git:sync) |
源码树的根目录 |
monorepo 场景:指定相对路径
当从 monorepo 部署单个子应用时,nixpacks.toml 往往不在源码根目录。此时可用 nixpackstoml-path 属性为某个应用单独指定路径:
dokku builder-nixpacks:set node-js-app nixpackstoml-path .dokku/nixpacks.toml
注意事项:
- 该值始终是相对于基础搜索目录的相对路径,任何情况下都不会被当作绝对路径解析;
- 如果仓库中不存在该文件,构建将直接失败。
清除与全局默认值
传入空值即可清除(恢复默认)应用级配置:
dokku builder-nixpacks:set node-js-app nixpackstoml-path
nixpackstoml-path 也支持全局设置。全局默认值为 nixpacks.toml,当某个应用未单独设置时,使用全局值:
dokku builder-nixpacks:set --global nixpackstoml-path nixpacks2.toml
清除全局值同样传入空值:
dokku builder-nixpacks:set --global nixpackstoml-path
生效顺序与底层原理
实际生效路径的解析顺序在 internal-functions 中实现,与 report 的 computed 逻辑一致:
- 取应用级
nixpackstoml-path值;为空则 - 取全局
nixpackstoml-path值;仍为空则 - 回落到内置默认值
nixpacks.toml。
而 core-post-extract 触发器会在源码解包后把计算出的目标文件统一移动到 nixpacks.toml(若目标文件不存在则删除根目录下的 nixpacks.toml),从而保证后续 nixpacks build 始终在约定位置找到清单:
if [[ "$NEW_NIXPACKS_YML" != "nixpacks.toml" ]]; then
mv "$NEW_NIXPACKS_YML" nixpacks.toml
fi
另外,builder-nixpacks:set 命令(见 subcommands/set)只接受 nixpackstoml-path 一个合法键,传入其他键会直接报错;传入非空值写入属性,空值则删除属性。
禁用构建缓存
Nixpacks 与 Docker 一样默认启用构建缓存。需要禁用缓存时,同样借助 docker-options 插件向 build 阶段追加参数:
dokku docker-options:add node-js-app build "--no-cache"
在 builder-build 的参数解析中,--no-cache(连同 --inline-cache、--no-error-without-start)属于无值开关参数,会被原样透传给 nixpacks build。
查看 builder-nixpacks 报告
全部应用报告
dokku builder-nixpacks:report
输出示例:
=====> node-js-app builder-nixpacks information
Builder-nixpacks computed nixpackstoml path: nixpacks2.toml
Builder-nixpacks global nixpackstoml path:
Builder-nixpacks nixpackstoml path: nixpacks2.toml
=====> python-sample builder-nixpacks information
Builder-nixpacks computed nixpackstoml path: nixpacks.toml
Builder-nixpacks global nixpackstoml path:
Builder-nixpacks nixpackstoml path:
=====> ruby-sample builder-nixpacks information
Builder-nixpacks computed nixpackstoml path: nixpacks.toml
Builder-nixpacks global nixpackstoml path:
Builder-nixpacks nixpackstoml path:
三个字段的含义:
nixpackstoml-path:应用级原始值,未设置时为空;global-nixpackstoml-path:全局原始值,未设置时为空;computed-nixpackstoml-path:构建时实际生效值,依次回落到应用级 → 全局值 → 内置默认nixpacks.toml。
注意:report 触发器(src/triggers/triggers.go)与子命令(src/subcommands/subcommands.go)分别对应 report 触发与 builder-nixpacks:report 命令入口,两者最终都调用 report.go 中的 ReportSingleApp / CommandReport,字段取值逻辑与上述回退顺序完全一致。
单应用报告与按字段输出
仅查看某个应用:
dokku builder-nixpacks:report node-js-app
=====> node-js-app builder-nixpacks information
Builder-nixpacks computed nixpackstoml path: nixpacks2.toml
Builder-nixpacks global nixpackstoml path:
Builder-nixpacks nixpackstoml path: nixpacks2.toml
只输出某个字段的原始值(便于脚本化取值):
dokku builder-nixpacks:report node-js-app --builder-nixpacks-nixpackstoml-path
nixpacks2.toml
属性一览
可设置属性
| Property | Scope | Default | Report flags | Description |
|---|---|---|---|---|
nixpackstoml-path |
app + global | nixpacks.toml |
--builder-nixpacks-nixpackstoml-path、--builder-nixpacks-global-nixpackstoml-path、--builder-nixpacks-computed-nixpackstoml-path |
应用内 nixpacks.toml 清单的相对路径,供 nixpacks builder 使用 |
构建流程中的源码级细节
理解以下实现细节,有助于排查部署异常(对应实现均在 builder-build):
- 镜像标签与标签注入:构建出的镜像会打上
org.label-schema.*、com.dokku.image-stage=build、com.dokku.builder-type=nixpacks、com.dokku.app-name=$APP等标签;构建完成后还会用 builder-build.Dockerfile 二次构建,注入自定义 entrypoint 与标签。 - release 进程剔除:构建前若源码中存在
Procfile且包含release进程类型,会先将其删除(release 阶段由 builder-release 另行处理)。 - 透传的 nixpacks 参数:
docker-options中添加的构建参数会被解析为 nixpacks CLI 参数透传,覆盖--tag/-t、--install-cmd/-i、--label/-l、--build-cmd/-b、--start-cmd/-s、--pkgs/-p、--apt/-a、--env/-e、--platform、--cache-key、--incremental-cache-image、--libs、--cache-from、--docker-host、--add-host、--docker-tls-verify以及--no-cache、--inline-cache、--no-error-without-start等开关。 - release 阶段镜像标签:构建完成后,builder-release 会基于应用镜像再执行一次
docker image build(借助 builder-release.Dockerfile 的FROM $APP_IMAGE空构建),把com.dokku.image-stage=release等 release 标签注入同一镜像,供 Dokku 后续的发布与调度阶段使用。
小结
Nixpacks builder 为 Dokku 提供了一条“免 buildpack、自动推导构建命令”的部署路径。启用前请务必确认 nixpacks CLI 已安装;部署时关注 nixpacks.toml 的检测位置(monorepo 用 nixpackstoml-path 调整)、构建期环境变量只能通过 docker-options 注入、以及用 builder-nixpacks:report 核对最终生效路径这三件关键事项。结合本文给出的源码路径,可以进一步深入阅读插件的触发链与参数透传逻辑,快速定位构建期问题。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00