기존 Docker 컨테이너에 볼륨을 추가하려면 어떻게해야합니까?


297

우분투에 Docker를 설치하고 다음을 수행하여 만든 Docker 컨테이너가 있습니다.

sudo docker run -i -t ubuntu /bin/bash

나는 즉시 Java와 다른 도구를 설치하기 시작했고, 시간을 보내고 컨테이너를 중지했습니다.

exit

그런 다음 볼륨을 추가하고 싶었지만 이것이 생각보다 간단하지 않다는 것을 깨달았습니다. 사용하면 sudo docker -v /somedir run ...새로운 컨테이너가 생겨 Java를 설치하고 마운트 된 볼륨이있는 컨테이너에 도착하기 전에 이미 수행 한 작업을 수행합니다.

호스트에서 폴더를 마운트하는 데 대한 모든 문서는 볼륨을 마운트하는 것이 컨테이너를 만들 때 수행 할 수있는 것으로 암시하는 것 같습니다. 따라서 새 컨테이너를 처음부터 재구성하지 않아야하는 유일한 옵션은 기존 컨테이너를 리포지토리에 커밋하고 볼륨을 마운트하는 동안이를 새로운 컨테이너의 기초로 사용하는 것입니다.

이것이 실제로 기존 컨테이너에 볼륨을 추가하는 유일한 방법입니까?


1
컨테이너 후, 이들은 프로그래머의 필수 부분이되었으므로 이러한 질문은 여기에 더 자주 게시됩니다. docker태그를 사용하여 여기에 게시 된 질문 은 34k +입니다 . 이는 두 사이트보다 훨씬 더 높습니다. stackoverflow.com/questions/tagged/docker
MA Hossain Tonu

답변:


394

기존 컨테이너를 커밋 (컨테이너 변경으로 새 이미지 생성) 한 다음 새 마운트로 실행할 수 있습니다.

예:

$ docker ps  -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                          PORTS               NAMES
    5a8f89adeead        ubuntu:14.04          "/bin/bash"              About a minute ago   Exited (0) About a minute ago                       agitated_newton

$ docker commit 5a8f89adeead newimagename

$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

문제가 없으면 이전 컨테이너를 중지하고이 새 컨테이너를 사용하십시오.

그게 다야 :)


22
그리고 어떤 이유로 이전 이름을 가져 오기 위해 새 컨테이너가 필요한 경우 이전 컨테이너를 제거한 후 docker rename 을 사용 하십시오.
Dirk

10
시스템 에서 새로운 이미지 를 생성 하기 때문에 위와 같이 newnameofcontainer이름을 지정해야한다고 언급 했습니다 . 그런 다음 다음 작업을 수행 할 때 실제로 새 컨테이너를 실행하려는 이미지 의 이름을 사용합니다 . 위의 작동하지만 위의 자리 표시 자 newnameofcontainer가 실제로 새 이미지의 이름임을 다른 사람들에게 명확히하고 싶었습니다. 감사! 멋진 답변입니다. 아,new_image_namedocker commitdocker rundocker image ls
FireDragon

3
실제로 이미지에서 시작하려는 경우 새 컨테이너를 커밋 할 필요가 없습니다. 그냥 docker run -v /srv/a:/tmp ubuntu:14.04좋다
YongHao Hu

이미 모든 파일로 실행되는 컨테이너가 있습니다. 위의 방법으로 새 ​​컨테이너를 만들면 모든 것을 다시 만들 수 없습니다. 새로운 컨테이너 또는 이미지를 만들지 않고도 이것을 피하고 마운트 할 수있는 방법이 있습니까?
dhinar

이렇게하면 이전 볼륨 매핑이 이전 컨테이너에서 유지됩니까? 아니면 새 컨테이너로 다시 선언해야합니까?
thebeancounter

79

컨테이너 실행에 볼륨을 추가하는 방법은 없지만이 목표를 달성하려면 아래 명령을 사용할 수 있습니다.

컨테이너와 로컬 파일 시스템간에 파일 / 폴더를 복사하십시오.

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

참조를 위해 :

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


47
볼륨 마운트와 컨테이너에서 파일을 복사하는 것과 컨테이너에서 파일을 복사하는 것에는 큰 차이가 있습니다 ...
Jules

31
어쨌든 그것은 나를 도왔습니다. 나는 'docker cp'명령을 몰랐으며 정확하게 컨테이너를 실행하는 컨테이너에서 호스트로 파일을 복사하려고했습니다.
Ivan

3
마운트는 아니지만 컨테이너와 로컬 호스트간에 파일을 다시 가져 와서 쉽게 가져올 수 있습니다.
linehrr

이렇게하면 컨테이너 내용을 로컬로 복제하는 문제가 해결되지만 이는 볼륨을 마운트하는 것과 비슷하지 않으므로 대안으로 생각해서는 안됩니다. 즉, 복제는 사용자가 관리해야하며 데이터는 현재 두 곳에 존재합니다.
Sebastian Gaweda

1
왜 이렇게 많은 표를 얻었는지 이해할 수 없습니다. 이것은 질문에 대한 매우 잘못된 답변입니다.
João Matos

33

/home/<user-name>호스트의 /mnt폴더를 기존 (실행 중이 아닌) 컨테이너 의 폴더에 성공적으로 마운트했습니다 . 다음과 같은 방법으로 수행 할 수 있습니다.

  1. 중지 된 컨테이너에 해당하는 구성 파일을 엽니 다 /var/lib/docker/containers/99d...1fb/config.v2.json( config.json이전 버전의 docker 일 수 있음).

  2. MountPoints내 경우에는 비어있는 섹션을 찾으십시오 "MountPoints":{}. 다음으로 내용을 다음과 같이 바꾸십시오 (적절한 설정으로 다른 컨테이너에서 적절한 내용을 복사 할 수 있습니다).

"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}

또는 동일 (서식) :

  "MountPoints": {
    "/mnt": {
      "Source": "/home/<user-name>",
      "Destination": "/mnt",
      "RW": true,
      "Name": "",
      "Driver": "",
      "Type": "bind",
      "Propagation": "rprivate",
      "Spec": {
        "Type": "bind",
        "Source": "/home/<user-name>",
        "Target": "/mnt"
      },
      "SkipMountpointCreation": false
    }
  }
  1. 도커 서비스를 다시 시작하십시오. service docker restart

이것은 Ubuntu 18.04.1 및 Docker 18.09.0에서 작동합니다.


3
답변 해주셔서 감사합니다. 3 단계는 중요합니다. 또한 쓰기를 수행하기 전에 도커 컨테이너를 먼저 중지하는 것이 좋습니다.
buzypi

7
이것은 기존 컨테이너를 완전히 보존하므로 가장 좋은 대답입니다. 이것이 내가 한 일입니다. 1. 도커 엔진을 중지합니다. systemctl stop docker.service2. 편집 config.v2.json: vim <(jq . /var/lib/docker/containers/<container-ID>/config.v2.json)3. 파일에 업데이트를 저장합니다. :w config.v2.json4. vim을 종료합니다. :q!5. 기존 파일 업데이트 : jq -c . config.v2.json > /var/lib/docker/containers/<container-ID>/config.v2.json6. 도커 엔진을 systemctl start docker.service시작합니다 . 7. 필요한 경우 컨테이너를 시작합니다. : docker start <container-name/ID>8. 즐기십시오 :-)
Android Control

2
핵심 단계service docker restart입니다. 내가하려고 docker restart <container>다음 새 설정이 포착되지 않고, 기존의 설정에 의해 덮어지고있어.
KFL

1
또한 jq사람이 편집 할 수 있도록 JSON을 인쇄하는 데 도움이됩니다.cat config.v2.json | jq . > config.json
KFL

14

Jérôme Petazzoni볼륨이 실행되는 동안 볼륨을 컨테이너연결하는 방법에 대한 흥미로운 블로그 게시물을 가지고 있습니다. 이것은 Docker에 기본 제공되는 것이 아니라 달성 할 수있는 것입니다.

그가 지적한대로

블록 장치를 기반으로하지 않는 파일 시스템에서는 작동하지 않습니다.

/ proc / mounts가 블록 장치 노드를 올바르게 나열하는 경우에만 작동합니다 (위에서 보았 듯이 반드시 해당되는 것은 아님).

또한 로컬 환경에서만 테스트했습니다. 클라우드 인스턴스 또는 그와 비슷한 것을 시도조차하지 않았습니다.

YMMV


8

불행히도 볼륨을 마운트하기위한 스위치 옵션은 run명령 에서만 찾을 수 있습니다.

docker run --help

-v, --volume list Bind mount a volume (default [])

이 문제를 해결할 수있는 방법이 있으므로 컨테이너에 이미 설정 한 응용 프로그램을 다시 설치할 필요가 없습니다.

  1. 컨테이너 수출 docker container export -o ./myimage.docker mycontainer
  2. 이미지로 가져 오기 docker import ./myimage.docker myimage
  3. 그때 docker run -i -t -v /somedir --name mycontainer myimage /bin/bash

1
참고 docker container-1.11.2 (이 문서 작성 시점에서 Synology가 지원하는 최신 버전)에서는 유효한 명령이 아닙니다. 그래도 추가되었을 때 말하는 문서를 찾을 수 없습니다. 이 경우 첫 번째 명령은 docker export -o ./myimage.docker mycontainer입니다.
Chris R. Donnelly

2

오랫동안이 문제를 찾아야 한 후 Docker Windows 컨테이너를 사용하기위한 참고 사항!

콘도 :

  • 윈도우 10
  • Docker Desktop (최신 버전)
  • 이미지 Microsoft / mssql-server-windows-developer에 Docker Windows 컨테이너 사용

문제:

  • 호스트 사전을 Windows 컨테이너에 마운트하고 싶었습니다.

여기 부분적으로 설명 된 솔루션 :

  • 도커 컨테이너 만들기

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer

  • 컨테이너의 명령 셸로 이동

docker exec -it <CONTAINERID> cmd.exe

  • DIR 생성

mkdir DirForMount

  • 컨테이너를 중지

docker container stop <CONTAINERID>

  • 커밋 컨테이너

docker commit <CONTAINERID> <NEWIMAGENAME>

  • 오래된 컨테이너 삭제

docker container rm <CONTAINERID>

  • 새로운 이미지와 볼륨 마운팅으로 새로운 컨테이너 생성

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>

이 후 docker windows 컨테이너 에서이 문제를 해결했습니다.


-3

가장 좋은 방법은 다음 방법으로 로컬 파일 시스템의 디렉토리에있는 모든 파일과 폴더를 복사하는 것입니다. docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

SRC_PATH컨테이너 DEST_PATH에 localhost에

그런 다음 docker-compose down동일한 볼륨을 연결하고 다음 DEST_PATH을 사용하여 Docker 컨테이너를 실행하십시오.docker-compose up -d

다음을 수행하여 볼륨 추가 docker-compose.yml

volumes:
 - DEST_PATH:SRC_PATH

위의 다른 더 나은 옵션이 있습니다.
MrR

실제로 위의 더 나은 옵션이 있으며 파일을 복사해도 마운트되지 않습니다. 또한 docker-compose 옵션에 지정된 "볼륨"정의는 다른 방법입니다. volume :-HOST_PATH : CONTAINER_PATH
Guillaume S.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.