# Docker 儲存

[![image-1675737589104.png](https://bookstack.treemanou.com/uploads/images/gallery/2023-02/scaled-1680-/bAEvwM8s8ZONGIss-image-1675737589104.png)](https://bookstack.treemanou.com/uploads/images/gallery/2023-02/bAEvwM8s8ZONGIss-image-1675737589104.png)

### **--mount 與 -v/ --volume**

當在使用 docker create 或是 docker run 的指令時，會有兩個選項可以使用，個別是 --mount 以及 -v (或是 --volume)。

<span class="s1">注意，千萬不要誤以為使用</span> -v <span class="s1">就是用</span> Volume <span class="s1">的方式或者是</span> --mount <span class="s1">就是使用</span> Bind Mount <span class="s1">的方式，不是這樣的！！我們先來看看這兩個在</span> docker create <span class="s1">與</span> docker run <span class="s1">中的說明是甚麼：</span>

```p2
-v, --volume list      Bind mount a volume
    --mount mount      Attach a filesystem mount to the container
```

但其實是可以用 --mount 或 -v 來綁定資料到 Volume，也可以用 --mount 或 -v 來綁定資料到 Filesystem。既然都可以，那為什麼要分兩種呢？

這是因為<span class="s1"> --mount </span>其實出現的比較早，但他設定綁定資料的方式比較完整卻麻煩，因此在後續又出現了<span class="s1"> -v </span>的選項來簡化綁定的設定過程。

---

### **Data Volume**

相關指令

```shell
# 建立volume 
# docker volume create [OPTIONS] [VOLUME]
$docker volume create my-vol

#使用 -v
$ docker run -d --name my-http -v my-vol:/usr/local/apache2 -p 8080:80 httpd
#使用 --mount
$ docker run -d --name my-http --mount source=my-vol,target=/usr/local/apache2 -p 8080:80 httpd
```

```shell
# 列出所有volume
[tomcat@docker]$ docker volume ls
DRIVER              VOLUME NAME
local               2db2d2b1a6ceb9f578d2149dc44625e1996dcc33de0639f8644ce2082182b9a8
local     			my-vol

# 查詢某volume細節
[tomcat@docke]$ docker volume inspect 2db2d2b1a6ceb9f578d2149dc44625e1996dcc33de0639f8644ce2082182b9a8
[
    {
        "CreatedAt": "2019-06-04T15:40:43+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/2db2d2b1a6ceb9f578d2149dc44625e1996dcc33de0639f8644ce2082182b9a8/_data",
        "Name": "2db2d2b1a6ceb9f578d2149dc44625e1996dcc33de0639f8644ce2082182b9a8",
        "Options": null,
        "Scope": "local"
    }
]

[tomcat@docke]$ docker volume inspect my-vol
[
    {
        "CreatedAt": "2023-02-07T02:11:18Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]


# 刪除所有不使用的volume
[tomcat@docker]$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
2db2d2b1a6ceb9f578d2149dc44625e1996dcc33de0639f8644ce2082182b9a8
44d6286d1a793ac8c788b0fd364fa8d9430ce3ec079731dbe894dd996cae9adb
925559f4c2399c0c989d8602ca77fb3243dfb83022fe029b09b130c9521e7f89
9484acbd73c53af47f29add893c5125b0cd7f0f96e521c54e643f1aeb8f97eeb
b47202da45060de8f67e48058966b32078d525cadd1c94671a0ffe33f3d5df4b
006d620ae77bf7530ea37abd48b9c20ac264956f4b9ef3397e2c5072f32677c2
15e0fd2e575c2c24a2a137ff420dbf30326f3859d483561efc45e568d294c802
98b5385b04a401e9e870c5a1e807d69c56a1764b2ec91baedd9c13994cb2c863
ffdae0e84d00966afdc0df55d664d06ee99c14d249ad7558848088c464d472ff

Total reclaimed space: 77.8MB

# 指定volume mount 至 /var/www/html
[tomcat@docker]$ docker run -d -v html_doc:/var/www/html httpd



```

---

### **Bind Mount to FileSystem**

```shell
# 直接mount 外部資料夾 至 /var/www/html
# 相對路徑
[tomcat@docker-qc html-doc]$ docker run -d -v ${PWD}/html-doc:/var/www/html httpd
# 絕對路徑
[tomcat@docker-qc html-doc]$ docker run -d -v /home/tomcat/docker/html-doc:/var/www/html httpd
```

### **Bind Mount to Memory**

Tmpfs，全名 Temporary File System，是在 Linux 暫存檔儲存空間的常見名稱，通常以掛載檔案系統方式實現。他可以將資料儲存在記憶體中而不是存在硬碟內，所以只要一重新開機，資料則會被抹除。

Tmpfs <span class="s1">如其名，如果使用</span> Tmpfs Mount <span class="s1">則資料會存在於記憶體上，在重啟</span> Container <span class="s1">的時候就會</span> Reset <span class="s1">資料。</span>

<span style="background-color: #ffff99;"><span class="s1">特別注意的是，使用</span> Tmpfs Mount <span class="s1">並不是使用</span> -v <span class="s1">的選項，而是使用</span> --tmpfs <span class="s1">，</span>--tmpfs <span class="s1">就如同</span> -v<span class="s1">一樣簡化了使用</span> --mount <span class="s1">時所需的設定。</span></span>

```p1
使用 --tmpfs
$ docker run -d --name my-http --tmpfs /usr/local/apache2/htdocs -p 8080:80 httpd
使用 --mount
$ docker run -d --name my-http --mount type=tmpfs,destination=/usr/local/apache2/htdocs -p 8080:80 httpd
```

---

[![image-1642495777057.png](https://bookstack.treemanou.com/uploads/images/gallery/2022-01/scaled-1680-/ucGrtB4qipR1RYnh-image-1642495777057.png)](https://bookstack.treemanou.com/uploads/images/gallery/2022-01/ucGrtB4qipR1RYnh-image-1642495777057.png)

官方参考链接 [https://docs.docker.com/storage/volumes/#share-data-among-machines](https://docs.docker.com/storage/volumes/#share-data-among-machines)

---

### 常用volume mapping (log)

```shell
# nginx
docker run -p 80:80 -itd -v /tmp/log/nginx/docker-nginx-log:/var/log/nginx nginx

```

### **使用綁定的不同時機比較**

既然 Docker 提供了這麼多的方式讓我們儲存資料，那麼我們應該在甚麼情況下使用哪一種方式來儲存呢？

#### **- 使用 Volume 的時機**

- 想要在多個 Container 中共用資料的時候
- 在無法確保存放資料路徑或結構的時候
- 當 Docker 不在本機端而是在雲端或遠端的時候
- 當有需要資料的備份、還原、轉移的時候
- 當資料有大量 I/O 的情況，Docker 建議你可以把資料放在 Docker VM 內，會有更好的性能表現
- 當你的應用程式需要完整且原生的 File System 的時候

#### **- 使用 Bind Mount 的時機**

- 想要將 Config 設定檔同時分享給 Container 與本機端的時候
- 想要同時分享程式碼或其他來源文件給 Container 與本機端的時候
- 當非常確定所綁定的路徑底下，其資料夾與結構等等都非常確定且保持一致不會改變的時候

#### **- 使用 Tmpfs Mount 的時機**

- 不想讓資料被永久儲存的時候
- 需要每次重啟都有乾淨的環境時
- 當想要讀寫性能非常好時，因為它掛載的空間是在記憶體上

[Docker筆記 - 讓資料遠離Container，使用 Volume、Bind Mount 與 Tmpfs Mount](https://medium.com/alberthg-docker-notes/docker%E7%AD%86%E8%A8%98-%E8%AE%93%E8%B3%87%E6%96%99%E9%81%A0%E9%9B%A2container-%E4%BD%BF%E7%94%A8-volume-bind-mount-%E8%88%87-tmpfs-mount-6908da341d11 "Docker筆記 - 讓資料遠離Container，使用 Volume、Bind Mount 與 Tmpfs Mount")