한마디로 : 아니오, 귀하의 VOLUME
지시가 정확하지 않습니다.
Dockerfile은 VOLUME
컨테이너 측 경로가 지정된 하나 이상의 볼륨을 지정합니다. 그러나 이미지 작성자가 호스트 경로를 지정할 수 없습니다. 호스트 측에서 볼륨은 Docker 루트 내에 매우 긴 ID와 같은 이름으로 생성됩니다. 내 컴퓨터에서 이것은/var/lib/docker/volumes
.
참고 : 자동 생성 된 이름은 매우 길고 사람의 관점에서 이해가되지 않기 때문에 이러한 볼륨을 "명명되지 않은"또는 "익명"이라고합니다.
'.'를 사용하는 예 점을 첫 번째 또는 두 번째 인수로 설정하더라도 문자가 내 컴퓨터에서 실행되지 않습니다. 이 오류 메시지가 나타납니다.
docker : 데몬의 오류 응답 : oci runtime error : container_linux.go : 265 : 컨테이너 프로세스를 시작하면 "process_linux.go : 368 : container init이 (가) \"open / dev / ptmx : no such file or directory \ ""입니다.
나는 무엇을이 시점 밝혔다 된 것은 아마도 이해하려고 사람에게 매우 가치없는 것을 알고 VOLUME
그리고 -v
그것은 확실히 당신이 달성하려고 무엇을위한 솔루션을 제공하지 않습니다. 따라서 다음 예제가 이러한 문제에 대해 더 많은 정보를 제공 할 수 있기를 바랍니다.
직감 : 음량 지정
이 Dockerfile이 주어지면 :
FROM openjdk:8u131-jdk-alpine
VOLUME vol1 vol2
(이 minitutorial의 결과를 위해, 우리가 지정 vol1 vol2
하거나 /vol1 /vol2
이유를 묻지 않으면 아무런 차이 가 없습니다)
그것을 빌드하십시오 :
docker build -t my-openjdk
운영:
docker run --rm -it my-openjdk
컨테이너 내부에서 ls
명령 행을 실행 하면 두 개의 디렉토리가 있음을 알 수 있습니다. /vol1
그리고 /vol2
.
컨테이너를 실행하면 호스트 측에 두 개의 디렉토리 또는 "볼륨"이 생성됩니다.
컨테이너 실행하면서, 실행 docker volume ls
상의 호스트 컴퓨터 와이 같은 것을 볼 수 있습니다 (I은 간결 세 가지 점 이름의 중간 부분을 대체했다)
DRIVER VOLUME NAME
local c984...e4fc
local f670...49f0
컨테이너로 돌아가서 실행하십시오 touch /vol1/weird-ass-file
(해당 위치에 빈 파일을 작성 함).
이 파일은 이제 호스트 시스템에서 이름이없는 볼륨 lol 중 하나로 사용 가능합니다. 첫 번째로 나열된 볼륨을 처음 시도했기 때문에 두 번의 시도가 필요했지만 결국 호스트 컴퓨터에서이 명령을 사용하여 두 번째로 나열된 볼륨에서 파일을 찾았습니다.
sudo ls /var/lib/docker/volumes/f670...49f0/_data
마찬가지로 호스트에서이 파일을 삭제하려고하면 컨테이너에서도 삭제됩니다.
참고 : _data
폴더는 "마운트 포인트"라고도합니다.
컨테이너를 종료하고 호스트의 볼륨을 나열하십시오. 그들은 사라 졌어요. --rm
컨테이너를 실행할 때 플래그를 사용 했으며이 옵션은 종료시 컨테이너뿐만 아니라 볼륨도 효과적으로 제거합니다.
새 컨테이너를 실행하지만 다음을 사용하여 볼륨을 지정하십시오 -v
.
docker run --rm -it -v /vol3 my-openjdk
이렇게 하면 세 번째 볼륨 이 추가 되고 전체 시스템에 이름이 지정되지 않은 볼륨이 세 개 있습니다. 우리가 지정한 경우에만 명령이 충돌했을 것 -v vol3
입니다. 인수는 컨테이너 내부 의 절대 경로 여야합니다 . 호스트 측에서 새 세 번째 볼륨은 익명이며의 다른 두 볼륨과 함께 있습니다 ./var/lib/docker/volumes/
앞서 Dockerfile
런타임 중에 호스트에서 컨테이너로 파일을 가져 오려고 할 때 문제가되는 호스트 경로에 매핑 할 수 없다고 언급했습니다 . 다른 -v
구문으로이 문제를 해결합니다.
프로젝트 디렉토리 에 컨테이너 내부와 ./src
동기화하려는 하위 폴더가 있다고 상상해보십시오 /src
. 이 명령은 트릭을 수행합니다.
docker run -it -v $(pwd)/src:/src my-openjdk
:
캐릭터의 양쪽은 절대 경로를 기대합니다. 왼쪽은 호스트 시스템의 절대 경로이고 오른쪽은 컨테이너 내부의 절대 경로입니다. pwd
"현재 / 작업 디렉토리 인쇄"명령입니다. 명령을 넣으면 $()
명령이 괄호 안에 들어가서 서브 쉘에서 실행되고 프로젝트 디렉토리의 절대 경로가됩니다.
모두 합치면 ./src/Hello.java
다음과 같은 내용으로 호스트 시스템의 프로젝트 폴더에 있다고 가정 하십시오.
public class Hello {
public static void main(String... ignored) {
System.out.println("Hello, World!");
}
}
이 Dockerfile을 빌드합니다.
FROM openjdk:8u131-jdk-alpine
WORKDIR /src
ENTRYPOINT javac Hello.java && java Hello
이 명령을 실행합니다 :
docker run -v $(pwd)/src:/src my-openjdk
"Hello, World!"가 인쇄됩니다.
가장 좋은 부분은 이미지를 다시 빌드하지 않고도 두 번째 실행에서 다른 출력을 위해 새 메시지로 .java 파일을 자유롭게 자유롭게 수정할 수 있다는 것입니다.
최종 비고
저는 Docker를 처음 접했고 위에서 언급 한 "자습서"는 3 일 명령 행 해커 톤에서 수집 한 정보를 반영합니다. 나는 나의 진술을 뒷받침하는 명확한 영어와 같은 문서에 대한 링크를 제공 할 수 없었지만 거의 부끄러운 일이지만, 솔직히 이것은 문서가 부족하고 개인적인 노력이 아니라고 생각합니다. "Windows 10-> Vagrant 2.0.0-> Docker 17.09.0-ce"인 현재 설정을 사용하여 광고가 작동하는 것으로 알고 있습니다.
이 튜토리얼에서는 "Dockerfile에서 컨테이너의 경로를 지정하고 실행 명령 만 호스트 경로를 지정하게하는 방법"문제를 해결하지 못합니다. 방법이있을 수 있습니다, 나는 그것을 찾지 못했습니다.
마지막으로 VOLUME
Dockerfile에서 지정하는 것은 드문 일이 아니라 결코 사용하지 않는 것이 가장 좋습니다 VOLUME
. 두 가지 이유가 있습니다. 우리가 이미 확인한 첫 번째 이유 : 호스트 경로를 지정할 수 없습니다. Dockerfiles는 호스트 시스템의 특성에 매우 무관해야하기 때문에 좋은 방법입니다. 그러나 두 번째 이유는 사람들이 --rm
컨테이너를 실행할 때 옵션 을 사용하는 것을 잊어 버릴 수 있기 때문입니다 . 컨테이너를 제거해야하지만 볼륨을 제거하는 것을 잊어 버릴 수도 있습니다. 또한 최고의 메모리를 사용하더라도 모든 익명 볼륨 중 제거 할 수있는 볼륨을 찾는 것은 어려운 작업 일 수 있습니다.