🐳

buildxでDockerfileに実行と成果物まで閉じ込める

に公開

TL:DR

docker buildxで導入されたlocal exporter(公式)を使ってビルドしたイメージ内のファイルシステムをすべて取り出せる。scratchを使って、ファイルシステムを成果物だけにすれば、成果物だけ取り出せる。詳細はこちら

$ ls
main.cpp Dockerfile
$ docker buildx build -o . .
[+] Building 0.3s (10/10) FINISHED
...
$ ls
main.cpp Dockerfile main

背景

複雑なビルド方法をとるレポジトリについて、ビルド可能なスナップショットをとると同時にビルド結果を取得しようと、Dockerfileにビルド環境からビルド方法まで書いてしまって、docker image buildでビルドまで済ませてしまう手法をとっていた。

この方法だとdocker cpで結果を取り出す必要があるので、docker image buildした後、docker container create後コピーをして、最後にコンテナリソースの削除までする必要があった。しかし、docker cpする際にどこに結果があるかという前情報を調べておく必要があった。

そこで調べてみたところ、公式がこのユースケースに対するアンサーをdocker buildxという形で実装していた(参照)。podmanでも同様のコマンドが実装されているらしい。

$ ls
main.cpp Dockerfile 
$ docker buildx build -o type=local,dest=./ .
[+] Building 0.3s (10/10) FINISHED
...
$ ls
main.cpp Dockerfile main
$ rm main
$ docker buildx build -o ./out .
[+] Building 0.3s (10/10) FINISHED
...
$ ls
main.cpp Dockerfile out
$ ls ./out
main
main.cpp
#include <iostream>

int main() {
    std::cout << "Hello Docker buildx!" << std::endl;
    return 0;
}
Dockerfile
FROM gcc:13 AS builder
WORKDIR /app

COPY main.cpp .

RUN g++ -O2 -static -o main main.cpp

# 成果物だけを出力する
FROM scratch AS export-stage
COPY --from=builder /app/main /

Discussion