Docker 머신에 로컬 볼륨을 마운트하는 방법


86

docker-compose와 함께 docker-machine을 사용하려고합니다. docker-compose.yml 파일에는 다음과 같은 정의가 있습니다.

web:
  build: .
  command: ./run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

실행할 때 docker-compose up -d모든 잘 명령을 실행하려고 할 때까지 이동하고 오류가 생성됩니다

컨테이너 b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d : [8] 시스템 오류 : exec : "./run_web.sh": stat ./run_web.sh : 해당 파일 또는 디렉토리가 없습니다.

로컬 볼륨은 원격 시스템에 마운트되지 않습니다. 웹앱의 코드로 로컬 볼륨을 마운트하는 데 권장되는 전략은 무엇입니까?


프로젝트 및 docker-compose.yml의 구조는이 튜토리얼과 유사합니다. syncano.com/…
jdcaballerov

1
이것은 로컬에서 compose를 사용하기 시작할 수있는 사람들에게 유용한 힌트로 docker-compose 문서에 있어야합니다. 도대체 내 파일 경로가 잘못되었거나 찾을 수없는 이유를 파악하려는 WTF 순간의 시간을 절약 할 수 있었을 것입니다. 아뇨 그냥 어리석은 것 같아요.
timbrown 2015

답변:


93

Docker-machine은 사용자 디렉토리를 자동 마운트합니다.하지만 때로는 그것만으로는 충분하지 않습니다.

도커 1.6에 대해서는 잘 모르지만 1.8에서는 도커 머신에 추가 마운트를 추가 할 있습니다.

가상 머신 마운트 지점 추가 (1 부)

CLI : (기계가 정지 된 경우에만 작동)

VBoxManage sharedfolder add <machine name/id> --name <mount_name> --hostpath <host_dir> --automount

따라서 Windows의 예는

/c/Program\ Files/Oracle/VirtualBox/VBoxManage.exe sharedfolder add default --name e --hostpath 'e:\' --automount

GUI : (기계를 중지 할 필요가 없습니다)

  1. "Oracle VM VirtualBox Manager"를 시작합니다.
  2. 오른쪽 클릭 <machine name>(기본값)
  3. 설정 ...
  4. 공유 폴더
  5. 오른쪽의 폴더 + 아이콘 (공유 추가)
  6. 폴더 경로 : <host dir>(e :)
  7. 폴더 이름 : <mount name>(e)
  8. "Auto-mount"및 "Make Permanent"를 선택합니다 (원하는 경우 읽기 전용 ...) (자동 마운트는 현재 무의미합니다 ...)

boot2docker에 장착 (2 부)

boot2docker에 수동으로 마운트하십시오 .

  1. 로그인, "Oracle VM VirtualBox Manager"에서 "Show"를 사용하거나 IP 주소로 docker에 ssh / putty를 사용하는 등 다양한 방법이 있습니다 docker-machine ip default.
  2. sudo mkdir -p <local_dir>
  3. sudo mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>

그러나 이것은 컴퓨터를 다시 시작하고 마운트가 손실 될 때까지만 좋습니다.

boot2docker에 자동 마운트 추가 :

기기에 로그인되어있는 동안

  1. (루트로) 편집 / 만들기 /mnt/sda1/var/lib/boot2docker/bootlocal.sh, sda1은 당신을 위해 다를 수 있습니다 ...
  2. 더하다

    mkdir -p <local_dir>
    mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>
    

이러한 변경으로 새 마운트 지점이 있어야합니다. 이것은 부팅시 호출되고 영구적 인 몇 안되는 파일 중 하나입니다. 더 나은 솔루션이있을 때까지 작동합니다.


이전 방법 : 덜 권장 되지만 대안으로 남음

  • 편집 (루트) /mnt/sda1/var/lib/boot2docker/profile, sda1은 다를 수 있습니다 ...
  • 더하다

    add_mount() {
      if ! grep -q "try_mount_share $1 $2" /etc/rc.d/automount-shares ; then
        echo "try_mount_share $1 $2" >> /etc/rc.d/automount-shares
      fi
    }
    
    add_mount <local dir> <mount name>
    

A와 최후의 수단 , 당신은 약간 지루한 대안을 취할 수 있고, 당신은 단지 부팅 이미지를 수정할 수 있습니다.

  • git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
  • cd boot2docker
  • git -c core.autocrlf=false checkout v1.8.1 # 또는 적절한 버전
  • 편집하다 rootfs/etc/rc.d/automount-shares
  • try_mount_share <local_dir> <mount_name>끝에 fi 바로 앞에 줄을 추가 합니다. 예를 들면

    try_mount_share /e e
    

    / bin 등과 같이 os에 필요한 것으로 설정하지 마십시오.

  • docker build -t boot2docker . # 처음에는 약 1 시간 정도 소요됩니다 :(
  • docker run --rm boot2docker > boot2docker.iso
  • 이전 boot2docker.iso를 백업하고 ~ / .docker / machine / machines /의 그 자리에 새 파일을 복사하십시오.

이것은 작동합니다. 길고 복잡합니다.

docker 버전 1.8.1, docker-machine 버전 0.4.0


이것에 문제가있는 사람이라면 로컬 경로를 도커 머신의 경로와 일치시켜야한다고 확신합니다. 또한 docker-compose는 볼륨을 마운트하는 데 성공한 것처럼 보였지만 일반 docker는 그 이유를 알지 못했습니다.
spieden

3
여기에 언급 된 솔루션에 대한 스크립트를 작성했습니다. 최신 docker 1.10 및 docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e에서 작동
cristobal

다른 리소스에서 사용에 대해 이야기 /mnt/sda1/var/lib/boot2docker/profile합니다. 사용으로 전환 한 이유를 설명해 주 /mnt/sda1/var/lib/boot2docker/bootlocal.sh시겠습니까? 또한,이 많은 텍스트를 훑어 보는 것은 답변의 가독성에 기여하지 않습니다 ;-)
Forage

1
@Forage Point는 내 서식에 대해 취했습니다. :). 나는 bootlocal.sh더 이상 방법을 제안하는 이유를 기억하지 못합니다 . 내가 말할 수 bootlocal.sh있는 것은 프로파일에서하는 것보다 내가했던 것처럼 마운트 명령을 사용하는 것이 더 깔끔해 보인다는 것 입니다. 또한 일반적으로는 profile여러 번 실행할 수 있고 마운트는 한 번만 실행하면되므로 더 의미가 있습니다. 그러나 둘 다 작동 할 수 있습니다.
Andy

사랑해! 감사합니다!
Qorbani

28

또한이 문제가 발생했으며 docker-machine을 사용할 때 로컬 볼륨이 마운트되지 않은 것 같습니다. 해킹 솔루션은

  1. docker-machine 인스턴스의 현재 작업 디렉토리를 가져옵니다. docker-machine ssh <name> pwd

  2. rsync원격 시스템에 폴더 복사 와 같은 명령 줄 도구 사용

    rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:<result _of_pwd_from_1>.
    

기본 pwd는 / root이므로 위의 명령은 다음과 같습니다. rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

NB : 원격 시스템에 대한 암호를 제공해야합니다. ssh를 사용하여 원격 시스템에 빠르게 만들고 암호를 만들 수 있습니다.

  1. 볼륨은 마운트 지점을 달라 docker-compose.yml에서 파일 .:/app/root/<name_of_folder>:/app

  2. 운영 docker-compose up -d

NB 로컬에서 변경이 이루어지면 변경 rsync사항을 원격 시스템에 푸시 하기 위해 다시 실행 하는 것을 잊지 마십시오 .

완벽하지는 않지만 작동합니다. 문제가 진행 중입니다. https://github.com/docker/machine/issues/179

이를 해결하려는 다른 프로젝트로는 docker-rsync가 있습니다.


rsync를 원격 시스템에 설치해야합니다.`sh : rsync : 찾을 수 없음 rsync : 연결이 예기치 않게 닫힘 (지금까지 0 바이트 수신 됨) [sender] rsync 오류 : / SourceCache / rsync / rsync에서 원격 명령을 찾을 수 없음 (코드 127) -45 / rsync / io.c (453) [sender = 2.6.9]`어떻게 작동하게 되었나요?
krinker

1
rsync는 로컬 시스템에 설치해야합니다
gbozee

이 단계를 사용하면 내 digitalocean 호스트가 완전히 잠 깁니다. 파일은 정상적으로 전송되지만 docker-machine을 사용하여 호스트에 다시 연결하려고하면 컴퓨터 exit status 255를 완전히 다시 만들어야합니다.
dsifford

1
여기에 언급 된 솔루션에 대한 스크립트를 작성했습니다. 최근에 작동 docker 1.10하고 docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
크리스토

@cristobal rsync 솔루션이 아닌 마운트 솔루션을 스크립팅 한 것 같습니다.
Andy

14

현재로서는 머신에 볼륨을 마운트하는 방법을 실제로 볼 수 없으므로 지금까지 필요한 파일을 머신에 복사하거나 동기화하는 방법이 있습니다.

docker-machine의 github repo에서이 문제를 해결하는 방법에 대한 대화 가 있습니다 . 누군가 docker-machine에서 scp 를 구현 하는 pull request를 만들었고 이미 master에 병합되었으므로 다음 릴리스에 포함될 가능성이 큽니다.

아직 출시되지 않았기 때문에 지금까지 코드가 github에 호스팅되어 있다면 앱을 실행하기 전에 저장소를 복제하는 것이 좋습니다.

web:
  build: .
  command: git clone https://github.com/my/repo.git; ./repo/run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

업데이트 : 더 자세히 살펴보면이 기능이 이미 최신 바이너리 에서 사용 가능하다는 것을 알았습니다.이 기능 을 받으면 다음과 같은 명령을 실행하는 로컬 프로젝트를 복사 할 수 있습니다.

docker-machine scp -r . dev:/home/docker/project

이것이 일반적인 형태이기 때문에 :

docker-machine scp [machine:][path] [machine:][path]

따라서 컴퓨터간에 파일을 복사 할 수 있습니다.

건배! 1


고정 표시기 기계 SCP에 대한 문서 : docs.docker.com/machine/reference/scp
안토니 Dahanne

2
이 방법은 :( 매우 느립니다
세르게이 Jevsejev

5

2017 년 10 월 이후로 트릭을 수행하는 docker-machine에 대한 새로운 명령이 있지만 실행하기 전에 디렉토리에 아무것도 없는지 확인하십시오. 그렇지 않으면 손실 될 수 있습니다.

docker-machine mount <machine-name>:<guest-path> <host-path>

자세한 정보는 문서를 확인하십시오 : https://docs.docker.com/machine/reference/mount/

변경된 PR : https://github.com/docker/machine/pull/4018


1
믿을 수 없을 정도로 Docker Machine 문서 (링크 한 것)에서 명령의 순서 ...:<guest-path> <host-path>가 다른 방법 이 아니라는 사실을 아는 것은 말 그대로 불가능합니다 . 문서에서 메모하는 것만 큼 간단하고 중요한 것은 아닙니다.
Dan Nissenbaum

나는 그것이 매우 명시 적이 지 않다고 생각합니다. 당신이 옳습니다. 명령 목록에서 추측해야합니다
Jorge

트릭을 수행하지만 다른 방식으로 수행합니다. 로컬 머신에 docker-machine dir을 마운트 할 수 있습니다. 불행히도 그것은 다른 방법을 허용하지 않습니다 :(
ravenwing 19

4

docker-machine과 함께 rsync 옵션을 선택하면 다음 docker-machine ssh <machinename>과 같은 명령과 결합 할 수 있습니다 .

rsync -rvz --rsh='docker-machine ssh <machinename>' --progress <local_directory_to_sync_to> :<host_directory_to_sync_to>

이 명령 형식의 rsync를 사용하며 HOST비워 둡니다 .

rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

( http://linuxcommand.org/man_pages/rsync1.html )


1

마지막으로 Windows Docker Toolbox를 v1.12.5로 업그레이드하고 Oracle VM VirtualBox관리자에 공유 폴더를 추가하고 경로 변환을 비활성화 하여 볼륨을 계속 작동시키는 방법을 알아 냈습니다 . Windows 10 이상이있는 경우 최신 Windows 용 Docker를 사용하는 것이 가장 좋습니다.

첫 번째 업그레이드 문제 :

  1. 먼저 VirtualBox를 제거하십시오.
    • 예, Android Studio와 같은 다른 도구에서 문제가 발생할 수 있습니다. 감사합니다 Docker :(
  2. 새 버전의 Docker Toolbox를 설치합니다.

Redis 데이터베이스 예 : redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

Docker 빠른 시작 터미널에서 ....

  1. 실행 docker-machine stop default-VM이 손상되었는지 확인

Oracle VM VirtualBox Manager에서 ...

  1. default또는 명령 줄을 통해 VM에 공유 폴더 추가
    • D:\Projects\MyProject\db => /var/db

에서 docker-compose.yml...

  1. redis 볼륨을 다음과 같이 매핑했습니다. "/var/db/redis:/data:rw"

Docker 빠른 시작 터미널에서 ....

  1. 설정 COMPOSE_CONVERT_WINDOWS_PATHS=0(Toolbox 버전> = 1.9.0)
  2. docker-machine start defaultVM을 다시 시작하려면 실행 하십시오.
  3. cd D:\Projects\MyProject\
  4. docker-compose up 지금 작동합니다.

이제 redis 데이터베이스를 생성합니다. D:\Projects\MyProject\db\redis\dump.rdb

상대 호스트 경로를 피하는 이유는 무엇입니까?

나는 상대 호스트 경로 회피 가 유효하지 않은 '\'문자를 소개 할 수 있습니다로 Windows 도구 상자에 대한합니다. 상대 경로를 사용하는 것만 큼 좋지는 docker-compose.yml않지만 적어도 동료 개발자는 docker-compose.yml파일 을 해킹하지 않고도 프로젝트 폴더가 다른 곳에 있더라도 쉽게 할 수 있습니다 (SCM에 좋지 않음).

원래 문제

참고로 ... 다음은 이전 버전에서 잘 작동하는 깨끗한 상대 경로를 사용할 때 얻은 원래 오류입니다. 내 볼륨 매핑은"./db/redis:/data:rw"

ERROR: for redis Cannot create container for service redis: Invalid bind mount spec "D:\\Projects\\MyProject\\db\\redis:/data:rw": Invalid volume specification: 'D:\Projects\MyProject\db\redis:/data

이것은 두 가지 이유로 중단됩니다 ..

  1. D:드라이브에 액세스 할 수 없습니다.
  2. 볼륨 경로에는 \문자를 포함 할 수 없습니다.
    • docker-compose 그들을 추가하고 그것에 대해 당신을 비난합니다!
    • COMPOSE_CONVERT_WINDOWS_PATHS=0이 말도 안되는 소리를 중지하는 데 사용 합니다.

docker-compose.ymlVirtualBox를 다시 제거하고 공유 폴더를 재설정해야 할 수 있으며 어쨌든 동료 개발자가 당신을 좋아할 것이므로 파일 에 추가 VM 공유 폴더 매핑을 문서화하는 것이 좋습니다 .


당신은 훌륭한 사람입니다
AaronHS

1

다른 모든 답변은 당분간 좋았지 만 이제는 (Docker Toolbox v18.09.3) 모두 즉시 작동합니다. VirtualBox VM에 공유 폴더를 추가하기 만하면됩니다.

Docker Toolbox는 Virtual Box 공유 폴더 기능을 사용하여 가상 Linux 시스템 아래에 C:\Users공유 폴더로 자동 추가 /c/Users하므로 docker-compose.yml파일이이 경로 아래에 있고이 경로 아래에만 호스트 시스템의 디렉토리를 마운트하면 모든 것이 즉시 작동합니다.

예를 들면 :

C:\Users\username\my-project\docker-compose.yml:

...
  volumes:
    - .:/app
...

.경로 자동 절대 경로로 변환한다 C:\Users\username\my-project으로 다음과 /c/Users/username/my-project. 그리고 이것은 Linux 가상 머신의 관점에서이 경로가 정확히 어떻게 보이는지입니다 (확인할 수 있습니다 : docker-machine ssh그런 다음 ls /c/Users/username/my-project). 따라서 최종 마운트는 /c/Users/username/my-project:/app.

모두 투명하게 작동합니다.

그러나 호스트 마운트 경로가 C:\Users경로 아래에 있지 않으면 작동하지 않습니다 . 예를 들어, 동일한 넣어 docker-compose.yml아래를 D:\dev\my-project.

이것은 쉽게 고칠 수 있습니다.

  1. 가상 머신 ( docker-machine stop)을 중지합니다 .
  2. Virtual Box GUI를 열고 이름이라는 가상 머신의 설정을 default열고 Shared Folders섹션을 열고 새 공유 폴더를 추가합니다.

    • 폴더 경로 : D:\dev
    • 폴더 이름: d/dev

    OK두 번 누르고 Virtual Box GUI를 닫습니다.

  3. 가상 머신 ( docker-machine start)을 시작합니다 .

그게 다야. 호스트 시스템의 모든 경로는 D:\dev이제 docker-compose.yml마운트 에서 작동 합니다.


1

그것은 세 가지 도구의 완료 마녀의 조합이 될 수 있습니다 : docker-machine mount, rsync,inotifywait

TL; DR

아래 모두를 기반으로 한 스크립트 는 여기에 있습니다.

하자 당신이 당신이 말 docker-compose.ymlrun_web.sh/home/jdcaballerov/web

  1. 호스트에있는 것과 동일한 경로 를 가진 컴퓨터에 디렉토리 마운트 합니다.docker-machine machine:/home/jdcaballerov/web /tmp/some_random_dir
  2. 마운트 된 디렉토리를 호스트의 dir과 동기화 rsync -r /home/jdcaballerov/web /tmp/some_random_dir
  3. 디렉토리의 모든 파일 변경 사항을 동기화합니다.

    inotifywait -r -m -e close_write --format '%w%f' /home/jdcaballerov/web | while read CHANGED_FILE
    do
        rsync /home/jdcaballerov/web /tmp/some_random_dir
    done
    

주의하십시오 -동일한 경로를 가진 두 개의 디렉토리가 있습니다. 하나는 로컬 (호스트) 머신에 있고 두 번째는 도커 머신에 있습니다.


0

run_web.sh파일이 파일과 동일한 디렉토리에 있다고 가정 docker-compose.yml합니다. 그러면 명령은 command: /app/run_web.sh.

하지 않는 한 Dockerfile(당신은 공개되지하는 것을) 퍼팅을 처리합니다 run_web.sh도커 이미지로 파일을.


답변 해 주셔서 감사합니다. 동일한 디렉토리에 있습니다. 그러나 볼륨이 마운트되지 않은 것으로 나타났습니다. 파일을 사용할 수 없으며 그게 문제입니다. 추가하는 방법. 구조는 syncano.com/…
jdcaballerov

docker 및 dicker-compose의 최신 버전이 있는지 확인하십시오.
Thomasleveil 2015

docker : Docker 버전 1.6.0, 빌드 4749651, docker-machine 버전 0.2.0 (8b9eaf2), docker-compose 1.2.0
jdcaballerov

syncano.com/…에서 Dockerfile 을 수정 한 적이 있습니까?
Thomasleveil

1
예, 코드를 추가하고 디렉토리를 만듭니다. 문제는 docker-compose가 실행될 때 볼륨 (volume :-. : / app)을 덮어 쓰고 빈 디렉토리를 남긴다는 것입니다. 나는 compose에서 볼륨을 주석으로 달았고 작동합니다.
jdcaballerov

0

여기에 게시물을 요약 한 후 업데이트 된 스크립트를 첨부하여 추가 호스트 마운트 지점을 만들고 Virtualbox가 다시 시작될 때 자동 마운트합니다. 다음과 같은 작업 환경 개요 :-Windows 7-docker-machine.exe 버전 0.7.0-VirtualBox 5.0.22

    #!env bash

    : ${NAME:=default}
    : ${SHARE:=c/Proj}
    : ${MOUNT:=/c/Proj}
    : ${VBOXMGR:=C:\Program Files\Oracle\VirtualBox\VBoxManage.exe}
    SCRIPT=/mnt/sda1/var/lib/boot2docker/bootlocal.sh

    ## set -x
    docker-machine stop $NAME
    "$VBOXMGR" sharedfolder add $NAME --name c/Proj --hostpath 'c:\' --automount 2>/dev/null || :
    docker-machine start $NAME
    docker-machine env $NAME

    docker-machine ssh $NAME 'echo "mkdir -p $MOUNT" | sudo tee $SCRIPT'
    docker-machine ssh $NAME 'echo "sudo mount -t vboxsf -o rw,user $SHARE $MOUNT" |  sudo tee -a $SCRIPT'
    docker-machine ssh $NAME 'sudo chmod +x /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    docker-machine ssh $NAME 'sudo /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    #docker-machine ssh $NAME 'ls $MOUNT'

0

내 로컬 컴퓨터의 virtualbox 드라이브와 함께 docker-machine 0.12.2를 사용하고 있습니다. /hosthome/$(user name)로컬 파일에 액세스 할 수 있는 디렉토리가 있음을 발견했습니다 .


0

Windows 10에서 18.03.1-ce-win65 (17513)를 사용하고 있다고 생각했는데 이전에 드라이브를 공유하고 자격 증명을 캐시 한 경우 암호를 변경하면 Docker가 컨테이너 내에 공백으로 마운트 된 볼륨.

실제로 일어나고있는 것은 이전 캐시 된 자격 증명을 사용하여 공유에 액세스하는 데 실패하고 있다는 표시를 제공하지 않습니다. 이 시나리오의 해결책은 UI (설정-> 공유 드라이브)를 통해 자격 증명을 재설정하거나 드라이브 공유를 비활성화 한 다음 다시 활성화하고 새 암호를 입력하는 것입니다.

이러한 상황에서 docker-compose가 오류를 제공하면 유용합니다.

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