Docker Compose Yaml Volumes

根據之前的文章我們了解到創建 Volume 有兩種方式一種是在 Dockerfile 設定 VOLUMES 指令,文章地址
另一種方式則是透過 Docker Cli 的方式先使用 Cli 建立好 Volume 之後在透過 docker run 啟動時帶入-v參數即可使用到剛剛設定的 Volume,文章地址
並且還有其他兩種做資料持久化的方式,一個是使用 Bind mount 直接將 Host 目錄綁定到 container 內部, 令一種則是特殊的 tmpfs 方式,能直接把資料寫入到 Host 的記憶體內部,文章地址

以上提到的方式都可以在 Docker Compose 中實現,文檔地址
首先先建立環境並且輸入以下內容

mkdir mycompose && cd $_
vi docker-compose.yml 
services:
  alpine:
    image: alpine
    tty: true
    stdin_open: true
    volumes:
      - type: volume
        source: db-data
        target: /data-long
      - db-data:/data-short

volumes:
  db-data:

這邊開始就有一些新的語法出現了,首先看到第一層的設定除了我們之前學過得 services 跟它同一階層的還有一個 volumes 這邊的 volumes 第二層有一個 db-data 其實就是為了要跨容器共用同一個 volume 所設計的, 就跟我們手動使用 Cli 建立 volume 效果一樣 docker volume create db-data,只是先創建一個 volume 之後在再與 container 相連起來

接下來是 services 層,下層有兩個設定值 ttystdin_open 其實就是我們經常在使用命令 docker run -dit apline 之中的 -i-t 參數,可以參考之前文章,因為 docker compose 會啟動一連串的 container,所以這種針對單個 container 的設定值
需要在 docker-compose.yml 中添加

最後才是 services 層底下的 volumes,之前只是先設定好到這裡才是真正綁定的地方
首先要注意有兩種寫法 長寫法短寫法,可以按照個人需求使用,不過長寫法功能比較多而且意思較為明確

接下來我們使用命令 docker compose up -d 來運行這個設定檔 我們看看輸出內容看到分別幫我們建立了一個 Network mycompose_default、一個 Volume mycompose_db-data 和一個 Container mycompose-alpine-1

[node1] (local) root@192.168.0.28 ~/mycompose
$ docker compose up -d
[+] Running 2/2
 ⠿ alpine Pulled                                                                                                                                                                                                                                                                    1.0s
   ⠿ 63b65145d645 Pull complete                                                                                                                                                                                                                                                     0.7s
[+] Running 3/3
 ⠿ Network mycompose_default     Created                                                                                                                                                                                                                                            0.2s
 ⠿ Volume "mycompose_db-data"    Created                                                                                                                                                                                                                                            0.0s
 ⠿ Container mycompose-alpine-1  Started  

我們分別使用這三個命令來進行驗證

$ docker network list
NETWORK ID     NAME                DRIVER    SCOPE
8bc072a976fa   bridge              bridge    local
ba443ca8e44d   host                host      local
30d4defd294c   mycompose_default   bridge    local
a4c9cb1ce1c0   none                null      local

[node1] (local) root@192.168.0.28 ~/mycompose
$ docker volume list
DRIVER    VOLUME NAME
local     mycompose_db-data

[node1] (local) root@192.168.0.28 ~/mycompose
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND     CREATED         STATUS         PORTS     NAMES
3415fc0f94a5   alpine    "/bin/sh"   4 minutes ago   Up 4 minutes             mycompose-alpine-1

我們進入 container 內部看看使否 Volume 有綁定成功

docker exec -it 3415fc0f94a5 /bin/sh

確實有剛剛設定的兩個位置 data-longdata-short

/ # ls -l
total 8
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 bin
drwxr-xr-x    2 root     root             6 Mar  9 13:47 data-long
drwxr-xr-x    2 root     root             6 Mar  9 13:47 data-short
drwxr-xr-x    5 root     root           360 Mar  9 13:47 dev
drwxr-xr-x    1 root     root            66 Mar  9 13:47 etc
drwxr-xr-x    2 root     root             6 Feb 10 16:45 home
drwxr-xr-x    7 root     root           243 Feb 10 16:45 lib
drwxr-xr-x    5 root     root            44 Feb 10 16:45 media
drwxr-xr-x    2 root     root             6 Feb 10 16:45 mnt
drwxr-xr-x    2 root     root             6 Feb 10 16:45 opt
dr-xr-xr-x 1898 root     root             0 Mar  9 13:47 proc
drwx------    1 root     root            26 Mar  9 13:55 root
drwxr-xr-x    2 root     root             6 Feb 10 16:45 run
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 sbin
drwxr-xr-x    2 root     root             6 Feb 10 16:45 srv
drwxr-xr-x   13 root     root             0 Jun 13  2021 sys
drwxrwxrwt    2 root     root             6 Feb 10 16:45 tmp
drwxr-xr-x    7 root     root            66 Feb 10 16:45 usr
drwxr-xr-x   12 root     root           137 Feb 10 16:45 var

我們也知道目前這兩個路徑其實是使用同一個 Volume 的,我們可以試著寫入檔案到其中一個路徑
的確兩個目錄都有顯示同一個檔案

/ # touch /data-long/hello
/ # ls -l /data-long
total 0
-rw-r--r--    1 root     root             0 Mar  9 13:56 hello
/ # ls -l /data-short
total 0
-rw-r--r--    1 root     root             0 Mar  9 13:56 hello
/ # 

接下來是 mount bind 和 tmpfs 的寫法

services:
  alpine:
    image: alpine
    tty: true
    stdin_open: true
    volumes:
      - type: bind
        source: /root/mycompose
        target: /data-long-bind
      - /root/mycompose:/data-short-bind
      - type: tmpfs
        target: /my-tmpfs1
    tmpfs: /my-tmpfs2

用法跟 volume 相似只是 source 路徑設定成 Host 底下的資料夾就會成功綁定了
tmpfs 比較特別只支援 長寫法 並且只要輸入 target 路徑即可,或是使用專門的 tmpfs 設定值

完成後運行設定檔並且進入容器看看,確實有多了四個路徑出來

$ docker exec -it f6b9057de3de /bin/sh
/ # ls -l
total 8
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 bin
drwxr-xr-x    2 root     root            32 Mar  9 14:07 data-long-bind
drwxr-xr-x    2 root     root            32 Mar  9 14:07 data-short-bind
drwxr-xr-x    5 root     root           360 Mar  9 14:07 dev
drwxr-xr-x    1 root     root            66 Mar  9 14:07 etc
drwxr-xr-x    2 root     root             6 Feb 10 16:45 home
drwxr-xr-x    7 root     root           243 Feb 10 16:45 lib
drwxr-xr-x    5 root     root            44 Feb 10 16:45 media
drwxr-xr-x    2 root     root             6 Feb 10 16:45 mnt
drwxrwxrwt    2 root     root            40 Mar  9 14:07 my-tmpfs1
drwxrwxrwt    2 root     root            40 Mar  9 14:07 my-tmpfs2
drwxr-xr-x    2 root     root             6 Feb 10 16:45 opt
dr-xr-xr-x 1810 root     root             0 Mar  9 14:07 proc
drwx------    1 root     root            26 Mar  9 14:11 root
drwxr-xr-x    2 root     root             6 Feb 10 16:45 run
drwxr-xr-x    2 root     root          4096 Feb 10 16:45 sbin
drwxr-xr-x    2 root     root             6 Feb 10 16:45 srv
drwxr-xr-x   13 root     root             0 Jun 13  2021 sys
drwxrwxrwt    2 root     root             6 Feb 10 16:45 tmp
drwxr-xr-x    7 root     root            66 Feb 10 16:45 usr
drwxr-xr-x   12 root     root           137 Feb 10 16:45 var

並且確實有跟 Host 底下的資料夾綁定在一起

/ # ls -l /data-long-bind/
total 4
-rw-r--r--    1 root     root           279 Mar  9 14:07 docker-compose.yml
/ # ls -l /data-short-bind/
total 4
-rw-r--r--    1 root     root           279 Mar  9 14:07 docker-compose.yml

Summary

今天學習了如何在 docker-compose.yml 中設定文件持久化,並且擁有多種寫法之後可以按照自己的需求來選用