跳至主要内容

5.4 為你的 volume 命名

顯然抽抽樂去對應容器不是一個有效率且聰明的作法,所以可以透過替 volume 命名來讓人類可以透過肉眼輕易的分辨出區別。

回到最一開始啟動容器時的指令,可以透過加入 --volume 的指令,來告訴 Docker 要對應的 volume 名字是什麼。

$ docker container run --detach --name mysql --env MYSQL_ROOT_PASSWORD=whatever --volume /var/lib/mysql mysql # 不要輸入這段指令,是錯誤的

請你先別急著下指令,上面雖然加入了 --volume 的指令並且目的地也是 mysql 這個映像檔本身資料庫檔案存放的位置,但上述的寫法其實和沒寫是一樣的,因為 VOLUME /var/lib/mysql 早就被定義在 Dockerfile 裡面了不是嗎?

所以應該在目的地的前方加上 volume 的名字,像是這樣:

$ docker container run --detach --name mysql --env MYSQL_ROOT_PASSWORD=whatever --volume mysql-data:/var/lib/mysql mysql # 不換行
827b118d0aa7c8f83415e66d2a49106....

注意到了嗎?只需要在目的地的前方加上要取的 volume 名字,並且用冒號進行連接,就能夠建立一個有名字的 volume 並且連接到 /var/lib/mysql 這個路徑。

接著列出所有的 volume 看看,是不是真的有效。

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

接著執行 docker volume inspect 指令試看看,是不是一切都變得易讀多了呢?

也可以輕鬆地透過名字來分辨這個 volume 是哪一個容器要用的。

$ docker volume inspect mysql-data
[
{
"CreatedAt": "2022-09-17T14:13:56Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql-data/_data",<-易讀
"Name": "mysql-data", <-易讀
"Options": null,
"Scope": "local"
}
]

除了在容器啟動時直接輸入 volume 的名字,如剛剛範例中的 mysql-data:/var/lib/mysql 之外,也可以手動的提前建立好 volume,並連接到容器上。

$ docker volume create whatever
whatever

volume 的共用性

前面有提過可以把 volume 連接到任何想要連接容器上面,所以這邊再次啟動一個 mysql 的容器,並且把剛剛的 mysql-data 連接到新的容器上。

先刪除掉目前所有的容器。

$ docker container rm --force $(docker container ls --all --quiet)

接著再次啟動一個 mysql 的容器。

$ docker container run --detach --name mysql --env MYSQL_ROOT_PASSWORD=whatever --volume mysql-data:/var/lib/mysql mysql # 不換行
63b9256b6c9addc1334de9ccf41293....

接著列出所有的 volume。

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

可以看到,新的 mysql 容器建立的時候,因為有給予 volume 名字的關係,Docker 會發現已經有一個存在的 mysql-data volume,就不再用 SHA 隨機產生一個 volume 了。

利用 docker container inspect 的方式,也可以確定新的容器連接上的 volume 確實是 mysql-data 沒錯。

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

這邊會發現 Name 以及 Source 都和 mysql-data 相符,也證明了 volume 的共用性,是可以再容器之間共享的。

還有另外一個指令可以參考,若是我們希望和某一個容器共用同一個 volume,則可以使用 --volumes-from 的指令:

$ docker container run --detach --name mysql2 --env MYSQL_ROOT_PASSWORD=whatever --volumes-from mysql mysql # 不換行
e8b1d30c4f4387a0110fd1619553349e51489d3c...

這邊的 mysql2 這個容器就會和 mysql 這個容器使用相同的 volume。

但這僅限於是同一種服務,畢竟每一個服務要存放檔案的目的地路徑都不相同,若是這邊明明啟動的是一個 redis 的服務,但卻 --volumes-from mysql,雖然不會壞掉,但也沒有任何意義就是了。