Dockerのマルチステージビルド

バージョン17.05以降から、Dockerはマルチステージビルドのサポートを開始しました。 このことについて誰もHabréに書いていないことに私は驚いた。 このギャップを修正しましょう。



変更は、既存の画像に基づいて画像(画像)を収集し、最小サイズを維持する必要がある場合に特に役立ちます。



Dockerイメージを収集したすべての人は、Dockerfileのほとんどすべての命令が個別のレイヤーを追加することを知っています。新しいレイヤーを追加する前に、このレイヤーからすべての不要なアーティファクトをクリアする必要があります。 したがって、真に効果的なDockerfileを作成するために、可能な限り最小のレイヤーサイズを維持するために、スクリプトやその他のロジックを使用することが従来から提案されていました。 イメージを構築する目的に応じていくつかのDockerfileを使用するのが一般的でした-デバッグ用、プロファイリング用などの特定のツールセットを備えたDEVELOPMENTファイルと、作業に必要なコンポーネントセットを備えたSTAGINGまたはPRODUCTIONにアプリケーションをデプロイするための非常に小さなイメージアプリケーション。



組み立ててテストを実行する必要がある単純な「hello world」HTTPサーバーがあり、実行可能ファイルのみを含む最小限のdockerイメージを組み立てるとします。



ここから例を見ることができます。



最小のDockerfileは次のようになります。



Dockerfile:



FROM golang:latest COPY . . RUN go test && go build ./src/main.go
      
      





イメージをビルドして実行しましょう:



 docker image build -t hello_world:build .
      
      





画像のメタデータを見ると:docker image inspect hello_world:build、6つの独立したレイヤーで構成されており、約800MBを消費していることがわかります。 そして、これは単なるHello Worldであり、実際のアプリケーションが想像できるサイズです。 したがって、PRODUCTIONでは、実行可能ファイルからのみイメージを収集することはすでに理にかなっています。



その結果、次の一連のコマンドを実行する必要があります。



ベースコンテナを起動します。



 docker container run -it --name hello_world hello_world:build
      
      





既存のコンテナに基づいて新しいコンテナを作成し、バイナリファイルをコピーします。



 docker create --name extract hello_world:build mkdir ./Production/ docker cp extract:/go/main ./Production/main docker rm -f extract docker rm -f hello_world
      
      





アプリケーションが機能するために必要なファイルのみを含むPRODUCTIONコンテナを作成します。



 docker build --no-cache -t hello_world:latest ./Production/ rm ./Production
      
      





プロセスは要件に応じて異なる場合がありますが、通常は何らかの方法でこのような手順が含まれます。



したがって、マルチステージビルドを使用すると、このプロセスを大幅に簡素化し、Dockerfile内で記述することができます。 各FROM命令は個別のベースイメージを使用でき、それぞれがドッカーイメージを組み立てる新しい段階を開始します。 ただし、主な利点は、必要なアーティファクトをあるステージから別のステージにコピーできることです。 その結果、上記のすべての手順は次のように記述できます。

Dockerfile:



 FROM golang:latest as build COPY . . RUN go build ./src/main.go FROM alpine:latest as production COPY --from=build /go/main . CMD ["./main"]
      
      





あとは、コマンドを実行するだけです。



 docker image build -t hello_world:latest .
      
      





注: FROM golang命令で指定されたエイリアス:最新のビルド-上記のCOPYの例のように--from = build / go / main。、およびCOPYインデックス--fromの両方で、前のイメージにアクセスできることを追加する価値があります= 0 / go / main。



参照:






All Articles