볼륨에 단일 파일을 마운트하는 방법


256

PHP 응용 프로그램을 고정하려고합니다. dockerfile에서 아카이브를 다운로드하고 추출하십시오.

새 버전이 출시되고 config.php가 덮어 쓰기 때문에 응용 프로그램을 다시 설치 해야하는 dockerfile을 업데이트하면 모든 것이 잘 작동합니다.

그래서 데이터베이스와 마찬가지로 파일을 볼륨으로 마운트 할 수 있다고 생각했습니다.

볼륨과 직접 경로를 사용하여 두 가지 방법으로 시도했습니다.

도커 작성 :

version: '2'
services:
  app:
    build: src
    ports:
      - "8080:80"
    depends_on:
      - mysql
    volumes:
      -  app-conf:/var/www/html/upload
      -  app-conf:/var/www/html/config.php
    environment:
      DB_TYPE: mysql
      DB_MANAGER: MysqlManager

  mysql:
    image: mysql:5.6
    container_name: mysql
    volumes:
      - mysqldata:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD:
      MYSQL_DATABASE:
      MYSQL_USER:
      MYSQL_PASSWORD:

volumes:
  mysqldata:
  app-conf:

오류가 발생하는 원인은 다음과 같습니다.

그리고 주어진 경로로 마운트 된 볼륨으로 시도했습니다.

/src/docker/myapp/upload:/var/www/html/upload
/src/docker/myapp/upload:/var/www/html/config.php

그러나 두 가지 방법 모두 작동하지 않습니다. 마운트 된 볼륨으로 업로드가 생성되는 것을 볼 수 있습니다.

그러나 실패

/var/www/html/config.php \\ "는 \\"디렉토리가 아닙니다 \\ "\" "

내가 시도하면

/src/docker/myapp/upload/config.php:/var/www/html/config.php

Docker는 업로드 폴더와 config.php 폴더를 만듭니다. 파일이 아닙니다.

또는 구성을 유지하는 다른 방법이 있습니까?


필자의 경우 컨테이너 / 볼륨을 만들기 전에 빈 파일을 "터치"하는 것이 간단합니다. 파일이 존재하지 않으면 디렉토리를 생성 한 것입니다.
FreeSoftwareServers

답변:


311

TL; DR / 공지 사항 :

마운트하려는 파일 대신 디렉토리가 작성되는 경우 유효 하고 절대 경로 를 제공하지 않았을 수 있습니다 . 이는 조용하고 혼란스러운 실패 모드에서 흔히 발생하는 실수입니다.

파일 볼륨은 docker에서 이런 방식으로 수행됩니다 (절대 경로 예제 (env 변수를 사용할 수 있음). 파일 이름을 언급해야합니다).

    volumes:
      - /src/docker/myapp/upload:/var/www/html/upload
      - /src/docker/myapp/upload/config.php:/var/www/html/config.php

당신은 또한 할 수 있습니다 :

    volumes:
      - ${PWD}/upload:/var/www/html/upload
      - ${PWD}/upload/config.php:/var/www/html/config.php

/src/docker/myapp폴더 에서 docker-compose를 실행하면


81
내가 말했듯이 /src/docker/myapp/upload/config.php:/var/www/html/config.php를 시도하면 Docker가 업로드 폴더를 만든 다음 config.php 폴더를 만듭니다. 파일이 아닙니다.
Jakub Juszczak

9
귀하의 게시물에서 다르게 작성했습니다. 파일이 있으면 파일로 마운트해야합니다.
BlackStork

16
이것이 작동하려면 절대 경로를 제공해야했습니다. PWD를 사용한 팁이 여기에 많은 도움이되었습니다. 감사합니다!
Steve Smith

4
나에게 파일이 아닌 폴더를 만들고 있지만 그 파일이 나중에 해당 경로에서 복사되기 때문에 바인딩을 연기 할 생각이 있습니까?
eKelvin

18
/src/docker/myapp/upload/config.php가 호스트 도커에 존재하지 않으면 폴더를 만들 것입니다 ... 내가하고있는 일은 docker run을 실행하기 전에 빈 파일을 만드는 스크립트를 만드는 것입니다-이상적입니다 도커에게 cmd line args를 통해 나를 위해 지시하도록 지시 할 수 있다면.
Cancerbero

78

나는 비슷한 문제로 고통 받고 있었다. 이미지를 다시 작성하지 않고 필요할 때마다 수정할 수 있도록 구성 파일을 컨테이너로 가져 오려고했습니다.

아래 명령이 $(pwd)/config.pyDocker 호스트 /root/app/config.py에서 컨테이너로 파일로 매핑 될 것이라고 생각했습니다 .

docker run -v $(pwd)/config.py:/root/app/config.py my_docker_image

그러나 항상 config.py파일이 아닌 이라는 디렉토리를 작성했습니다 .

단서를 찾는 동안 이유를 찾았습니다 ( 여기에서 )

-v 또는 --volume을 사용하여 Docker 호스트에없는 파일 또는 디렉토리를 바인드 마운트하면 -v가 엔드 포인트를 작성합니다. 항상 디렉토리로 작성됩니다 .

따라서 도커 호스트에는이 없기 때문에 항상 디렉토리로 생성됩니다 $(pwd)/config.py.

도커 호스트에서 config.py를 생성하더라도. $(pwd)/config.py그냥 /root/app/config.py수출하지 않는 것보다 큽니다 /root/app/config.py.


16
난 그냥 추가 touch path/to/fileDockerfile그래서 나는 여전히 파일 (안 만들어 DIR) 될 마운트 할 때
샤디

8
왼쪽 :은 전체 경로 여야합니다. 그것은 이런 식으로 작동합니다
sdkks

touch대답이었다 Dockerfile에 다음 고정 표시기-작성 볼륨 디렉토리 생성하지 않고 제대로 작동 마운트 그렇게
ctrlbrk을

27

볼륨 ( ) 대신 마운트 ( --mount)를 사용하십시오.-v

자세한 정보 : https://docs.docker.com/storage/bind-mounts/

예:

/tmp/a.txt가 docker host에 있는지 확인하십시오.

docker run -it --mount type=bind,source=/tmp/a.txt,target=/root/a.txt alpine sh

감사합니다 Subbu, @Jakub Juszczak 이것은 허용되는 답변이어야합니다. 그것은 질문에 전혀 대답하는 유일한 답변이며, 저에게
효과적

2
이것은 실제로 질문에 대답하지 않습니다. 문제가 절대 경로에 있기 때문에 볼륨 도 잘 작동합니다. 볼륨의 호스트 부분이 아직없는 경우 --mount-v동작 의 유일한 차이점 은 동작입니다. 링크에 따라 :> -v 또는 --volume을 사용하여 Docker 호스트에 존재하지 않는 파일 또는 디렉토리를 바인드 마운트하는 경우 -v는 엔드 포인트를 작성합니다. 항상 디렉토리로 작성됩니다.
대부

2
이것을 docker-compose로 변환하는 방법을 모르겠습니다. '작은 도움?
msanford

@msanford 대답에 도커 작성 예제를 추가했습니다.
sebisnow

10

나와 같은 Windows 컨테이너를 사용하는 사람은 Windows 컨테이너를 사용하여 단일 파일을 바인딩하거나 마운트 할 수 없습니다.

컨테이너 내부의 볼륨 또는 바인드 마운트 대상은 존재하지 않거나 비어있는 디렉토리 중 하나 여야하므로 Windows 기반 컨테이너를 사용할 때 다음 예제는 실패합니다. 또는 C : 이외의 드라이브 또한 바인드 마운트의 소스는 파일이 아닌 로컬 디렉토리 여야합니다 .

net use z: \\remotemachine\share

docker run -v z:\foo:c:\dest ...

docker run -v \\uncpath\to\directory:c:\dest ...

docker run -v c:\foo\somefile.txt:c:\dest ...

docker run -v c:\foo:c: ...

docker run -v c:\foo:c:\existing-directory-with-contents ...

발견하기는 어렵지만 거기에 있습니다.

파일을 Windows 컨테이너에 매핑하는 것과 관련된 Github 문제에 연결


7

나를 위해 일한 방법은 bind마운트 를 사용하는 것입니다

  version: "3.7"    
  services:
  app:
    image: app:latest
    volumes:
      - type: bind
        source: ./sourceFile.yaml
        target: /location/targetFile.yaml

대답을 주셔서 감사합니다 마이크 품종에서 이상 : 고정 표시기-작성을 사용하여 볼륨에서 마운트 하나의 파일

bind마운트 를 표현하려면 "긴 구문"을 사용해야합니다 . https://docs.docker.com/compose/compose-file/#long-syntax


6

다음 docker-compose.yml과 같이 파일 의 상대 경로를 사용할 수도 있습니다 (Windows 호스트, Linux 컨테이너에서 테스트).

 volumes:
      - ./test.conf:/fluentd/etc/test.conf

1
docker-compose 버전 1.24.1, 빌드 4667896b version: '3.7'가있는 docker-compose.yml파일에 지정된 Mac에서 이것을 테스트 하고 작동했습니다.
Acumenus

6
여전히 파일 대신 디렉토리를 얻습니다.
chovy

6

docker-compose 파일 버전 3.2부터는 기본 파일 "volume"대신 "bind"유형의 볼륨 마운트를 지정 하여 단일 파일을 컨테이너에 마운트 할 수 있습니다. docker-compose 볼륨 문서에서 "바인드 마운트"를 검색 하십시오 . https://docs.docker.com/compose/compose-file/#volumes

필자의 경우 로컬 개발 및 테스트 용 비밀 만 포함 된 단일 ".secrets"파일을 내 응용 프로그램에 마운트하려고했습니다. 프로덕션 환경에서는 애플리케이션이 대신 이러한 비밀 정보를 AWS에서 가져옵니다.

약식 구문을 사용하여이 파일을 볼륨으로 마운트 한 경우 :

volumes:
 - ./.secrets:/data/app/.secrets

Docker는 컨테이너 외부의 파일에 매핑하는 대신 컨테이너 내에 ".secrets" 디렉토리를 만듭니다 . 내 코드는 "IsADirectoryError : [Errno 21] 디렉토리가 '.secrets'"와 같은 오류를 발생시킵니다.

읽기 전용 "바인드"볼륨 마운트를 사용하여 비밀 파일을 지정하는 대신 긴 구문을 사용하여이 문제를 해결했습니다.

volumes:
 - type: bind
   source: ./.secrets
   target: /data/app/.secrets
   read_only: true

이제 Docker는 내 .secrets 파일을 컨테이너에 올바르게 마운트하여 디렉토리 대신 컨테이너 내부에 파일을 만듭니다. 다른 사람들이이 예가 도움이 되길 바랍니다!


감사합니다! 이것이 제가 WordPress wp-config.php 파일을 마운트 (및 디렉토리로 생성되는 것을 중지)하는데 필요한 솔루션이었습니다
Jono

0

나에게 문제는 컨테이너에 마운트하려고하는 파일에 깨진 심볼릭 링크가 있다는 것입니다


0

Windows에서도 같은 문제가 발생했습니다 Docker 18.06.1-ce-win73 (19507).

Docker 설정 패널을 통해 공유 드라이브를 제거했다가 다시 추가하면 모든 것이 다시 작동했습니다.


0

Windows에서 docker-compose.yml에 $ {PWD} env 변수가 필요한 경우 docker-compose.yml 파일과 동일한 디렉토리에 .env 파일을 작성한 다음 폴더 위치를 수동으로 삽입 할 수 있습니다.

CMD (pwd_var.bat) :

echo PWD=%cd% >> .env

Powershell (pwd_var.ps1) :

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'; echo "PWD=$(get-location).path" >> .env

: 더 좋은 기능이 고정 표시기-작성 .env의 변수들을 수 있습니다 https://docs.docker.com/compose/reference/envvars/을 특히 대한 COMPOSE_CONVERT_WINDOWS_PATHS고정 표시기의 작성이 baskslash와 윈도우 경로를 승인 할 수 있도록 ENV 변수 "\".

Windows에서 파일을 공유하려면 파일을 컨테이너와 공유하기 전에 파일이 존재해야합니다.


docker와 함께 PowerShell을 사용할 수 없으며 공급 업체 잠금을 생성하고 커뮤니티를
손상시킵니다

0

아마도 이것은 누군가를 도울 것입니다.

나는이 문제가 있었고 모든 것을 시도했다. 볼륨 바인딩이 잘 보였고 디렉토리 (파일이 아님)를 마운트 한 경우에도 마운트 된 디렉토리에 파일 이름이 있지만 디렉토리로 마운트되었습니다.

공유 드라이브를 다시 활성화하려고 시도했으며 Docker가 방화벽이 활성화되었다고 불평했습니다.

방화벽을 비활성화 한 후 모든 것이 제대로 작동했습니다.


감사합니다! 귀하의 게시물을 통해 내 selinux가 적용되도록 설정되어 내 문제가 모두 발생했음을 알게되었습니다. 왜 귀하가 다운 투표를했는지 몰라 ¯_ (ツ) _ / ¯
Octavian

0

소스 파일 또는 디렉토리에 따라 파일 또는 디렉토리 / 폴더를 모두 마운트 할 수 있습니다. 또한 전체 경로를 제공해야하거나 PWD를 사용할 수 있는지 확실하지 않은 경우. 다음은 간단한 작업 예입니다.

이 예에서는 작업 디렉토리에 이미 존재하는 env-commands 파일을 마운트하고 있습니다.

$ docker run  --rm -it -v ${PWD}/env-commands:/env-commands aravindgv/eosdt:1.0.5 /bin/bash -c "cat /env-commands"

-1

내 Windows 8.1에서 동일한 문제가 있습니다

그것은 경로의 대소 문자 구분 때문인 것으로 나타났습니다. 나는라는 docker-compose up디렉토리 cd /c/users/alex/와 파일이 디렉토리가되었습니다 내부 용기.

그러나 내가 cd /c/Users/alex/(사용자가 대문자로 하지 않았 음) docker-compose up거기에서 전화했을 때 효과가있었습니다.

내 시스템에서는 Users 디렉토리와 Alex 디렉토리가 모두 대문자로 표시되지만 Users 디렉토리 만 나타납니다.

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