[docker] Dockerfile에서 조건부 복사 / 추가?

내 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



답변

이것은 현재 지원되지 않습니다 (동일한 Dockerfile이 파일의 존재에 따라 파일을 복사하거나 복사하지 않기 때문에 재현 불가능한 이미지로 이어질 것이라고 생각합니다).

이는 여전히 문제 13045 에서 와일드 카드 ” COPY foo/* bar/" not work if no file in foo“(2015 년 5 월)를 사용하여 요청 됩니다.
현재 (2015 년 7 월) Docker에서 구현되지는 않지만 bocker 와 같은 다른 빌드 도구 가이를 지원할 수 있습니다.


답변

다음은 간단한 해결 방법입니다.

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

하나 이상의 유효한 소스가 필요 foo하므로 존재 하는지 확인하십시오 COPY.

있는 경우 file-which-may-exist복사됩니다.

참고 : 복사하지 않으려는 다른 파일을 와일드 카드가 선택하지 않도록주의해야합니다. 더 조심하려면 file-which-may-exist?대신 사용할 수 있습니다 ( ?단일 문자 만 일치).

또는 더 나은 방법은 다음과 같은 문자 클래스를 사용하여 하나의 파일 만 일치시킬 수 있도록합니다.

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


답변

이 주석 에서 언급했듯이 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


답변

해결 방법

ENV 변수를 기반으로 FOLDER를 서버에 복사해야합니다. 빈 서버 이미지를 가져 왔습니다. 로컬 폴더에 필요한 배포 폴더 구조를 생성했습니다. 그런 다음 DockerFile에 줄 아래에 추가 하여 폴더를 컨테이너에 복사하십시오. 나는 고정 표시기 서버를 시작하기 전에 n은 마지막 줄에 추가 엔트리 포인트는 초기화 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;

고정 표시기-작성 선 아래 파일.

환경 :-BUILD_EVN = TEST

이러한 변경 사항은 Docker 빌드 중에 폴더를 컨테이너에 복사합니다. docker-compose up 을 실행할 때 서버가 시작되기 전에 실제 필요한 폴더를 서버에 복사하거나 배포합니다.


답변

모든 파일을 일회용 디렉토리에 복사하고 원하는 파일을 손으로 선택하고 나머지는 버립니다.

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


답변

다른 아이디어를 시도했지만 우리의 요구 사항을 충족하지 못했습니다. 아이디어는 하위 정적 웹 애플리케이션을위한 기본 nginx 이미지를 만드는 것입니다. 보안, 최적화 및 표준화 이유로, 기본 이미지는 할 수 있어야 RUN자식 이미지에 의해 추가 된 디렉토리에서 명령. 기본 이미지는 하위 이미지에 의해 추가되는 디렉토리를 제어하지 않습니다. 가정 아동 이미지가 뜻 COPY에서 자원 곳 COMMON_DEST_ROOT.

이 방법은 해킹이지만, 아이디어는 기본 이미지가 지원입니다 COPY자식 이미지를 추가 한 N에 디렉토리에 대한 지시를. ARG PLACEHOLDER_FILE그리고 ENV UNPROVIDED_DEST만족하는 데 사용됩니다 <src><dest>모든 요구 사항 COPY명령이 없습니다 필요합니다.

#
# base-image:01
#
FROM nginx:1.17.3-alpine
ENV UNPROVIDED_DEST=/unprovided
ENV COMMON_DEST_ROOT=/usr/share/nginx/html
ONBUILD ARG PLACEHOLDER_FILE
ONBUILD ARG SRC_1
ONBUILD ARG DEST_1
ONBUILD ARG SRC_2
ONBUILD ARG DEST_2
ONBUILD ENV SRC_1=${SRC_1:-PLACEHOLDER_FILE}
ONBUILD ENV DEST_1=${DEST_1:-${UNPROVIDED_DEST}}
ONBUILD ENV SRC_2=${SRC_2:-PLACEHOLDER_FILE}
ONBUILD ENV DEST_2=${DEST_2:-${UNPROVIDED_DEST}}

ONBUILD COPY ${SRC_1} ${DEST_1}
ONBUILD COPY ${SRC_2} ${DEST_2}

ONBUILD RUN sh -x \
    #
    # perform operations on COMMON_DEST_ROOT
    #
    && chown -R limited:limited ${COMMON_DEST_ROOT} \
    #
    # remove the unprovided dest
    #
    && rm -rf ${UNPROVIDED_DEST}

#
# child image
#
ARG PLACEHOLDER_FILE=dummy_placeholder.txt
ARG SRC_1=app/html
ARG DEST_1=/usr/share/nginx/html/myapp
FROM base-image:01

이 솔루션에는 PLACEHOLDER_FILE지원되는 더미 및 하드 코딩 된 수의 COPY 명령과 같은 명백한 단점이 있습니다 . 또한 COPY 명령어에 사용되는 ENV 변수를 제거 할 방법이 없습니다.


답변