programing

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

lovejava 2023. 8. 2. 08:36

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

저는 PHP 애플리케이션을 도커화하려고 합니다.도커 파일에서, 나는 아카이브를 다운로드하고, 압축을 푸는 등의 작업을 합니다.

모든 것이 잘 작동합니다.그러나 새 버전이 출시되고 도커 파일을 업데이트하면 구성 때문에 애플리케이션을 다시 설치해야 합니다.php는 덮어씁니다.

그래서 저는 데이터베이스에서처럼 파일을 볼륨으로 마운트할 수 있다고 생각했습니다.

저는 볼륨과 직접 경로의 두 가지 방법으로 시도했습니다.

도킹 스테이션:

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/sys/config.sys\"로 인해 \"디렉토리가 아님\"""

저랑 같이 해보면.

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

Docker는 업로드 폴더를 생성한 다음 config.php 폴더를 생성합니다.파일이 아닙니다.

아니면 구성을 유지할 수 있는 다른 방법이 있습니까?

TL;DR/통지:

마운트하려는 파일 대신 디렉토리가 생성되는 경우 유효하고 절대적인 경로를 제공하지 못했을 수 있습니다.이는 침묵하고 혼란스러운 고장 모드에서 흔히 볼 수 있는 실수입니다.

파일 볼륨은 도커에서 다음과 같은 방식으로 수행됩니다(절대 경로 예제(환경 변수 사용 가능). 파일 이름을 언급해야 합니다).

    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/myappfolder

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

제 말은 아래 명령이 매핑될 것이라고 생각했다는 것입니다.$(pwd)/config.py에서 도커 호스트로/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.

가 있었던 은 제게효있방은법던었을 입니다.bind

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

마이크 종류의 답변에 감사드립니다: 도커 합성을 사용하여 볼륨에서 단일 파일을 마운트합니다.

구문하여 "long syntax"를 .bind를사여마트를 사용하여 .volumes키: https://docs.docker.com/compose/compose-file/compose-file-v3/ #long-delay-3

마운트 사용(--mount) 대신 볼륨(-v)

더 많은 정보: https://docs.docker.com/storage/bind-mounts/

예:

/tmp/a를 확인합니다.도커 호스트에 txt가 있습니다.

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

도커 합성 파일 버전 3.2에서 컨테이너에 단일 파일을 마운트할 수 있는 "bind"(기본 유형 "volume" 대신) 유형의 볼륨 마운트를 지정할 수 있습니다.도커로 검색된 볼륨 문서에서 "스캐너 마운트"를 검색합니다. https://docs.docker.com/compose/compose-file/ #http://#

저의 경우, 저는 로컬 개발 및 테스트 전용 비밀이 포함된 단일 ".secret" 파일을 애플리케이션에 마운트하려고 했습니다.운영 환경에서 제 애플리케이션은 대신 AWS에서 이러한 비밀을 가져옵니다.

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

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

도커는 컨테이너 외부의 파일에 매핑하는 대신 컨테이너 내부에 ".secrets" 디렉터리를 만듭니다.그러면 코드에서 "IsADirectoryError: [Errno 21] Is directory: '.secrets'"와 같은 오류가 발생합니다.

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

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

이제 Docker는 내 .secrets 파일을 컨테이너에 올바르게 마운트하여 디렉터리 대신 컨테이너 내부에 파일을 만듭니다.

위의 답변은 모두 정답입니다.

하지만 마운트된 파일이 도커 호스트 안에 미리 존재해야 하며 그렇지 않으면 도커가 대신 디렉터리를 만들 입니다.

예:

/a/file/inside/host/hostFile.txt:/a/file/inside/container/containerFile.txt

hostFile.txt미리 존재해야 합니다.그렇지 않으면 다음 오류가 표시됩니다.containerFile.txt is a directory

나처럼 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 문제에 대한 링크

상경 사를수있다니습에서 .docker-compose.yml다음과 같은 파일(Windows 호스트, Linux 컨테이너에서 테스트됨):

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

작성 시 상대 경로를 사용하고 있으며 작동합니다.

version: "3.7"
services:
    svc1: 
      volumes:
        # Current dir is parent of src
        - "./src/file.conf:/path/in/container/file.conf 

용사를 합니다.docker run마운트 파일을 바인딩하는 명령은 다음을 생성합니다.

docker: Error response from daemon: invalid mount config for type "bind": invalid mount path: 'path/file.conf' mount path must be absolute. 
See 'docker run --help'.

이를 위한 유일한 방법은 다음과 같이 절대 마운트 경로를 지정하는 것입니다.

docker run -it --rm --mount type=bind,source="/path/to/file.conf",target=/file.conf alpine sh

한사용 사용"%cd%"윈도우즈 사용자 또는"$(pwd)"Linux 사용자용은 절대 경로를 처리하는 방법입니다.

스토리지 바인딩 마운트 참조

Visual Studio Code Users의 경우 PowerShell이 아닌 명령 프롬프트 터미널에서 %cd% 명령을 실행하고 있는지 확인합니다.

원본 파일 또는 디렉터리에 따라 파일 또는 디렉터리/폴더를 마운트할 수 있습니다.또한 전체 경로를 제공하거나 PWD를 사용할 수 있는지 확신할 수 없는 경우에도 제공해야 합니다.다음은 간단한 작업 예제입니다.

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

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

TL&DR: 도커는 모든 마운트 지점을 디렉터리로 기본 설정합니다.파일이 도커 인스턴스에 마운트되었는지 확인하려면 도커 합성 및 실행 전에 파일이 이미 존재해야 합니다.

설명:

전통적으로 볼륨을 마운트하는 목적은 항상 디렉터리에 저장 위치를 마운트하는 것을 의미했습니다.그러나 이제는 파일을 공유할 수 있게 됨에 따라 변화하고 있습니다.프로그래머의 관점에서 "/tmp/something"이 파일인지 디렉터리인지 알기 어렵습니다.따라서 Docker는 파일이 이미 존재하지 않는 한 모든 마운트 지점이 먼저 디렉토리라고 가정합니다.

이 예에서는 파일을 마운트하려면 해당 파일이 호스트 시스템에 이미 있는지 확인합니다.Docker는 이 항목이 이미 존재하는 것을 확인하면 파일을 Docker 환경에 마운트합니다.

원격 가상 시스템에서 도커와 함께 작동하기 위해 도커 컨텍스트를 사용하는 경우에는 주의해야 합니다.이 경우 마운트하려는 파일이 대상 VM에 존재하지 않습니다.따라서 존재하지 않는 파일이 폴더로 마운트됩니다.

저도 같은 문제가 있었습니다. 도커 컴포지트는 파일 대신 디렉터리를 만들고 중간에 충돌하는 것이었습니다.

내가 한 일:

  1. 파일을 매핑하지 않고 컨테이너 실행

  2. 구성 파일을 호스트 위치에 복사합니다.

    docker cp 컨테이너 이름: /var/www/docker/config.docker ./config.docker

  3. 용기를 제거합니다(용기를 아래로 향하게 합니다).

  4. 매핑을 원래대로 되돌리고 용기에 다시 장착합니다.

도커 컴포지트는 디렉토리를 만드는 대신 구성 파일을 찾고 매핑합니다.

2022 답변, Mac에서 Minikube/Hyperkit 도커 및 도커 컴포지트 사용

더 이상 Docker Desktop을 사용하지 않기 때문에 미니큐브를 사용하는 "Docker in Docker (dind)" 패러다임과 유사한 문제를 많이 경험했습니다.

  1. 미니큐브를 장착합니다.
  2. 절대 경로를 사용합니다.

예를 들어, 가장 쉬운 방법은 정확한 홈 경로를 탑재하는 것이었습니다.

minikube mount $HOME:/Users/<you>

... keeps running...

도커식의

volumes:
      - /Users/<you>/path/to/file.yaml:/somedir/file.yaml

문제는 컨테이너에 마운트하려는 파일의 심볼릭 링크가 끊어졌다는 것입니다.

에서도 같은 .Docker 18.06.1-ce-win73 (19507).

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

윈도우에서 도커 구성에 ${PWD} 환경 변수가 필요한 경우.yml 당신은 당신의 도커-docer.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

도커-docker.env 변수에 대한 더 많은 좋은 기능들이 있습니다: https://docs.docker.com/compose/reference/envvars/ 은 특히,COMPOSE_CONVERT_WINDOWS_PATHS를 사용하여 창 할 수 하는 env baskslash를 사용합니다."\".

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

누군가에게 도움이 될 수도 있습니다.

저는 이 문제가 있었고 모든 것을 시도했습니다.볼륨 바인딩은 정상적으로 보였고 (파일이 아닌) 디렉터리를 마운트하더라도 마운트된 디렉터리에 파일 이름이 올바르게 있지만 dirs로 마운트되었습니다.

공유 드라이브를 다시 활성화하려고 했는데 도커가 방화벽이 활성화되어 있다고 불평했습니다.

방화벽을 비활성화한 후 모든 것이 정상적으로 작동했습니다.

저는 소스 파일을 잘못 지정한 것이 문제였습니다.

다음은 예입니다.

 robert ❱ ~ ❱ docker run --rm -it -v "${PWD}/non-existant:/root/destination" -w /root --entrypoint /usr/bin/ls ubuntu -lad destination
drwxr-xr-x 2 root root 64 Mar 29 05:54 destination
 robert ❱ ~ ❱ touch exists
 robert ❱ ~ ❱ docker run --rm -it -v "${PWD}/exists:/root/destination" -w /root --entrypoint /usr/bin/ls ubuntu -lad destination
-rw-r--r-- 1 root root 0 Mar 29 05:58 destination
 robert ❱ ~ ❱

TL;DR - 저처럼 철자가 맞을 수 있습니다.

실제로 원본 dir에 마운트할 파일을 포함하는 것을 잊어버린 경우에도 이 문제가 발생하는 것 같습니다.저는 힘들게 배웠어요.'file not present'와 같은 오류 메시지가 없으면 대신 대상에 디렉터리를 만듭니다.

Windows 8.1에서도 동일한 문제가 발생했습니다.

그것은 경로의 대소문자 구분 때문인 것으로 밝혀졌습니다.전화해봤어요.docker-compose up디렉토리에서cd /c/users/alex/그리고 컨테이너 안에 파일이 디렉토리로 바뀌었습니다.

하지만 내가 했을 때cd /c/Users/alex/(사용자 대문자로 표시되지 않음) 및 호출됨docker-compose up거기서부터, 효과가 있었습니다.

내 시스템에서 Usersdir와 Alexdir는 모두 대문자로 표시되지만 Usersdir만 중요한 것처럼 보입니다.

언급URL : https://stackoverflow.com/questions/42248198/how-to-mount-a-single-file-in-a-volume