使用 Docker 在卷中掛載單個文件
一、概述
眾所周知,我們可以使用 Docker 將我們的應用程序容器化,從而使軟件交付更容易。除了僅嵌入我們的應用程序外,我們還可以使用各種選項擴展目標容器,例如掛載外部文件。
在本教程中,我們將專注於使用 Docker 掛載單個文件,並展示不同的方法。此外,我們將討論此過程中的常見錯誤以及如何修復它們。
2. 在 Docker 中持久化數據
在繼續之前,讓我們快速回顧一下 Docker 如何管理應用程序數據。
我們知道Docker 為每個正在運行的容器創建了一個隔離的環境。默認情況下,文件存儲在內部容器的可寫層上。這意味著當容器不再存在時,在容器內所做的任何更改都將丟失。
為了防止數據丟失,Docker 提供了兩種將文件持久化到主機的主要機制:捲和綁定掛載。
卷由 Docker 自己創建和管理,外部進程不應修改它們。另一方面,綁定掛載可以由主機系統存儲和管理,而不會阻止非 Docker 進程編輯數據。
為了實現我們的目標,我們將關注綁定機制。
3. 使用 Docker CLI 綁定文件
與 Docker 交互的最簡單方法是使用專用的 Docker CLI,該 CLI 使用配置標誌執行各種命令。眾所周知,要創建單個容器,我們可以使用docker run
命令和所需的圖像:
docker run alpine:latest
根據官方參考, run
命令支持許多允許預配置容器的附加選項。讓我們看一下可用選項的列表:
--mount
Attach a filesystem mount to the container
--volume , -v
Bind mount a volume
**兩者的工作方式相似,允許我們在本地持久化數據**。現在讓我們來看看它們中的每一個。
3.1。 –mount
選項
–mount
選項的語法由多個鍵值對組成,使用<key>=<value>
元組。鍵的順序不重要,用逗號分隔多對。
首先,讓我們在工作目錄中創建一個虛擬文件:
$ echo 'Hi Baeldung! >> file.txt
要將單個本地文件掛載到容器中,我們可以擴展之前的run
命令:
$ docker run -d -it \
--mount type=bind,source="$(pwd)"/file.txt,target=/file.txt,readonly \
alpine:latest
我們剛剛創建並啟動了一個安裝本地文件的新容器。現在讓我們看一下配置鍵。
該type
使用可用值指定安裝機制: bind
、 volume,
或tmpfs
。在我們的例子中,我們應該始終為bind
設置一個值。
source
(或者 - src
)是主機上應該掛載的文件或目錄的絕對路徑。我們也可以使用本地 shell 命令來計算結果。
target
(或者 - destination, dst
)採用文件或目錄安裝在容器內的絕對路徑。
最後,還有一個readonly
選項使綁定掛載成為只讀。該標誌是可選的。
最後,我們來驗證一下掛載結果:
$ docker exec ... cat /file.txt
Hi Baeldung!
我們還可以檢查容器詳細信息,使用docker inspect
命令檢查所有掛載:
"Mounts": [
{
"Type": "bind",
"Source": ".../file.txt",
"Destination": "/file.txt",
"Mode": "",
"RW": false,
"Propagation": "rprivate"
}
],
現在,我們可以看看與路徑相關的常見錯誤。如果我們提供非絕對路徑,Docker CLI 將返回一個終止命令執行的錯誤:
docker: Error response from daemon: invalid mount config for type "bind": invalid mount path: 'file.txt+' mount path must be absolute.
有時我們會提供主機上缺少的文件的絕對源路徑。在這種情況下,容器將開始在目標路徑中掛載一個空目錄。此外,如果我們在 Windows 上工作,我們 **應該注意路徑轉換**。
3.2. –volume
選項
正如我們之前提到的,我們可以用相同的功能替換–mount
和–volume
( –v)
標誌。我們還必須記住,語法是完全不同的。
–volume
語法由三個字段組成,用冒號分隔。此外,值的順序很重要。
讓我們使用–v
選項轉換前面的示例:
$ docker run -d -it
-v "$(pwd)"/file.txt:/file.txt:ro \
alpine:latest
結果是一樣的。我們剛剛將本地文件掛載到容器中。
正如我們所看到的, –v
選項給出的三個值與–mount
標誌使用的鍵相似。
第一個值與source
鍵一樣,指定主機上文件或目錄的路徑。
第二個字段提供容器內的路徑和target
鍵。
最後,我們有一個可選的ro
選項,用於指定read-only
屬性。
在我們檢查語法之後,讓我們看看一些常見的錯誤。和以前一樣,我們應該記住 Windows 路徑分隔符。選擇一個不存在的文件也會導致創建一個空目錄。
但與非絕對路徑略有不同。如果我們提供了**第二個值的無效路徑,與之前一樣,Docker CLI 將返回一個錯誤**。但是,如果我們提供這樣的路徑作為源值,Docker 將創建一個命名卷,這是另一種持久化文件的機制。
總之, –mount
和–volume
標誌之間最顯著的區別在於它們的語法。我們可以互換使用它們。
4. 使用 Docker Compose 綁定文件
在我們學習瞭如何使用 Docker CLI 綁定文件之後,現在讓我們檢查是否仍然可以使用 docker-compose 文件獲得相同的結果。
眾所周知,docker-compose 是一種通過提供配置文件來創建容器的便捷方式。對於每個服務,我們可以聲明**一個volumes
部分來配置綁定選項**。 volumes
部分可以使用長語法或短語法來指定,它們分別與–mount
和–volumes
標誌有很多共同之處。
4.1。長語法
長語法允許我們單獨配置每個鍵以指定卷安裝。使用相同的示例,讓我們準備一個 docker-compose 條目:
services:
alpine:
image: alpine:latest
tty: true
volumes:
- type: bind
source: ./file.txt
target: file.txt
read_only: true
與 Docker CLI 一樣,我們的容器現在已預先配置為在其中掛載本地文件。我們使用type
、 source
、 target,
和可選的read_only
鍵來確定 configuration ,就像我們使用–mount
標誌一樣。此外,我們可以使用從 docker-compose 文件計算的相對路徑作為source
值。
4.2.短句法
簡短語法使用由冒號分隔的單個字符串值**來指定卷掛載**:
services:
alpine:
image: alpine:latest
tty: true
volumes:
- ./file.txt:/file.txt:ro
該字符串與–volume
標誌幾乎相同。前兩個值分別代表源路徑和目標路徑。最後一部分指定了額外的標誌,我們可以在其中指定只讀屬性。與長語法一樣,我們也可以使用相對源路徑。
我們必須記住,長格式允許我們配置不能用短語法表達的附加字段。此外,我們可以在單volumes
部分混合兩種語法。
5. 結論
在本文中,我們剛剛介紹了 Docker 中數據持久性的一部分。我們嘗試使用 Docker CLI 和 docker-compose 文件在容器中掛載單個本地文件。
Docker CLI 提供帶有run
命令的–mount
和–volume
選項來綁定單個文件或目錄。這兩個標誌的工作方式相似,但語法不同。因此,我們可以互換使用它們。
我們也可以使用 docker-compose 文件達到相同的結果。在每個服務的volumes
部分中,我們可以使用長語法或短語法來配置卷掛載。和以前一樣,這些語法可以互換地產生相同的結果。