跳至主要内容

5.3 運行帶有 Volume 指令的映像檔

前兩個小節都只是紙上談兵,根本還沒有真的見到 volume 本人呀,別急,把 mysql 給運行起來吧!

$ docker container run --detach --name mysql --env MYSQL_ROOT_PASSWORD=whatever mysql # 不換行
cc94cfe86706e585f36d60e7dec2a7ffdfcf9ca5ff83f697d8

接著一樣,確認這個容器是真的有在運作,而不是進入退出的狀態。

$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc94cfe86706 mysql "docke..." Abou... Up 3306/tcp, 33.. mysql

確認過後,再次使用 docker container inspect 這個超級好用的指令來看看容器有什麼不一樣!

$ docker container inspect mysql
[
{
...
"Mounts":[
{
"Type": "volume",
"Name": "2c1a7d85be3f0c1079ab0d73b92fd9aadb82...",
"Source": "/var/lib/docker/volumes/2c1a7d../_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
...
}
]

可以觀察到這個容器掛載了一個 volume 在裡面,看到 Destination 的部分,是指容器內部路徑,而 Source 則是指外部的 volume,而這個 volume 的路徑,若是使用 Linux 作業系統的人,可以直接透過 cd 的指令進入到這個資料夾中。

而 macOS 以及 Windows 的使用者,還記得之前的章節提過,macOS 以及 Windows 都是透過迷你的虛擬機在運行 Docker,所以直接 cd 到這個路徑是行不通的,因為資料是存放在迷你的虛擬機中。

這邊可以透過以下指令來列出存活的 volume 。

$ docker volume list
DRIVER VOLUME NAME
local 2c1a7d85be3f0c1079ab0d73b92fd9aadb8204c2....

仔細對比 VOLUME NAME 會發現跟連接到容器的 SHA 值是一樣的,代表寫在映像檔中的 VOLUME 指令,會在沒有指定 volume 的情況下自行建立一個以隨機 SHA 值命名的 volume。

一樣可以透過 inspect 的指令來看到 volume 的詳細資訊,可以透過 docker volume inspect + TAB 的方式,來做到篩選現有的 volume,並且檢查其詳細資訊。

$ docker volume inspect 2c1a7d85be3f0c1079ab0d73....
[
{
"CreatedAt": "2022-09-17T10:46:59Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/2c1a7d85b...",
"Name": "2c1a7d85be3f0c10...",
"Options": null,
"Scope": "local"
}
]

我怎麼知道哪個 volume 接到哪個容器?

突然發現一件事,現在可以透過容器知道現連接的是哪一個 volume,但卻沒辦法從 volume 的角度去看到這個現在連接哪一個容器呀!

若是開啟兩個 MySQL 的服務呢?

$ docker container run --detach --name mysql2 --env MYSQL_ROOT_PASSWORD=whatever mysql # 不換行
35fd131389c0343f0faadc4fbe74b976d216c1fc65cd84b

接著列出所有的 volume 看看。

$ docker volume list
DRIVER VOLUME NAME
local 2c1a7d85be3f0c1079ab0d73b92fd9aadb8204c2....
local 35fd131389c0343f0faadc4fbe74b976d216c1fc....

應該會開始意識到 VOLUME NAME 所帶來的問題,對吧?

從列出 volume 這件事情,我們沒有辦法得到任何有用的資訊,沒辦法知道這是接到哪一個容器。

而如果今天容器被刪除了呢?要知道刪除容器再次重啟是一件稀鬆平常的事情。

$ docker container rm --force mysql mysql2
mysql
mysql2

接著確認所有的容器都被刪除地乾乾淨淨了。

$ docker container list --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

接著再列出 volume,它們並沒有被刪除,就如同前面提到的,volume 正常情況下會需要透過手動來刪除。

$ docker volume list
DRIVER VOLUME NAME
local 2c1a7d85be3f0c1079ab0d73b92fd9aadb8204c2....
local 35fd131389c0343f0faadc4fbe74b976d216c1fc....

但現在好像完蛋了,哪一個 volume 是對應到哪一個容器呢?雖然資料都還在,難不成要像在玩抽抽樂一樣嗎?這個 volume 去對應那個容器試試看好了,不行再換下一個?