web-dev-qa-db-ja.com

Dockerは、ファイルをイメージにコミットせずにファイルを追加する方法を教えてください。

Dockerイメージに追加する約300Mbのzip形式のローカルファイルがあります。次に、次の状態で画像が抽出されます。

問題は、ADDステートメントがコミットになり、新しいファイルシステムレイヤーがイメージを必要以上に300Mb大きくすることです。

ADD /files/Apache-stratos.Zip /opt/Apache-stratos.Zip
RUN unzip -q Apache-stratos.Zip && \
    rm Apache-stratos.Zip && \
    mv Apache-stratos-* Apache-stratos

質問:コミットを行わずにローカルファイルを追加するための回避策はありますか?

1つのオプションは、単純なWebサーバーを実行することです(例:python -m SimpleHTTPServer)dockerビルドを開始する前に、wgetを使用してファイルを取得しますが、少し面倒なようです。

RUN wget http://localhost:8000/Apache-stratos.Zip && \
    unzip -q Apache-stratos.Zip && \
    rm Apache-stratos.Zip && \
    mv Apache-stratos-* Apache-stratos

もう1つのオプションは、ビルド時ではなく、コンテナーの起動時にzipファイルを抽出することですが、できるだけ早く起動を維持したいと思います。

8
Chris Snow

ドキュメント によると、アーカイブファイルをローカルファイルシステム(URLではなく)からDockerfileのADDに渡すと(パス+ファイル名ではなく宛先パスを使用)、ファイルが解凍されます指定されたディレクトリに。

<src>が認識された圧縮形式(identity、gzip、bzip2、またはxz)のローカルtarアーカイブである場合、ディレクトリとして解凍されます。リモートURLからのリソースは解凍されません。ディレクトリをコピーまたは解凍すると、tar-xと同じ動作になります。結果は次の和集合になります。

1)宛先パスに存在するもの、および2)「2」を優先して競合が解決されたソースツリーの内容。ファイルごとに。

試してください:

ADD /files/Apache-stratos.Zip /opt/

さらに解凍せずに、ファイルがそこにあるかどうかを確認します。

15
Alister Bulman

Docker 17.05+では、 multi-stage build を使用して、余分なレイヤーの作成を回避できます。

FROM ... as stage1
# No need to clean up here, these layers will be discarded
ADD /files/Apache-stratos.Zip /opt/Apache-stratos.Zip
RUN unzip -q Apache-stratos.Zip
    && mv Apache-stratos-* Apache-stratos

FROM ...
COPY --from=stage1 Apache-stratos/ Apache-stratos/
4
augurar

docker-squash を使用して、新しく作成されたレイヤーを押しつぶすことができます。これにより、画像サイズが大幅に縮小されます。

残念ながら、言及された回避策(RUN curl ... && unzip ... & rm ...、コンテナ開始時に解凍)が現時点での唯一のオプションです(docker1.11)。

2
Tomas Tomecek

現在、私が考えることができる3つのオプションがあります。


オプション1:Zipファイルからtarまたは圧縮されたtar形式に切り替えてから、ADDがファイルを解凍できるようにします。

ADD /files/Apache-stratos.tgz /opt/

唯一の欠点は、ディレクトリの名前変更などの他の変更により、書き込み時にコピーが再度トリガーされるため、tarファイルに最終的なディレクトリ構造の内容が含まれていることを確認する必要があります。


オプション2:マルチステージビルドを使用します。早い段階でファイルを抽出し、変更を実行してから、結果のディレクトリを最終段階にコピーします。これは、BuildKitを使用できないビルドエンジンに適したオプションです。 augurarの答えはこれをカバーしています だから私は彼がすでに持っているのと同じDockerfileを繰り返さないでしょう。


オプション3:BuildKit(18.09以降で使用可能)を使用すると、ビルドコンテキストを含む他の場所からRUNコマンド内でファイルをマウントできます。これには現在、実験的な構文が必要です。結果のDockerfileは次のようになります。

# syntax=docker/dockerfile:experimental
FROM ...
...
RUN --mount=type=bind,source=/files/Apache-stratos.Zip,target=/opt/Apache-stratos.Zip \
    unzip -q Apache-stratos.Zip && \
    rm Apache-stratos.Zip && \
    mv Apache-stratos-* Apache-stratos

次に、それをビルドするには、ビルドを実行する前に変数をエクスポートします(.bashrcまたは同等のものでエクスポートすることもできます)。

DOCKER_BUILDKIT=1 docker build -t your_image .

BuildKitの実験的な機能の詳細については、こちらをご覧ください: https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md

0
BMitch