---
title: "Buildahとは？buildah buildの使い方とrootless・Kubernetes内ビルドの設定"
url: "https://www.issoh.co.jp/tech/details/15687/"
published: 2026-07-25
updated: 2026-10-09
categories: ["Kubernetes・コンテナ"]
publisher: "株式会社一創"
---

# Buildahとは？buildah buildの使い方とrootless・Kubernetes内ビルドの設定

Buildahは、デーモンを常駐させずにOCI形式のコンテナイメージを作るLinux向けのコマンドラインツールです。最新版は1.45.1（2026年9月15日公開）で、リポジトリは2026年にGitHubの`containers/buildah`から`podman-container-tools/buildah`へ移っています。この記事では、`buildah build`の既定値と、そのままだとHEALTHCHECKが消える落とし穴、Containerfileを使わない逐次ビルド、マルチアーキテクチャのpush、GitHub ActionsとKubernetesのPod内でrootlessビルドを回す設定までを、v1.45.1のマニュアルとソースに沿って解説します。

## まとめ：Buildahの要点と使い分けの判断

Buildahは「イメージを作る」ことだけを担うツールです。Podmanがコンテナの実行と管理を、Buildahがビルドを担当し、`podman build`も内部ではBuildahのGo APIを呼んでいます。デーモンが無いので、CIのジョブごとに独立したプロセスとしてビルドでき、一般ユーザーのままでも動きます。

- `buildah build`（旧名`buildah bud`）は既存のDockerfileをそのまま読める。ただし既定のイメージ形式はOCIで、HEALTHCHECKとONBUILDは保存されない。必要なら`--format docker`を付ける
- `buildah build`は中間レイヤーのキャッシュが既定で無効（`podman build`は有効）。CIでキャッシュを使うなら`--layers`を明示し、ジョブ間でストレージを引き継がない場合はキャッシュの保存・復元も設定する
- Kubernetesやコンテナの中でビルドするなら、公式イメージ`quay.io/buildah/stable`が`BUILDAH_ISOLATION=chroot`を既定にしている。非特権で動かすには、この設定とsubuid・subgid、ストレージに加え、実行ユーザー、必要なケーパビリティ、ユーザー名前空間を許可するホスト側の設定を合わせる必要がある

採用が効くのは、共有CIやKubernetes上でビルドジョブにroot権限とDockerソケットを渡したくない場合と、RHEL・OpenShift・Podmanで道具をそろえたい場合です。開発者の手元がDocker Desktopで統一され、BuildKitのキャッシュ機能を使い込んでいるなら、置き換える理由は薄くなります。

## Buildahの仕組み：デーモンを持たないビルドとrootless

### fork-execモデルとPodmanとの役割分担

Dockerは`dockerd`という常駐デーモンにCLIが命令を送り、デーモン側でビルドします。BuildahのREADMEは自身を「シンプルなfork-execモデルで、デーモンとしては動かない」と説明しています。`buildah`コマンドを実行したプロセスがその場でレイヤーを組み立て、終わればプロセスごと消えます。デーモンが落ちて全ジョブが止まる、ソケット経由で他人のビルドに触れる、といった問題が構造上起きません。

Podmanとの関係もREADMEに明記されています。PodmanはDockerfileからのビルドにBuildahのGo APIを使い、Buildahとは独立してインストールできます。一方で「コンテナ」の意味が違い、Buildahの作業用コンテナはイメージに中身を足すための一時的なもので、Podmanの長時間動かすコンテナとは管理の仕方が違います。同じユーザーなら保存領域（containers storage）は共有されますが、通常の`podman ps`にBuildahの作業コンテナは出てこず、`podman ps --external`で初めて表示されます。Podman側の操作は[Podmanコマンド一覧と使い方](/tech/details/2845/)にまとめています。

### rootlessを支えるユーザー名前空間とsubuid・subgid

一般ユーザーでビルドできるのは、ユーザー名前空間でコンテナ内のUID 0をホストの自分のUIDに対応させ、さらに`/etc/subuid`と`/etc/subgid`に割り当てた範囲を追加のUID・GIDとして使うからです。ベースイメージのファイルは複数のUIDで所有されているので、この範囲が無いとレイヤーを正しく展開できません。

```
# 自分に割り当てられた範囲を確認（例：shichiza:100000:65536）
grep "^$(whoami):" /etc/subuid /etc/subgid

# 名前空間の中でUIDの対応表を確認する
buildah unshare cat /proc/self/uid_map
```

`buildah unshare`は、自分のUIDを0に見せた名前空間でコマンドを動かすサブコマンドです。マニュアルには、一般ユーザーの`buildah mount`は`buildah unshare`のセッション内でないと失敗すると書かれています。rootlessでの不調は、まずこの2つのファイルとuid\_mapを見ると切り分けが早く進みます。ストレージはoverlayかVFSで、Podmanのrootless文書によると一般ユーザーがカーネルのoverlayfsを直接使えるのはLinux 5.12以降です。それより古いカーネルでは低速なfuse-overlayfsに切り替わります。

### 最新版1.45.1とディストリビューションの同梱版の差

上流の最新は1.45.1ですが、OSのパッケージで入る版はかなり古いことがあります。GitHub Actionsの`ubuntu-24.04`ランナー（イメージ20260927.320.1）に入っているのは1.33.7、コンテナイメージ`quay.io/buildah/stable`の`latest`は1.43.4（2026年10月9日時点）です。マニュアルの新しいオプションが手元で通らないときは、`buildah version`で版を確かめてから読むべきページの版を合わせてください。

```
# Fedora・RHEL系
sudo dnf -y install buildah
# Ubuntu 20.10以降・Debian
sudo apt-get -y update
sudo apt-get -y install buildah

buildah version
```

公式のインストール手順はLinuxディストリビューションだけを対象にしています。macOSとWindowsにはネイティブ版が無いので、WSL2やLinuxの仮想マシンの中で使います。

## buildah buildでContainerfileからイメージを作る手順

### buildah buildの基本構文と既定値

`buildah build`は、ビルドコンテキストにある`Containerfile`または`Dockerfile`を読んでイメージを作ります。`buildah bud`は同じコマンドの旧名で、今もエイリアスとして使えます。ファイルの書き方はDockerfileと同じなので、命令の基礎は[Dockerfileの書き方と主要命令](/tech/details/3315/)がそのまま当てはまります。

```
FROM registry.access.redhat.com/ubi9/python-312
WORKDIR /opt/app-root/src
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["python", "app.py"]
```

```
# カレントディレクトリのContainerfileでビルドし、キャッシュを有効にする
buildah build --layers -t localhost/myapp:1.0 .

# ファイル名を指定する場合
buildah build -f Containerfile.prod --layers -t localhost/myapp:1.0 .

buildah images
```

Dockerから移るときに差が出やすい既定値は次の3つです。

| 項目           | buildah build の既定    | 変更方法                             |
| ------------ | -------------------- | -------------------------------- |
| イメージ形式       | oci                  | –format docker ／ BUILDAH\_FORMAT |
| 中間レイヤーのキャッシュ | 無効（false）            | –layers ／ BUILDAH\_LAYERS=true   |
| RUNの隔離方式     | oci（一般ユーザーはrootless） | –isolation ／ BUILDAH\_ISOLATION  |

キャッシュの既定は`podman build`と逆です。Podmanのマニュアルでは`--layers`の既定は`true`で、同じContainerfileでもBuildahで直接ビルドすると毎回すべてのRUNをやり直します。CIでビルド時間が急に延びたら、まず`--layers`の付け忘れを疑ってください。

### OCI形式の既定でHEALTHCHECKが消える落とし穴

Dockerから移ったときに最も気づきにくいのがこの点です。OCIのイメージ仕様には、HEALTHCHECKやONBUILDに当たる項目がありません。v1.45.1のソース（`config.go`）では、OCI形式で書き出すときにHEALTHCHECK・ONBUILD・DOMAINNAME・COMMENTを破棄し、SHELLはビルド中のRUNには使うものの保存しない、という警告を出します。

```
WARN[0000] HEALTHCHECK is not supported for OCI image format and will be ignored. Must use `docker` format
```

ビルド自体は成功するので、ログを流し見していると、Docker Composeの`depends_on: condition: service_healthy`やDockerのヘルスチェックが動かなくなってから気づきます。ヘルスチェックをイメージに持たせる設計なら、`--format docker`を付けるか、CIの環境変数で`BUILDAH_FORMAT=docker`を設定します。Kubernetesはイメージ内のHEALTHCHECKを使わず、Podのprobeで死活を判定するので、Kubernetesだけで動かすならOCI形式のままで問題ありません。

```
buildah build --format docker --layers -t localhost/myapp:1.0 .
buildah inspect --format '{{.Docker.Config.Healthcheck}}' localhost/myapp:1.0
```

## from・run・commitで組むContainerfileなしの逐次ビルド

### シェルスクリプトで1ステップずつ組む手順

Buildahならではの使い方が、Containerfileを書かずにコマンドを並べてイメージを作る方法です。`buildah from`で作業用コンテナを作り、`buildah run`で中のコマンドを実行し、`buildah copy`でファイルを入れ、`buildah config`で起動コマンドやポートを設定して、`buildah commit`でイメージに確定します。READMEのlighttpdの例を、ファイル投入を足して整理すると次のようになります。

```
#!/usr/bin/env bash
set -euo pipefail

ctr=$(buildah from registry.fedoraproject.org/fedora:latest)
trap 'buildah rm "$ctr" >/dev/null' EXIT

buildah run "$ctr" -- dnf install -y lighttpd
buildah run "$ctr" -- dnf clean all
buildah copy "$ctr" ./public /var/www/lighttpd

buildah config --port 80 \
  --cmd "/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf" \
  --label "org.opencontainers.image.source=https://example.com/repo" \
  "$ctr"

buildah commit "$ctr" localhost/lighttpd:1.0
```

Containerfileとの違いは、各ステップの間に普通のシェルの条件分岐やループ、外部コマンドの結果を挟める点です。たとえば環境ごとに入れるパッケージを変える、ビルド中に生成した設定ファイルをテンプレートから作る、といった処理をビルド引数の工夫なしで書けます。逆に、手順が直線的ならContainerfileのほうが他の道具でも読めるので、逐次ビルドは「分岐が要るときだけ」に限るのが無難です。

### scratchとbuildah mountで最小イメージを作る方法

`buildah from scratch`は空のイメージから作業コンテナを作ります。`buildah mount`でそのルートファイルシステムをホスト側にマウントすれば、ホストの`dnf`で`--installroot`を指定して、パッケージマネージャーを含まないイメージを作れます。一般ユーザーで動かす場合、mountは`buildah unshare`の中で実行する必要があります。

```
buildah unshare bash -c '
  set -e
  ctr=$(buildah from scratch)
  mnt=$(buildah mount "$ctr")
  dnf -y install --installroot="$mnt" --use-host-config --setopt install_weak_deps=False coreutils-single
  dnf -y clean all --installroot="$mnt"
  buildah config --cmd "/usr/bin/ls -l /" "$ctr"
  buildah commit "$ctr" localhost/minimal:1.0
  buildah umount "$ctr"
'
```

この例は、ホストのdnfコマンドがDNF5であり、ホストのリポジトリ設定を使ってイメージを作る構成を前提とします。別ディストリビューションのルートファイルシステムを作る場合は、対象のリポジトリ、リリース番号、署名鍵などを別途設定する必要があり、この例の対象外です。単にイメージを小さくしたいだけなら、マルチステージビルドのContainerfileで十分なことが多いでしょう。

## buildah pushとマルチアーキテクチャのイメージ配信

### buildah loginとpushでレジストリへ送る手順

作ったイメージは`buildah push`でレジストリへ送ります。宛先には`docker://`（レジストリ）、`oci:`（OCIレイアウトのディレクトリ）、`dir:`などの転送先を書けます。認証は`buildah login`で、CIでは`--password-stdin`を使ってパスワードをコマンドラインに残さないようにします。

```
echo "$REGISTRY_PASSWORD" | buildah login -u "$REGISTRY_USER" --password-stdin quay.io
buildah push localhost/myapp:1.0 docker://quay.io/example/myapp:1.0
```

push先をどこにするかは、アクセス制御と運用費に効きます。候補の比較は[コンテナレジストリの種類と選び方](/tech/details/13259/)を参照してください。

### –platformと–manifestで複数アーキテクチャをまとめる方法

`--platform`は複数回指定するか、カンマ区切りで並べられます。マニュアルは、複数のプラットフォームを指定するときは`--tag`ではなく`--manifest`を使うよう指示しています。できたマニフェストリストは`buildah manifest push`で送り、各アーキテクチャのイメージも一緒に送るかどうかを決める`--all`は既定で`true`です。

```
buildah build --platform linux/amd64,linux/arm64 --manifest localhost/myapp:1.0 .
buildah manifest inspect localhost/myapp:1.0
buildah manifest push localhost/myapp:1.0 docker://quay.io/example/myapp:1.0
```

ホストと違うアーキテクチャのRUNを実行するには、`qemu-user-static`などのエミュレーターをホストに入れておく必要があります。マニュアル自身が「可能ならネイティブのアーキテクチャでビルドするほうがよい」と書いているとおり、エミュレーションではコンパイルを伴うRUNが大幅に遅くなります。arm64のランナーを用意できるなら、アーキテクチャごとに別ジョブでビルドして最後にマニフェストを組むほうが速く終わります。

## Podman・Docker（BuildKit）とのビルドの違い

3つとも同じContainerfileを読めますが、ビルドを動かす仕組みと既定値が違います。

| 観点                     | buildah build | podman build   | docker build（BuildKit） |
| ---------------------- | ------------- | -------------- | ---------------------- |
| 常駐デーモン                 | なし            | なし             | dockerd（BuildKit内蔵）    |
| ビルドの実装                 | Buildah本体     | BuildahのGo API | BuildKit               |
| レイヤーキャッシュ既定            | 無効            | 有効             | 有効                     |
| 既定のイメージ形式              | OCI           | OCI            | Docker互換               |
| Dockerfile命令に対応する専用CLI | あり            | なし             | なし                     |
| 常用コンテナの起動・管理           | 対象外           | 可能             | 可能                     |

手元で動かしてビルドもするならPodmanで足ります。Buildahを直接使う理由は、逐次ビルドが要る場合と、実行機能を持たないビルド専用の道具をCIに置きたい場合です。DockerとPodmanの違いは[Podmanとdockerの違い](/tech/details/13202/)で詳しく扱っています。Buildahのリモートキャッシュは`--cache-to`・`--cache-from`でレジストリのリポジトリを保存先に指定する方式です。GitHub Actionsのキャッシュやローカルディレクトリなど、レジストリ以外の保存先へキャッシュを書き出したい場合は、それらの保存先を備えるBuildKitと比べて決めてください。BuildKitの仕組みは[BuildKitとは](/tech/details/15701/)で解説しています。

## CIとKubernetesでrootlessビルドを回す設定

### GitHub Actionsのubuntu-24.04でBuildahを使う設定

GitHub Actionsの`ubuntu-24.04`ランナーにはBuildah・Podman・Skopeoが最初から入っており、追加のセットアップなしで使えます。同じGitHubホストランナーでも、軽量な`ubuntu-slim`にはコンテナ関連のツールが入っていない点は[GitHub Actionsのubuntu-slimとは](/tech/details/9661/)で整理しています。

```
name: build-image
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-24.04
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v7
      - name: Build
        run: |
          IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}:${GITHUB_SHA::7}
          echo "IMAGE=$IMAGE" >> "$GITHUB_ENV"
          buildah version
          buildah build --layers --format docker -t "$IMAGE" .
      - name: Push
        run: |
          echo "${{ secrets.GITHUB_TOKEN }}" | buildah login -u "${{ github.actor }}" --password-stdin ghcr.io
          buildah push "$IMAGE"
```

`${GITHUB_REPOSITORY,,}`はbashの小文字化で、GitHub Container Registryがリポジトリ名に大文字を受け付けないことへの対策です。ランナーのBuildahは1.33.7と古いので、新しい版で入ったオプションを使うと失敗します。ランナー同梱版より新しい版が必要なら、必要な版を含むイメージを選び、ジョブコンテナ内でのユーザー名前空間・ストレージ・権限の設定も確認してください。Docker前提でワークフローを組む場合の設計は[GitHub ActionsでDockerイメージをビルドする](/tech/details/16943/)と比べてください。

### Kubernetes・OpenShiftのPod内でビルドする設定

Pod内でのビルドは、Dockerソケットのマウントや特権コンテナを避けたいときにBuildahが選ばれる典型的な場面です。公式イメージ`quay.io/buildah/stable`のContainerfileでは、UID 1000相当の`build`ユーザーとsubuid・subgidの範囲が用意され、`ENV BUILDAH_ISOLATION=chroot`でRUNの隔離方式がchrootに設定されています。コンテナの中ではOCIランタイム（runc）での入れ子の隔離が動かないことが多いため、この既定が要になります。

[Buildahの公式チュートリアル5](https://github.com/podman-container-tools/buildah/blob/main/docs/tutorials/05-openshift-rootless-build.md)は、OpenShift 4.16とBuildah 1.36.0で動作確認したrootlessビルドの構成を載せています。公式イメージをそのまま使うのではなく、次のような派生イメージを作るのが出発点です。

```
# チュートリアルの検証版。新しいタグへ替える場合は自環境で動作を確かめる
FROM quay.io/buildah/stable:v1.36.0

RUN touch /etc/subgid /etc/subuid \
 && chmod g=u /etc/subgid /etc/subuid /etc/passwd \
 && echo build:10000:65536 > /etc/subuid \
 && echo build:10000:65536 > /etc/subgid

# rootlessではrunc既定の隔離が動かないためchrootを使う
RUN echo "export BUILDAH_ISOLATION=chroot" >> /home/build/.bashrc

# ストレージにoverlayを使う
RUN mkdir -p /home/build/.config/containers \
 && (echo '[storage]';echo 'driver = "overlay"') > /home/build/.config/containers/storage.conf

USER build
WORKDIR /home/build
CMD ["python3", "-m", "http.server"]
```

このイメージをクラスタ内のレジストリへpushし、ビルド専用のサービスアカウント`buildah-sa`を作って`oc adm policy add-scc-to-user anyuid -z buildah-sa`で`anyuid` SCCを割り当てます。チュートリアルの説明では、`anyuid`が標準の`restricted` SCCに対して足すCAP\_KILL・CAP\_SETGID・CAP\_SETUIDのうち、ビルド中に別UIDでコマンドを動かすのに必要なのはSETGIDとSETUIDの2つです。Pod側では、ストレージを`emptyDir`のボリュームに置くことでoverlayを使えるようにしています。

```
spec:
  serviceAccount: buildah-sa
  containers:
    - name: buildah
      image: image-registry.openshift-image-registry.svc:5000/image-build/buildah
      securityContext:
        capabilities:
          drop:
            - KILL
      volumeMounts:
        - name: containersstorage
          mountPath: /home/build/.local/share/containers/storage
  volumes:
    - name: containersstorage
      emptyDir:
        medium: ""
```

上はチュートリアルのReplicationControllerからPodテンプレートの部分を抜き出したものです。公式イメージを加工せずに使い、fuse-overlayfsで動かす場合は、ホストの`/dev/fuse`をコンテナに渡す必要があります。イメージのREADMEにも、`fuse: device not found`が出たらホストで`modprobe fuse`を実行するよう書かれています。OpenShift以外のKubernetesクラスタでは、Pod Security Admissionの`restricted`プロファイルが全ケーパビリティの削除を求めるので、ビルド用の名前空間だけ`baseline`にする、ノード側でユーザー名前空間の作成を許可する、といった調整が別途必要です。Podを動かすランタイム側の仕組みは[runcとは](/tech/details/15695/)と[CRI-Oとは](/tech/details/15683/)で確認できます。

## Buildahを採用すべき場面と見送るべき場面

Buildahが投資に見合うのは、ビルドの権限を絞ることに具体的な利益がある組織です。次のどれかに当てはまるなら導入を検討してください。

- 共有のCIサーバーやKubernetesクラスタで、ビルドジョブにDockerソケットやrootを渡している
- RHEL・OpenShift・Podmanが本番の基盤で、ビルドの道具も同じ系統にそろえたい
- 条件分岐や外部処理を挟むビルドがあり、Containerfileとビルド引数だけでは書きにくくなっている

反対に、開発者の端末がDocker Desktopで統一され、BuildKitのキャッシュやsecretマウントを使い込んでいる組織が「デーモンレスだから」という理由だけで乗り換えると、既定値の違い（キャッシュ無効・OCI形式）でビルドが遅くなり、ヘルスチェックが消えるといった事故を抱えます。手元はDocker、CIだけBuildahと混在させる場合は、イメージ形式の差を確認せずに移行すると、必要な設定が保存されないおそれがあります。移すならCIから始め、`--layers`と`--format`を明示したうえで、できたイメージを`buildah inspect`で旧イメージと比べてから広げてください。CIとコンテナ基盤の権限設計をまとめて見直す場合は、[AWS・Google Cloud・Azureのインフラ構築](/service/system/aws/)でもご相談を受けています。

## Buildahについてよくある質問

### buildah budとbuildah buildは違うコマンドですか？

同じコマンドです。`bud`は「build-using-dockerfile」の略で、現在の正式名は`buildah build`です。マニュアルの書式欄に両方が並んでおり、オプションも挙動も同じです。

### Buildahで作ったイメージはDockerで動きますか？

動きます。既定のOCI形式もDockerで実行できます。ただしHEALTHCHECKやONBUILDはOCI形式では保存されないので、Dockerでヘルスチェックを使うなら`--format docker`でビルドしてください。

### BuildahとBuildKitはどちらを選べばよいですか？

Dockerを使い続けてキャッシュやsecretの機能を活かすならBuildKit、デーモンとroot権限を外したCIやPod内ビルドを作りたいならBuildahです。速さではなく、ビルドジョブにどこまで権限を渡せるかで決めるのが実務的です。

### Kubernetesの中でBuildahを使うと特権コンテナが必要ですか？

必須ではありません。`BUILDAH_ISOLATION=chroot`、subuid・subgidの範囲、ストレージ用のボリュームに加え、非rootユーザーでの実行と、ユーザー名前空間・ストレージ操作を許可するホスト側の設定が必要です。ケーパビリティはCAP\_SETUIDとCAP\_SETGIDが要り、OpenShiftでは`anyuid` SCCなどでこれを許可します。

### macOSやWindowsでBuildahは使えますか？

ネイティブ版はありません。公式のインストール手順はLinuxディストリビューションのみです。WSL2やLinuxの仮想マシンにインストールするか、Podman Desktopの仮想マシンで`podman build`を使えば、同じBuildahのビルド処理を利用できます。

## 関連記事

- [Podmanとdockerの違いは？デーモンレス・rootlessの仕組みと移行判断](/tech/details/13202/)
- [BuildKitとは｜Dockerの新ビルドバックエンドの仕組み・キャッシュ/secret/マルチアーキと採用判断を実装者目線で解説](/tech/details/15701/)
- [GitHub ActionsでDockerイメージをビルドする｜push先とキャッシュ・マルチアーキの設計](/tech/details/16943/)
- [コンテナレジストリとは？種類・選び方から企業の導入判断まで解説](/tech/details/13259/)
- [Dockerfileとは｜書き方・主要命令・ベストプラクティスを解説【2026年版】](/tech/details/3315/)

---

出典: [Buildahとは？buildah buildの使い方とrootless・Kubernetes内ビルドの設定](<https://www.issoh.co.jp/tech/details/15687/>)（株式会社一創）
