Docker의 빌드 컨텍스트 외부에 파일을 포함시키는 방법은 무엇입니까?
Docker 파일에서 "ADD"명령을 사용하여 Docker의 빌드 컨텍스트 외부의 파일을 어떻게 포함시킬 수 있습니까?
Docker 설명서에서 :
경로는 빌드 컨텍스트 내에 있어야합니다. 도커 빌드의 첫 번째 단계는 컨텍스트 디렉토리 (및 서브 디렉토리)를 도커 디먼에 전송하는 것이므로 ../something/something을 추가 할 수 없습니다.
이 문제에 Docker를 수용하기 위해 전체 프로젝트를 재구성하고 싶지 않습니다. 모든 Docker 파일을 동일한 하위 디렉토리에 유지하고 싶습니다.
또한 Docker가 아직 심볼릭 링크를 지원하지 않는 것으로 보입니다. Dockerfile ADD 명령은 호스트 # 1676의 심볼릭 링크를 따르지 않습니다.
내가 생각할 수있는 유일한 다른 것은 파일을 Docker 빌드 컨텍스트에 복사하는 사전 빌드 단계를 포함시키는 것입니다 (그리고 해당 파일을 무시하도록 버전 컨트롤을 구성하십시오). 그보다 더 나은 해결 방법이 있습니까?
이 문제를 해결하는 가장 좋은 방법은 -f를 사용하여 빌드 컨텍스트와 독립적으로 Dockerfile을 지정하는 것입니다.
예를 들어,이 명령은 ADD 명령에 현재 디렉토리의 모든 항목에 대한 액세스 권한을 부여합니다.
docker build -f docker-files/Dockerfile .
업데이트 : Docker는 이제 Dockerfile을 빌드 컨텍스트 외부에 허용합니다 (18.03.0-ce, https://github.com/docker/cli/pull/886에 고정 ). 그래서 당신은 또한 같은 것을 할 수 있습니다
docker build -f ../Dockerfile .
Linux에서는 다른 디렉토리를 심볼릭 링크하는 대신 마운트 할 수 있습니다
mount --bind olddir newdir
자세한 내용은 https://superuser.com/questions/842642 를 참조하십시오.
다른 OS에서 비슷한 것을 사용할 수 있는지 모르겠습니다. 또한 Samba를 사용하여 폴더를 공유하고 폴더를 Docker 컨텍스트에 다시 마운트하려고 시도했습니다.
나는 종종 --build-arg
이 목적을 위해 옵션을 사용하고 있다고 생각합니다 . 예를 들어 Dockerfile에 다음을 넣은 후 :
ARG SSH_KEY
RUN echo "$SSH_KEY" > /root/.ssh/id_rsa
당신은 할 수 있습니다 :
docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .
그러나 Docker 설명서 에서 다음 경고에 유의하십시오 .
경고 : github 키, 사용자 자격 증명 등과 같은 비밀을 전달하기 위해 빌드 시간 변수를 사용하지 않는 것이 좋습니다. 빌드 시간 변수 값은 docker history 명령으로 이미지의 모든 사용자에게 표시됩니다.
문제 2745 의 토론을 읽으면 docker는 심볼릭 링크를 지원하지 않을뿐만 아니라 컨텍스트 외부의 파일 추가를 지원하지 않을 수도 있습니다. docker 빌드에 들어가는 파일은 명시 적으로 컨텍스트의 일부이거나 고정 버전으로도 배포 된 URL에서 가져와야하므로 잘 알려진 URL 또는 파일과 함께 제공되는 파일로 빌드를 반복 할 수있는 디자인 철학 인 것 같습니다. 도커 컨테이너.
나는 버전 제어 소스 (예 : docker build -t stuff http://my.git.org/repo) 에서 빌드하는 것을 선호합니다. 그렇지 않으면 임의의 파일로 임의의 장소에서 빌드하고 있습니다.
근본적으로, ....-SvenDowideit, Docker Inc
내 의견이지만 코드와 도커 리포지토리를 분리하려면 재구성해야한다고 생각합니다. 그렇게하면 컨테이너가 일반적이며 빌드 타임이 아닌 런타임에 모든 버전의 코드를 가져올 수 있습니다.
또는 docker를 기본 코드 배포 아티팩트로 사용하고 dockerfile을 코드 리포지토리의 루트에 넣습니다. 이 경로를 사용하는 경우 더 일반적인 시스템 수준 세부 정보를위한 부모 도커 컨테이너와 코드와 관련된 설정을위한 자식 컨테이너를 갖는 것이 좋습니다.
나는 좋은 패턴을 알아 내기 위해이 시간을 보냈고이 기능 지원으로 무슨 일이 일어나고 있는지 더 잘 설명 할 수있었습니다. 설명하는 가장 좋은 방법은 다음과 같습니다.
- Dockerfile : 자체 상대 경로에서 파일 만 볼 수 있습니다
- 컨텍스트 : 공유하려는 파일과 Dockerfile이 복사 될 "공간"의 위치
그래서, 말했듯이, 여기에 파일을 재사용 해야하는 Dockerfile의 예가 있습니다. start.sh
도커 파일
그것은 ALWAYS
로 자신의 현재 디렉토리를 가진, 상대 경로에서로드됩니다 local
사용자가 지정한 경로에 대한 참조입니다.
COPY start.sh /runtime/start.sh
파일
이 아이디어를 고려하면 Dockerfile에 특정 항목을 빌드하기 위해 여러 개의 사본이 있다고 생각할 수 있지만 모두에 액세스해야합니다 start.sh
.
./all-services/
/start.sh
/service-X/Dockerfile
/service-Y/Dockerfile
/service-Z/Dockerfile
./docker-compose.yaml
이 구조와 위의 파일을 고려하면 docker-compose.yml이 있습니다.
docker-compose.yaml
- 이 예에서
shared
컨텍스트 디렉토리는runtime
디렉토리입니다.- 여기 동일한 정신 모델로,이 디렉토리 아래의 모든 파일이 소위로 이동한다고 생각하십시오
context
. - 마찬가지로 동일한 디렉토리에 복사하려는 Dockerfile을 지정하십시오. 을 사용하여 지정할 수 있습니다
dockerfile
.
- 여기 동일한 정신 모델로,이 디렉토리 아래의 모든 파일이 소위로 이동한다고 생각하십시오
- 기본 컨텐츠가있는 디렉토리는 설정 될 실제 컨텍스트입니다.
은 docker-compose.yml
다음과 같습니다
version: "3.3"
services:
service-A
build:
context: ./all-service
dockerfile: ./service-A/Dockerfile
service-B
build:
context: ./all-service
dockerfile: ./service-B/Dockerfile
service-C
build:
context: ./all-service
dockerfile: ./service-C/Dockerfile
all-service
는 컨텍스트로 설정되고 공유 파일start.sh
은 각로 지정된 Dockerfile과 함께 복사됩니다dockerfile
.- 시작 파일을 공유하여 각자 고유의 방식으로 빌드됩니다!
건배!
더 간단한 해결 방법은 '컨텍스트'자체를 변경하는 것입니다.
예를 들어, 대신 다음을 제공하십시오.
docker build -t hello-demo-app .
현재 디렉토리를 컨텍스트로 설정합니다. 부모 디렉토리를 컨텍스트로 원한다고 가정 해 봅시다.
docker build -t hello-demo-app ..
먼저 이미지에 필요한 타르볼을 만들어이를 컨텍스트로 사용할 수도 있습니다.
https://docs.docker.com/engine/reference/commandline/build/#/tarball-contexts
HIPPA 이유로 인해 repo 컨텍스트 내부로 이동할 수 없었던 프로젝트 및 일부 데이터 파일에서 이와 동일한 문제가 발생했습니다. 나는 2 개의 Dockerfile을 사용했습니다. 하나는 컨테이너 외부에서 필요한 것들없이 기본 응용 프로그램을 빌드하고 내부 저장소에 게시합니다. 그런 다음 두 번째 dockerfile은 해당 이미지를 가져 와서 데이터를 추가하고 새 이미지를 생성 한 다음 배포하고 어디에도 저장하지 않습니다. 이상적이지는 않지만 민감한 정보를 저장소에 보관하려는 목적으로 작동했습니다.
docker-compose를 사용하여 필요한 볼륨을 마운트하는 서비스를 만들고 컨테이너 이미지를 커밋 함으로써이 작업을 수행했습니다. 그런 다음 후속 서비스에서 이전에 커밋 된 이미지에 의존합니다.이 이미지에는 마운트 된 위치에 모든 데이터가 저장되어 있습니다. 그런 다음 docker commit
명령을 실행할 때 호스트 마운트 디렉토리가 커밋되지 않으므로 이러한 파일을 최종 대상으로 복사해야합니다.
이 작업을 수행하기 위해 docker-compose를 사용할 필요는 없지만 인생을 조금 더 쉽게 만듭니다.
# docker-compose.yml
version: '3'
services:
stage:
image: alpine
volumes:
- /host/machine/path:/tmp/container/path
command: bash -c "cp -r /tmp/container/path /final/container/path"
setup:
image: stage
# setup.sh
# Start "stage" service
docker-compose up stage
# Commit changes to an image named "stage"
docker commit $(docker-compose ps -q stage) stage
# Start setup service off of stage image
docker-compose up setup
참고 URL : https://stackoverflow.com/questions/27068596/how-to-include-files-outside-of-dockers-build-context
'Programing' 카테고리의 다른 글
C #에서 ==와! =를 모두 정의해야하는 이유는 무엇입니까? (0) | 2020.03.03 |
---|---|
ES6에 Symbol을 가져 오는 동기는 무엇입니까? (0) | 2020.03.03 |
"런타임"이란 무엇입니까? (0) | 2020.03.03 |
각 행마다 다른 레이아웃의 Android ListView (0) | 2020.03.03 |
파이썬 인터프리터의 전체 경로를 찾으십니까? (0) | 2020.03.03 |