web-dev-qa-db-ja.com

Dockerfileの条件付きCOPY / ADD?

Dockerfilesの内部で、ファイルが存在する場合、そのファイルをイメージにコピーしたいのですが、pipのrequirements.txtファイルは良い候補のようですが、これをどのように達成しますか?

COPY (requirements.txt if test -e requirements.txt; fi) /destination
...
RUN  if test -e requirements.txt; then pip install -r requirements.txt; fi

または

if test -e requirements.txt; then
    COPY requiements.txt /destination;
fi
RUN  if test -e requirements.txt; then pip install -r requirements.txt; fi
74
derrend

これは現在サポートされていません(同じDockerfileがその存在に応じてファイルをコピーするかしないので、再現できないイメージにつながると思うので)。

issue 13045 では、ワイルドカード「COPY foo/* bar/" not work if no file in foo」(2015年5月)を使用して、これが引き続き要求されます。
現在(2015年7月)Dockerには実装されていませんが、bockerのような別のビルドツールでこれをサポートできます。

18
VonC

簡単な回避策は次のとおりです。

COPY foo file-which-may-exist* /target

fooには少なくとも1つの有効なソースが必要なので、COPYが存在することを確認してください。

file-which-may-existが存在する場合、それもコピーされます。

注:ワイルドカードが、コピーする予定のない他のファイルをピックアップしないように注意する必要があります。もっと注意するために、代わりにfile-which-may-exist?を使用できます(?は1文字に一致します)。

または、さらに良いことに、このような文字クラスを使用して、1つのファイルのみが一致するようにします。

COPY foo file-which-may-exis[t] /target
56
jdhildeb

このコメント で述べたように、Santhosh Hirekerurの答えはまだファイルをコピーします。真の条件付きコピーをアーカイブするには、この方法を使用できます。

ARG BUILD_ENV=copy

FROM Alpine as build_copy
ONBUILD COPY file /file

FROM Alpine as build_no_copy
ONBUILD RUN echo "I don't copy"

FROM build_${BUILD_ENV}
# other stuff

ONBUILD命令により、BUILD_ENVによって「ブランチ」が選択されている場合にのみファイルがコピーされます。 docker buildを呼び出す前に、小さなスクリプトを使用してこの変数を設定します

9
Siyu

ソリューションを回避する

ENV変数に基づいてFOLDERをサーバーにコピーする必要がありました。空のサーバーイメージを撮影しました。ローカルフォルダーに必要な展開フォルダー構造を作成しました。次に、以下の行をDockerFileに追加し、フォルダーをコンテナーにコピーします。 I n最後の行は、Dockerがサーバーを起動する前にinit file.shを実行するエントリポイントを追加しました。

#below lines added to integrate testing framework
RUN mkdir /mnt/conf_folder
ADD install /mnt/conf_folder/install
ADD install_test /mnt/conf_folder/install_test
ADD custom-init.sh /usr/local/bin/custom-init.sh
ENTRYPOINT ["/usr/local/bin/custom-init.sh"]

次に、ローカルにcustom-init.shファイルを作成し、次のようなスクリプトを使用します。

#!/bin/bash
if [ "${BUILD_EVN}" = "TEST" ]; then
    cp -avr /mnt/conf_folder/install_test/* /mnt/wso2das-3.1.0/
else
    cp -avr /mnt/conf_folder/install/* /mnt/wso2das-3.1.0/
fi;

docker-compose以下のファイル。

環境:-BUILD_EVN = TEST

これらの変更は、Dockerビルド中にフォルダーをコンテナーにコピーします。 docker-compose upを実行すると、サーバーが起動する前に実際の必要なフォルダーをサーバーにコピーまたはデプロイします。

6

すべてのファイルを使い捨てのディレクトリにコピーし、必要なファイルを選択して、残りを破棄します。

COPY . /throwaway
RUN cp /throwaway/requirements.txt . || echo 'requirements.txt does not exist'
RUN rm -rf /throwaway

ビルドステージを使用して同様のことを実現できます。ビルドステージは、同じソリューションに依存し、cpを使用して条件付きでコピーします。ビルドステージを使用することにより、最終イメージには最初のCOPYのすべてのコンテンツが含まれなくなります。

FROM Alpine as copy_stage
COPY . .
RUN mkdir /dir_for_maybe_requirements_file
RUN cp requirements.txt /dir_for_maybe_requirements_file &>- || true

FROM Alpine
# Must copy a file which exists, so copy a directory with maybe one file
COPY --from=copy_stage /dir_for_maybe_requirements_file /
RUN cp /dir_for_maybe_requirements_file/* . &>- || true
CMD sh
1
cdosborn