簡體   English   中英

在 Docker 中作為目錄安裝的單個文件卷

[英]Single file volume mounted as directory in Docker

Docker 文檔說可以將單個文件掛載到 Docker 容器中:

-v 標志還可用於從主機掛載單個文件 - 而不僅僅是目錄。

$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

這將使您進入新容器中的 bash shell,您將擁有來自主機的 bash 歷史記錄,當您退出容器時,主機將擁有在容器中鍵入的命令的歷史記錄。

但是,當我嘗試該文件時,該文件會掛載為目錄:

tom@u ~/project $ docker run --rm -it -v file.json:/file.json test
total 80K
drwxr-xr-x  9 root root 4.0K Dec  7 12:58 .
drwxr-xr-x 63 root root 4.0K Dec  7 12:58 ..
drwxr-xr-x  2 root root 4.0K Dec  4 16:10 file.json

我的 Dockerfile 看起來像這樣:

FROM ubuntu:14.04
MAINTAINER Tom
CMD ["ls", "-lah", "/test"]

Docker 版本為 1.9.1,構建 a34a1d5。

這是文檔問題,是我的誤解,還是還有其他問題?

也許在上面的答案中很清楚......但我花了一些時間才弄清楚我的情況。

導致使用 -v 共享的文件顯示為目錄而不是文件的根本原因是 Docker 在主機上找不到該文件。 因此 Docker 在容器中創建一個新目錄,名稱是主機上不存在的文件的名稱,因為 docker 認為用戶只是想共享一個將來會創建的卷/目錄。

所以在上面報告的問題中,如果你在 -v 命令中使用了相對目錄,而 docker 不理解相對目錄,那意味着在主機上找不到該文件,因此 docker 創建了一個目錄。 當問題是由於相對目錄時,上面建議使用 $(pwd) 的答案將是正確的解決方案。

但是對於那些閱讀此頁面的人來說,他們沒有使用相對目錄並且遇到同樣的問題......然后嘗試了解為什么主機上缺少文件。

這可能只是一個愚蠢的錯字......

可能是您正在從客戶端運行“docker run”命令,該命令在不同的主機上生成 docker 容器,並且正在共享的文件在該不同的主機上不存在。 與 -v 共享的文件必須存在於 docker 代理將生成容器的主機上......不一定在執行“docker run -v ...”命令的客戶端上(盡管它們在許多情況)。

對於 Mac 和 Windows,上面還有其他可能的解釋……也可能是這樣。

因此,主機中丟失的文件是問題所在……解決設置中的問題……使用 $(pwd) 可能是解決方案,但並非總是如此。

test是您使用“ docker build -t testdocker build -t test圖像的名稱,而不是/test文件夾。

嘗試使用Dockerfile

CMD ["ls", "-lah", "/"]
or
CMD ["cat", "/file.json"]

和:

docker run --rm -it -v $(pwd)/file.json:/file.json test

請注意使用$(pwd)以安裝具有完整絕對路徑的文件(不支持相對路徑)

通過使用$(pwd) ,您將獲得一個確實存在的絕對路徑,並尊重大小寫,而不是可能不存在的文件名或路徑。
不存在的主機路徑將作為文件夾安裝在容器中。

我花了一些時間來解決和診斷在 Windows 上運行 docker 的這個問題。 這也可能影響在 Mac OSX 上運行的人,因此我在此處為可能在這些環境中遇到問題的人添加了一個答案,因為我的搜索將我帶到了這個地方,並添加了對 docker 中似乎發生的事情的解釋。

在 Windows 或 Mac OSX 中,您的 docker 實際上是在 boot2docker VM 中運行的,並且默認情況下實際上只有用戶目錄是共享的。 在 Windows 上,這個用戶目錄被共享為 /c/Users/,但是在 Docker Machine 附帶的 MinGW shell 中,驅動器可以作為 /C 或 /c 訪問,所以如果你忘記了 docker 命令,這會讓你抓狂實際上針對 boot2docker VM 運行,並且您的文件路徑必須存在於 boot2docker VM 上,並以它們在那里存在的方式指定,因為 docker 中似乎發生的是,而不是給出目錄/文件所做的警告或錯誤不存在,docker 會在 boot2docker VM 中靜默創建指定的源作為目錄,因此沒有准備好的輸出表明您正在做任何不正確的事情。

因此,與上面的答案一樣,如果您的文件安裝為目錄,請檢查您是否提供了絕對路徑。 對於 Windows 和 Mac OSX,請檢查您安裝的絕對路徑是否存在於您的 boot2docker VM 中。

在 docker 中運行 docker 時(例如通過掛載/var/run/docker.sock ),您需要注意,如果您在 docker 中掛載,則使用的文件路徑始終是您主機上的文件路徑。

因此,如果在您的主機上執行以下掛載:

-v /tmp/foobar.txt:/my/path/foobar.txt

應該做以下安裝內泊塢窗:

-v /my/path/foobar.txt:/my/other/path.txt

而是使用主機文件路徑,例如:

-v /tmp/foobar.txt:/my/other/path.txt

Docker 可能找不到文件的情況,即使您確定它存在

正如 edi9999 指出的那樣,如果你告訴 docker 守護進程掛載一個文件,它不會查看你當前容器的文件系統,它會查看運行守護進程的文件系統。

如果您的 docker 守護程序出於某種原因在其他地方運行,您可能會遇到此問題。

❯ docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock docker
/ # echo "bar" > /foo
/ # docker run --rm -v /foo:/foo ubuntu bash -c 'cat foo'
cat: foo: Is a directory

Docker 在它的主機上找不到 /foo 文件,所以它(有用?)在那里創建一個目錄,所以至少你已經安裝了一些東西。

解決方法

您可以通過將主機目錄安裝到外部容器中,然后將該目錄用於要出現在內部容器中的卷來解決此問題:

❯ docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v /dev/shm:/dev/shm docker
/ # echo "bar" > /dev/shm/foo
/ # docker run --rm -v /dev/shm/foo:/dev/shm/foo ubuntu bash -c 'cat /dev/shm/foo'
bar

這使得路徑/dev/shm/foo在任一上下文中都引用同一個文件,因此您可以從外部容器引用該文件,守護進程將在主機上找到它,這意味着它將在內部容器,而不是目錄。

對於那些使用 VirtualBox 機器的人來說,有一個簡單的解決方案。 默認情況下,添加 C:/User 文件夾。 如果您的項目在 C:/projects 中,請添加此文件夾以使其在 VB 中可用(使用自動掛載)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM