Buildah 完全指南:无需 Docker Daemon 构建 OCI 镜像
什么是 Buildah
Buildah 是一个 OCI 镜像构建工具。与 Docker 最大区别:不需要 dockerd 守护进程。可以直接在用户空间构建镜像,原生支持 rootless。
Docker vs Buildah
| Docker | Buildah | |
|---|---|---|
| 需要 daemon | 必须(dockerd) | 不需要 |
| rootless | 需配置 | 原生支持 |
| Dockerfile | ✅ | ✅ (bud 子命令) |
| 多架构构建 | buildx + QEMU | --arch/--os + manifest |
| CI/CD | 需 setup-buildx-action | 一行 apt install |
| 镜像存储 | /var/lib/docker |
~/.local/share/containers/storage |
Ubuntu 安装
APT 安装(推荐)
sudo apt update
sudo apt install -y buildah
# 验证
buildah --version
安装最新版
. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" \
| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" \
| sudo apt-key add -
sudo apt update
sudo apt install -y buildah
QEMU 支持(跨架构构建)
# 安装 QEMU 用户态模拟
sudo apt install -y qemu-user-static
# 注册 binfmt
buildah info | grep -A5 'arch'
核心命令
构建容器(从零开始)
# 创建空容器
container=$(buildah from scratch)
# 或从基础镜像
buildah from alpine:latest
# 挂载容器文件系统
mnt=$(buildah mount $container)
# 写入文件
echo "hello" > $mnt/etc/motd
# 提交为镜像
buildah commit $container myimage:latest
构建镜像(Dockerfile)
buildah bud -t myapp:v1.0 .
# bud = build-using-dockerfile
支持标准 Dockerfile 指令:FROM、RUN、COPY、ENV、ARG、EXPOSE、CMD、ENTRYPOINT 等。
列出镜像
buildah images
buildah images --all
登录 Registry
buildah login docker.io -u <username> -p <password>
buildah login ghcr.io -u <username> --password-stdin
推送/拉取
# 推送
buildah push myapp:v1.0 docker://docker.io/myuser/myapp:v1.0
# 拉取
buildah pull docker.io/library/alpine:latest
多架构镜像
构建各架构
buildah bud --arch amd64 --os linux -t myapp:amd64 .
buildah bud --arch arm64 --os linux -t myapp:arm64 .
创建 Manifest List
buildah manifest create myapp:latest
buildah manifest add myapp:latest myapp:amd64
buildah manifest add myapp:latest myapp:arm64
推送多架构
# --all 推送 manifest list + 所有架构镜像
buildah manifest push --all myapp:latest docker://docker.io/myuser/myapp:latest
推送后,docker pull 会自动匹配客户端架构拉取对应镜像。
查看 Manifest
buildah manifest inspect myapp:latest
buildah manifest inspect docker.io/myuser/myapp:latest
GitHub Actions 集成
- name: Install buildah + qemu
run: |
sudo apt update
sudo apt install -y buildah qemu-user-static
- name: Build multi-arch image
run: |
buildah login docker.io -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
buildah bud --arch amd64 -t app:amd64 .
buildah bud --arch arm64 -t app:arm64 .
buildah manifest create app:latest
buildah manifest add app:latest app:amd64
buildah manifest add app:latest app:arm64
buildah manifest push --all app:latest docker://docker.io/${{ secrets.DOCKER_USERNAME }}/app:latest
Dockerfile 兼容性
标准 Dockerfile 完全兼容。不支持的特性:
| 特性 | 说明 | 替代方案 |
|---|---|---|
SHELL 指令 |
固定 /bin/sh |
用 RUN 中指定 shell |
--mount=type=cache (BuildKit) |
构建缓存挂载 | COPY + RUN 分层 |
--mount=type=secret (BuildKit) |
构建时注入密钥 | COPY --chmod + RUN 后删除 |
--network=host |
构建时网络模式 | 无直接替代 |
常用场景速查
# 从标准输入构建
echo 'FROM alpine\nRUN apk add curl' | buildah bud -t alpine-curl -
# 多阶段构建
buildah bud --target builder -t builder .
buildah bud -t final-image .
# 导出为 tar
buildah push myapp:latest docker-archive:/tmp/myapp.tar
# 本地 docker 跑
buildah push myapp:latest docker-daemon:myapp:latest
docker run myapp:latest
# 清理
buildah rm --all # 删除所有容器
buildah rmi --all # 删除所有镜像
总结
- CI 场景:比 Docker setup-buildx-action 更轻量,一行 apt install
- ROOTLESS:密钥/权限更安全
- Dockerfile 兼容:绝大部分项目无需改动
- 多架构:
--arch+manifest两个步骤搞定
