Docker-이미지에서 호스트로 파일을 복사하려면 어떻게해야합니까?


117

내 질문은 컨테이너에서 호스트로 파일을 복사하는 것과 관련 있습니다. 종속성을 가져오고 소스에서 빌드 아티팩트를 컴파일하고 실행 파일을 실행하는 Dockerfile이 있습니다. 나는 또한이있어 내 경우에는 (빌드 유물을 복사 할 .zip생산 sbt dist../ 대상 /`,하지만이 문제는 또한 적용 생각에 항아리, 바이너리 등 '에

docker cp이미지가 아닌 컨테이너에서 작동합니다. 컨테이너에서 파일을 가져 오기 위해 컨테이너를 시작해야합니까? 스크립트에서 나는 /bin/bash백그라운드에서 대화 형 모드로 실행 하고 파일을 복사 한 다음 컨테이너를 죽이려고 시도했지만 이것은 kludgey처럼 보입니다. 더 좋은 방법이 있습니까?

다른 한편으로, 나는 단지 하나의 파일을 꺼내기 위해 .tar실행 한 후에 파일의 압축을 푸는 것을 피하고 싶습니다 docker save $IMAGENAME(하지만 지금은 가장 간단한 옵션 인 것처럼 보입니다).

도커 볼륨을 사용합니다. 예 :

docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.zip /out

하지만 boot2dockerOSX에서 실행 중이고 내 mac 호스트 파일 시스템에 직접 쓰는 방법을 모르겠습니다 (읽기-쓰기 볼륨이 내 boot2docker VM 내부에 마운트되어 있으므로 blah.zip이미지에서 추출 할 스크립트를 쉽게 공유 할 수 없습니다. 기타. 생각?

답변:


172

이미지에서 파일을 복사하려면 임시 컨테이너를 만들고 여기에서 파일을 복사 한 다음 삭제합니다.

id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id

고정 표시기의 어떤 버전이 있었다 create(1.01 년에 존재하지 않는) 제거 추가 명령 /
ThorSummoner

2
@ThorSummoner는 docker create, 고정 표시기 1.3에 도입 된 blog.docker.com/2014/10/...
이고르 Bukanov을

1
이것이 정답으로 선택되지 않은 이유를 모르겠습니다.
CentAu

1
확실히 정답 !!! 컨테이너 내부의 어떤 것도 의존하지 않습니다 ... Golang 스크래치 이미지의 경우 이것이 가능한 유일한 방법입니다!
Marcello de Sales

2
stdout에 복사 한 다음 로컬 파일로 보낼 이유가 있습니까? 이 작업을 수행했을 때 파일 내용 전후에 많은 제어 문자가 덤프되었습니다. docker cp $id:path > local-tar-file완벽하게 작동 하는대로 직접 실행합니다 .
Yonatan

62

불행히도 Docker 이미지에서 직접 파일을 복사하는 방법은없는 것 같습니다. 먼저 컨테이너를 만든 다음 컨테이너에서 파일을 복사해야합니다.

그러나 이미지에 cat명령이 포함 된 경우 (많은 경우에 해당) 단일 명령으로 수행 할 수 있습니다.

docker run --rm --entrypoint cat yourimage  /path/to/file > path/to/destination

이미지에이 포함되어 있지 않으면 cat컨테이너를 만들고 docker cpIgor의 대답에 제안 된대로 명령을 사용하십시오 .


1
환상적인 솔루션. 시작 후 1 초 후에 충돌이 발생하여 컨테이너에 액세스 할 수 없지만 그 안에 파일을 가져와야합니다. 이것은 완벽하게 작동했습니다.
Mirodinho

23

훨씬 빠른 옵션은 실행중인 컨테이너에서 마운트 된 볼륨으로 파일을 복사하는 것입니다.

docker run -v $PWD:/opt/mount --rm --entrypoint cp image:version /data/libraries.tgz /opt/mount/libraries.tgz

실제 0m0.446s

** VS **

docker run --rm --entrypoint cat image:version /data/libraries.tgz > libraries.tgz

실제 0m9.014s


이것은 아마도 첫 번째 예제에서 파일의 지연 / 얕은 복사를 수행하는 기본 파일 시스템 (쓰기 중 복사를 생각해보십시오)과 실제로 두 번째 예제에서 파일의 바이트를 복사하는 것과 더 관련이있을 것입니다. 유용한 테스트는 cat a >bvs cp a b가 여기에 표시된 것과 유사한 타이밍을 갖는지 확인하는 것입니다. 또한 소스 경로와 대상 경로가 서로 다른 파일 시스템에있는 경우 두 예 모두 전체 바이트 단위 복사로 이어집니다.
KevinOrr

14

부모 의견은 이미 cat 사용 방법을 보여주었습니다 . 비슷한 방식으로 tar 를 사용할 수도 있습니다 .

docker run yourimage tar -c -C /my/directory subfolder | tar x

1
이 대답은 원래 질문에서 묻는 것처럼 파일 대신 디렉토리를 복사하는 것입니다. 그러나 +1은 파일에서도 작동하며 권한 및 소유자 보존이라는 추가 기능이 제공되기 때문입니다. 큰!
caligari

5
실제로 사용합니다docker run --rm --entrypoint tar _image_ cC _img_directory_ . | tar xvC _host_directory_
caligari

6
docker cp $(docker create registry.example.com/ansible-base:latest):/home/ansible/.ssh/id_rsa ./hacked_ssh_key

한 줄 솔루션을 제공하고자

편집 : 컨테이너가이 솔루션에서 실행될 필요도 없습니다.


1

이 문제에 대한 또 다른 (짧은) 대답 :

docker run -v $PWD:/opt/mount --rm -ti image:version bash -c "cp /source/file /opt/mount/"

0

MacOS에서 boot2docker를 사용하고 있습니다. "docker cp"를 기반으로 한 스크립트는 이식 가능하다는 것을 확신 할 수 있습니다. 모든 명령은 boot2docker 내부에서 릴레이되지만 바이너리 스트림은 Mac에서 실행되는 도커 명령 줄 클라이언트로 다시 릴레이되기 때문입니다. 따라서 도커 클라이언트의 쓰기 작업은 서버 내에서 실행되고 실행중인 클라이언트 인스턴스에 다시 기록됩니다!

내가 제공하는 모든 도커 컨테이너와 도커 볼륨에 대한 백업 스크립트를 공유하고 있으며 내 백업 스크립트는 boot2docker를 사용하여 Linux 및 MacOS에서 모두 테스트됩니다. 백업은 플랫폼간에 쉽게 교환 할 수 있습니다. 기본적으로 스크립트 내에서 다음 명령을 실행하고 있습니다.

docker run --name=bckp_for_volume --rm --volumes-from jenkins_jenkins_1 -v /Users/github/jenkins/backups:/backup busybox tar cf /backup/JenkinsBackup-2015-07-09-14-26-15.tar /jenkins

새 busybox 컨테이너를 실행하고 jenkins_jenkins_1이라는 이름으로 내 jenkins 컨테이너의 볼륨을 마운트합니다. 전체 볼륨이 backups / JenkinsBackup-2015-07-09-14-26-15.tar 파일에 기록됩니다.

백업 또는 복원 스크립트를 조정하지 않고 Linux 컨테이너와 Mac 컨테이너간에 아카이브를 이미 이동했습니다. 이것이 당신이 원하는 것이라면 여기에서 전체 스크립트를 찾을 수 있습니다 : blacklabelops / jenkins


0

호스트의 로컬 경로를 컨테이너의 경로에 바인딩 한 다음 cp원하는 파일을 스크립트 끝의 해당 경로에 바인딩 할 수 있습니다.

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest

그러면 나중에 복사 할 필요가 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.