6.5. Buildah で scratch からイメージを新規作成

ベースイメージから開始する代わりに、中身がない新規コンテナーと、少数のコンテナーメタデータのみを保持する新規コンテナーを作成できます。これは、scratch コンテナーと呼ばれます。ここで、buildah コマンドを使用して、scratch コンテナーから始まるイメージを作成することを選択するときに、考慮すべきいくつかの問題があります。

  • scratch コンテナーでは、scratch イメージに依存関係のない実行ファイルをコピーして、最小コンテナーを機能させるため、いくつかの設定を行うことができます。
  • yum パッケージや rpm パッケージなどのツールを使用して、scratch コンテナーを作成するには、少なくともコンテナー内の RPM データベースを初期化し、リリースパッケージを追加する必要があります。以下の例は、実行方法を示しています。
  • たくさんの RPM パッケージを追加した場合は、scratch イメージではなく、ベースイメージの rhel または rhel-minimal を使用することを検討してください。このベースイメージには、ドキュメント、言語パック、およびその他のコンポーネントが含まれ、結果としてイメージのサイズが小さくなる可能性があります。

この例では、コンテナーに Web サービス (httpd) を追加し、これを実行するように設定します。この例では、イメージを Buildah (/var/lib/containers にローカルに保存する containers-storage) にコミットするのではなく、ローカルの Docker サービス (/var/lib/docker にローカルに格納できる docker-daemon) が管理できるように、イメージをコミットする方法を説明します。Buildah に簡単にコミットすると、Docker サービス (docker) 、ローカルの OSTree リポジトリー (ostree) 、または OCI 準拠のその他のストレージ (oci) にプッシュできます。(詳細は man buildah push コマンドを実行してください。)

まず、scratch コンテナーを作成します。

# buildah from scratch
working-container

これにより、以下のようにマウントできる空のコンテナー (イメージなし) のみが作成されます。

# scratchmnt=$(buildah mount working-container)
# echo $scratchmnt
/var/lib/containers/storage/devicemapper/mnt/cc92011e9a2b077d03a97c0809f1f3e7fef0f29bdc6ab5e86b85430ec77b2bf6/rootfs

scratch イメージで RPM データベースを初期化し、redhat-release パッケージを追加します (RPM が機能するために必要なその他のファイルが含まれます)。

# dnf install -y --releasever=8 --installroot=$scratchmnt redhat-release

httpd サービスを scratch ディレクトリーにインストールします。

# dnf install -y --setopt=reposdir=/etc/yum.repos.d \
     --installroot=$scratchmnt \
     --setopt=cachedir=/var/cache/dnf httpd

コンテナーの index.html ファイルにテキストを追加すると、後でテストできるようになります。

# echo "Your httpd container from scratch worked." > $scratchmnt/var/www/html/index.html

init サービスとして httpd を実行する代わりに、buildah config オプションをいくつか設定して、httpd デーモンをコンテナーから直接実行するオプションを設定します。

# buildah config --cmd "/usr/sbin/httpd -DFOREGROUND" working-container
# buildah config --port 80/tcp working-container
# buildah commit working-container docker-daemon:myhttpd:latest

デフォルトでは、buildah commit コマンドは、docker.io リポジトリー名をイメージ名に追加し、そのイメージをローカルの Docker サービス用のストレージ領域 (/var/lib/docker) にコピーします。現在のところ、docker コマンドを使用して、イメージ ID を使用して新しいイメージをコンテナーとして実行できます。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/myhttpd   latest              47c0795d7b0e        9 minutes ago       665.6 MB
# docker run -p 8080:80 -d --name httpd-server 47c0795d7b0e
# curl localhost:8080
Your httpd container from scratch worked.