etc./StackOverFlow

Docker: Docker 컨테이너에서 호스트로 파일 복사

청렴결백한 만능 재주꾼 2021. 11. 29. 22:34
반응형

질문자 :user2668128


에이전트 자체에 모든 런타임 및 라이브러리를 설치할 필요가 없도록 Docker를 사용하여 CI(지속적 통합) 서버에 대한 종속성을 구축할 생각입니다.

이를 달성하려면 컨테이너 내부에 빌드된 빌드 아티팩트를 호스트로 다시 복사해야 합니다. 그게 가능합니까?



컨테이너에서 호스트로 파일을 복사하려면 다음 명령을 사용할 수 있습니다.

 docker cp <containerId>:/file/path/within/container /host/path/target

다음은 예입니다.

 $ sudo docker cp goofy_roentgen:/out_read.jpg .

여기 goofy_roentgen 은 다음 명령에서 얻은 컨테이너 이름입니다.

 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1b4ad9311e93 bamos/openface "/bin/bash" 33 minutes ago Up 33 minutes 0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp goofy_roentgen

Container ID (일부)를 사용할 수도 있습니다. 다음 명령은 첫 번째 명령과 동일합니다.

 $ sudo docker cp 1b4a:/out_read.jpg .

creack

docker run 을 사용할 필요가 없습니다.

docker create 할 수 있습니다.

문서에서 :

docker create 명령은 지정된 이미지 위에 쓰기 가능한 컨테이너 계층을 만들고 지정된 명령을 실행할 수 있도록 준비합니다. 그런 다음 컨테이너 ID가 STDOUT 인쇄됩니다. 컨테이너가 시작되지 않는다는 점을 제외하고는 docker run -d 와 유사합니다.

따라서 다음을 수행할 수 있습니다.

 docker create -ti --name dummy IMAGE_NAME bash docker cp dummy:/path/to/file /dest/to/file docker rm -f dummy

여기서는 컨테이너를 시작하지 않습니다. 그것은 나에게 유익해 보였다.


Ishan Bhatt

"볼륨"을 마운트하고 거기에 아티팩트를 복사하십시오.

 mkdir artifacts docker run -i -v ${PWD}/artifacts:/artifacts ubuntu:14.04 sh << COMMANDS # ... build software here ... cp <artifact> /artifacts # ... copy more artifacts into `/artifacts` ... COMMANDS

그런 다음 빌드가 완료되고 컨테이너가 더 이상 실행되지 않으면 빌드에서 호스트 artifacts

편집하다

주의 사항: 이렇게 하면 현재 실행 중인 사용자의 사용자 ID와 일치하는 도커 사용자의 사용자 ID에 문제가 발생할 수 있습니다. 즉, /artifacts 의 파일은 도커 컨테이너 내부에서 사용되는 사용자의 UID와 함께 사용자가 소유한 것으로 표시됩니다. 이 문제를 해결하는 방법은 호출하는 사용자의 UID를 사용하는 것입니다.

 docker run -i -v ${PWD}:/working_dir -w /working_dir -u $(id -u) \ ubuntu:14.04 sh << COMMANDS # Since $(id -u) owns /working_dir, you should be okay running commands here # and having them work. Then copy stuff into /working_dir/artifacts . COMMANDS

djhaskin987

TLDR;

 $ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF chown $(id -u):$(id -g) my-artifact.tar.xz cp -a my-artifact.tar.xz /host-volume EOF

설명

호스트 볼륨으로 docker run chown , 아티팩트를 cp :

 $ docker build -t my-image - <<EOF > FROM busybox > WORKDIR /workdir > RUN touch foo.txt bar.txt qux.txt > EOF Sending build context to Docker daemon 2.048kB Step 1/3 : FROM busybox ---> 00f017a8c2a6 Step 2/3 : WORKDIR /workdir ---> Using cache ---> 36151d97f2c9 Step 3/3 : RUN touch foo.txt bar.txt qux.txt ---> Running in a657ed4f5cab ---> 4dd197569e44 Removing intermediate container a657ed4f5cab Successfully built 4dd197569e44 $ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF chown -v $(id -u):$(id -g) *.txt cp -va *.txt /host-volume EOF changed ownership of '/host-volume/bar.txt' to 10335:11111 changed ownership of '/host-volume/qux.txt' to 10335:11111 changed ownership of '/host-volume/foo.txt' to 10335:11111 'bar.txt' -> '/host-volume/bar.txt' 'foo.txt' -> '/host-volume/foo.txt' 'qux.txt' -> '/host-volume/qux.txt' $ ls -n total 0 -rw-r--r-- 1 10335 11111 0 May 7 18:22 bar.txt -rw-r--r-- 1 10335 11111 0 May 7 18:22 foo.txt -rw-r--r-- 1 10335 11111 0 May 7 18:22 qux.txt

이 트릭은 heredocchown $(id -u):$(id -g) 값을 가져오기 때문에 작동합니다. 즉, 도커 호스트.

이점은 다음과 같습니다.

  • docker container run --name 또는 docker container create --name 전에 할 필요가 없습니다.
  • docker container rm 을 도커 할 필요가 없습니다.

rubicks

볼륨 마운트, 아티팩트 복사, 소유자 ID 및 그룹 ID 조정:

 mkdir artifacts docker run -i --rm -v ${PWD}/artifacts:/mnt/artifacts centos:6 /bin/bash << COMMANDS ls -la > /mnt/artifacts/ls.txt echo Changing owner from \$(id -u):\$(id -g) to $(id -u):$(id -g) chown -R $(id -u):$(id -g) /mnt/artifacts COMMANDS

$(id -u) 와 같은 명령 중 일부는 백슬래시이므로 컨테이너 내에서 처리되지만 백슬래시가 아닌 명령은 명령이 전송되기 전에 호스트 시스템에서 실행 중인 셸에서 처리됩니다. 컨테이너에.


Dimchansky

docker cp 가 작동하기 전에 컨테이너가 실행되어야 함을 나타내지 않습니다.

 docker build -t IMAGE_TAG . docker run -d IMAGE_TAG CONTAINER_ID=$(docker ps -alq) # If you do not know the exact file name, you'll need to run "ls" # FILE=$(docker exec CONTAINER_ID sh -c "ls /path/*.zip") docker cp $CONTAINER_ID:/path/to/file . docker stop $CONTAINER_ID

cmcginty

실행 중인 컨테이너가 없고 이미지만 있고 텍스트 파일만 복사하려는 경우 다음과 같이 할 수 있습니다.

 docker run the-image cat path/to/container/file.txt > path/to/host/file.txt

cancerbero

Docker 19.03이 출시되면 컨테이너 생성과 이미지 빌드를 건너뛸 수 있습니다. BuildKit 기반 빌드에는 출력 대상을 변경하는 옵션이 있습니다. 이것을 사용하여 이미지가 아닌 로컬 디렉토리에 빌드 결과를 쓸 수 있습니다. 예를 들어 다음은 go 바이너리 빌드입니다.

 $ ls Dockerfile go.mod main.go $ cat Dockerfile FROM golang:1.12-alpine as dev RUN apk add --no-cache git ca-certificates RUN adduser -D appuser WORKDIR /src COPY . /src/ CMD CGO_ENABLED=0 go build -o app . && ./app FROM dev as build RUN CGO_ENABLED=0 go build -o app . USER appuser CMD [ "./app" ] FROM scratch as release COPY --from=build /etc/passwd /etc/group /etc/ COPY --from=build /src/app /app USER appuser CMD [ "/app" ] FROM scratch as artifact COPY --from=build /src/app /app FROM release

위의 Dockerfile에서 내보내려는 파일만 포함하는 artifact 그리고 새로 도입된 --output 플래그를 사용하면 이미지 대신 로컬 디렉토리에 쓸 수 있습니다. 이것은 19.03과 함께 제공되는 BuildKit 엔진으로 수행해야 합니다.

 $ DOCKER_BUILDKIT=1 docker build --target artifact --output type=local,dest=. . [+] Building 43.5s (12/12) FINISHED => [internal] load build definition from Dockerfile 0.7s => => transferring dockerfile: 572B 0.0s => [internal] load .dockerignore 0.5s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/golang:1.12-alpine 0.9s => [dev 1/5] FROM docker.io/library/golang:1.12-alpine@sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0 22.5s => => resolve docker.io/library/golang:1.12-alpine@sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0 0.0s => => sha256:1ec62c064901392a6722bb47a377c01a381f4482b1ce094b6d28682b6b6279fd 155B / 155B 0.3s => => sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0 1.65kB / 1.65kB 0.0s => => sha256:2ecd820bec717ec5a8cdc2a1ae04887ed9b46c996f515abc481cac43a12628da 1.36kB / 1.36kB 0.0s => => sha256:6a17089e5a3afc489e5b6c118cd46eda66b2d5361f309d8d4b0dcac268a47b13 3.81kB / 3.81kB 0.0s => => sha256:89d9c30c1d48bac627e5c6cb0d1ed1eec28e7dbdfbcc04712e4c79c0f83faf17 2.79MB / 2.79MB 0.6s => => sha256:8ef94372a977c02d425f12c8cbda5416e372b7a869a6c2b20342c589dba3eae5 301.72kB / 301.72kB 0.4s => => sha256:025f14a3d97f92c07a07446e7ea8933b86068d00da9e252cf3277e9347b6fe69 125.33MB / 125.33MB 13.7s => => sha256:7047deb9704134ff71c99791be3f6474bb45bc3971dde9257ef9186d7cb156db 125B / 125B 0.8s => => extracting sha256:89d9c30c1d48bac627e5c6cb0d1ed1eec28e7dbdfbcc04712e4c79c0f83faf17 0.2s => => extracting sha256:8ef94372a977c02d425f12c8cbda5416e372b7a869a6c2b20342c589dba3eae5 0.1s => => extracting sha256:1ec62c064901392a6722bb47a377c01a381f4482b1ce094b6d28682b6b6279fd 0.0s => => extracting sha256:025f14a3d97f92c07a07446e7ea8933b86068d00da9e252cf3277e9347b6fe69 5.2s => => extracting sha256:7047deb9704134ff71c99791be3f6474bb45bc3971dde9257ef9186d7cb156db 0.0s => [internal] load build context 0.3s => => transferring context: 2.11kB 0.0s => [dev 2/5] RUN apk add --no-cache git ca-certificates 3.8s => [dev 3/5] RUN adduser -D appuser 1.7s => [dev 4/5] WORKDIR /src 0.5s => [dev 5/5] COPY . /src/ 0.4s => [build 1/1] RUN CGO_ENABLED=0 go build -o app . 11.6s => [artifact 1/1] COPY --from=build /src/app /app 0.5s => exporting to client 0.1s => => copying files 10.00MB 0.1s

빌드가 완료된 후 app 바이너리를 내보냈습니다.

 $ ls Dockerfile app go.mod main.go $ ./app Ready to receive requests on port 8080

Docker에는 업스트림 BuildKit 리포지토리에 문서화된 --output 플래그에 대한 다른 옵션이 있습니다 . https://github.com/moby/buildkit#output


BMitch

Mac용 Docker를 사용하는 사람을 위해 이 글을 게시합니다. 이것이 나를 위해 일한 것입니다.

 $ mkdir mybackup # local directory on Mac $ docker run --rm --volumes-from <containerid> \ -v `pwd`/mybackup:/backup \ busybox \ cp /data/mydata.txt /backup

-v 를 사용하여 마운트하면 backup 디렉토리가 자동으로 생성됩니다.

나는 이것이 언젠가 누군가에게 유용하기를 바랍니다. :)


Paul

이 명령과 함께 PowerShell(관리자)을 사용했습니다.

 docker cp {container id}:{container path}/error.html C:\\error.html

예시

 docker cp ff3a6608467d:/var/www/app/error.html C:\\error.html

Khachornchit Songsaen

docker run -dit --rm IMAGE docker cp CONTAINER:SRC_PATH DEST_PATH

https://docs.docker.com/engine/reference/commandline/run/ https://docs.docker.com/engine/reference/commandline/cp/


shuaihanhungry

실행 중인 컨테이너 대신 이미지 에서 파일을 가져오려는 경우 다음을 수행할 수 있습니다.

docker run --rm <image> cat <source> > <local_dest>

이것은 컨테이너를 불러오고 새 파일을 작성한 다음 컨테이너를 제거합니다. 그러나 한 가지 단점은 파일 권한과 수정 날짜가 유지되지 않는다는 것입니다.


s g

또 다른 좋은 옵션은 먼저 컨테이너를 빌드한 다음 쉘 인터프리터와 함께 -c 플래그를 사용하여 실행하여 일부 commads를 실행하는 것입니다.

 docker run --rm -i -v <host_path>:<container_path> <mydockerimage> /bin/sh -c "cp -r /tmp/homework/* <container_path>"

위의 명령은 다음을 수행합니다.

-i = 대화형 모드에서 컨테이너 실행

--rm = 실행 후 컨테이너를 제거했습니다.

-v = 호스트 경로에서 컨테이너 경로로 폴더를 볼륨으로 공유했습니다.

마지막으로 /bin/sh -c 명령을 매개변수로 도입하면 해당 명령이 숙제 파일을 컨테이너 경로에 복사합니다.

이 추가 답변이 도움이 되기를 바랍니다.


Yor Jaggy

보다 일반적인 솔루션 으로 Jenkins가 Docker 컨테이너 내부에 빌드할 수 있는 CloudBees 플러그인이 있습니다 . Docker 레지스트리에서 사용할 이미지를 선택하거나 빌드 및 사용할 Dockerfile을 정의할 수 있습니다.

작업 공간을 컨테이너에 볼륨으로 탑재하고(적절한 사용자 포함), 작업 디렉터리로 설정하고, 요청한 모든 명령을 수행합니다(컨테이너 내부). image.inside() {} 명령과 함께 docker-workflow 플러그인(UI보다 코드를 선호하는 경우)을 사용할 수도 있습니다.

기본적으로 이 모든 것이 CI/CD 서버에 구운 다음 일부입니다.


BobMcGee

docker cp containerId:source_path destination_path

docker ps -a 명령에서 얻을 수 있습니다.

소스 경로는 절대 경로여야 합니다. 예를 들어 애플리케이션/서비스 디렉토리가 도커 컨테이너의 앱에서 시작하는 경우 경로는 /app/some_directory/file이 됩니다.

예: docker cp d86844abc129:/app/server/output/server-test.png C:/Users/someone/Desktop/output


Ashish Kirodian

호스트 시스템(컨테이너 외부)에 데이터 디렉토리를 만들고 이를 컨테이너 내부에서 볼 수 있는 디렉토리에 마운트합니다. 이렇게 하면 호스트 시스템의 알려진 위치에 파일이 배치되고 호스트 시스템의 도구와 응용 프로그램이 파일에 쉽게 액세스할 수 있습니다.

 docker run -d -v /path/to/Local_host_dir:/path/to/docker_dir docker_image:tag

Innocent Anigbo

sudo docker cp <running_container_id>:<full_file_path_in_container> <path_on_local_machine>

예시 :

 sudo docker cp d8a17dfc455f:/tests/reports /home/acbcb/Documents/abc

Shivam Bharadwaj

파일을 복사할 경로를 만든 다음 다음을 사용합니다.

 docker run -d -v hostpath:dockerimag

Chandra Pal

컨테이너에 대한 특수 저장소를 생성하지 않고 하나의 폴더만 마운트하려면 volume 대신 bind 를 사용할 수 있습니다.

  1. 태그로 이미지를 빌드하십시오.

    docker build . -t <image>

  2. 이미지를 실행하고 app.py가 저장하는 현재 $(pwd) 디렉토리를 바인딩하고 이를 컨테이너 내부의 /root/example/에 매핑합니다.

    docker run --mount type=bind,source="$(pwd)",target=/root/example/ <image> python app.py


zytfo

이는 python과 같은 SDK에서도 수행할 수 있습니다. 이미 구축된 컨테이너가 있는 경우 콘솔( docker ps -a )을 통해 이름을 조회할 수 있습니다. name 은 과학자와 형용사(예: "relaxed_pasteur")를 연결한 것 같습니다.

help(container.get_archive) 확인하세요.

 Help on method get_archive in module docker.models.containers: get_archive(path, chunk_size=2097152) method of docker.models.containers.Container instance Retrieve a file or folder from the container in the form of a tar archive. Args: path (str): Path to the file or folder to retrieve chunk_size (int): The number of bytes returned by each iteration of the generator. If ``None``, data will be streamed as it is received. Default: 2 MB Returns: (tuple): First element is a raw tar data stream. Second element is a dict containing ``stat`` information on the specified ``path``. Raises: :py:class:`docker.errors.APIError` If the server returns an error. Example: >>> f = open('./sh_bin.tar', 'wb') >>> bits, stat = container.get_archive('/bin/sh') >>> print(stat) {'name': 'sh', 'size': 1075464, 'mode': 493, 'mtime': '2018-10-01T15:37:48-07:00', 'linkTarget': ''} >>> for chunk in bits: ... f.write(chunk) >>> f.close()

따라서 이와 같은 것이 컨테이너의 지정된 경로( /output)에서 호스트 시스템으로 가져와서 tar의 압축을 풉니다.

 import docker import os import tarfile # Docker client client = docker.from_env() #container object container = client.containers.get("relaxed_pasteur") #setup tar to write bits to f = open(os.path.join(os.getcwd(),"output.tar"),"wb") #get the bits bits, stat = container.get_archive('/output') #write the bits for chunk in bits: f.write(chunk) f.close() #unpack tar = tarfile.open("output.tar") tar.extractall() tar.close()

John Drinane

podman / buildah 1 을 사용하면 컨테이너를 마운트할 수 있기 때문에 컨테이너에서 호스트로 파일을 복사하는 데 더 큰 유연성을 제공합니다.

이 답변 에서와 같이 컨테이너를 만든 후

 podman create --name dummy IMAGE_NAME

이제 우리는 전체 컨테이너를 마운트할 수 있으며, 거의 모든 Linux 상자에 cp 유틸리티를 사용하여 컨테이너( dummy )에서 호스트 시스템의 /tmp /etc/foobar 이 모든 것은 루트 없이 수행할 수 있습니다. 관찰하다:

 $ podman unshare -- bash -c ' mnt=$(podman mount dummy) cp -R ${mnt}/etc/foobar /tmp podman umount dummy '

1. podman은 내부적으로 buildah를 사용하며 거의 동일한 API를 공유합니다.


smac89

출처 : http:www.stackoverflow.com/questions/22049212/docker-copying-files-from-docker-container-to-host

반응형