前幾天,我們不斷地在說明容器,對容器的熟悉度應該就像認識三十年的朋友一樣熟悉了。但這樣還是不夠的,我們必須要知道,你朋友的錢存在哪裡 (咦!?)。
今天我們就來談談朋友的錢存在哪(容器裡應用程式產生的資料存在哪)吧。
每個容器都有屬於自己的檔案系統,而最基本的檔案系統是由映像檔的共享層與容器內的可寫層所構成。
映像檔本身是多個層 ( Layer ) 所組成,就像一份漢堡的組成一樣,一層又一層。
當容器建立並啟動時,容器的檔案系統除了有映像檔的各層以外,docker 會自動加入可寫層,以供容器有個暫時儲存資料與檔案的地方。
因此,可寫層是跟隨著容器的生命週期,可寫層會在容器被刪除後,也跟著消失,所以:
容器裡產生的資料 ---> 可寫層 ---> 容器被刪除 ---> 可寫層被刪除 ---> 資料消失
但這不是我們想要遇到的問題,在前一篇可知,容器的汰舊換新是常態。
除了前一篇提到的更替狀況,還有一種情況是,部署新版 (新的功能或是修復已知 bug) 的專案時,這時我們會一定是部署新的容器上去,並把舊的刪掉。敏感的你,是不是察覺不對勁?
Production 的資料是不是就啪一聲的不見了….?
我們當然不能因為更新就讓會員資料全部都消失殆盡,所以 docker 有提供了永續性的資料儲存方式: 約定掛載 與 Volume。
說文解字。約定,即雙方意思合意,你心甘、我情願,因此在雙方認定的範圍內,互通有無; 掛載,也就是將元件、資料等與其他元件跟資料或系統連結。
在 docker 裡,就是透過設定 (約定),將本機資料與容器連結在一起 (掛載):
--mount type=bind,source="本機資料夾目錄",target="容器內資料儲存的目錄"
沒錯,你沒看錯,這一整串就是在做約定掛載,我們需要指定資料流通的兩端( source, target )。
type、source、target 之間必須要有逗號,且逗號間不能有空格。
什麼?好麻煩?OK, Docker 聽到你的心聲了,那就用 -v 本機資料夾目錄:容器內資料儲存的目錄
吧
/Users/mike/Desktop/bind
裡建立 index.html
檔案body
tag 裡面輸入任何你想要的畫面設計,這裡為了簡單示範,我在我的 index.html
只輸入 <h1>**This is new data</h1>
**docker container run --mount type=bind,source="/Users/mike/Desktop/bind",target="/usr/local/apache2/htdocs/" -p 8001:80 -d httpd
或
docker container run -v /Users/mike/Desktop/bind:/usr/local/apache2/htdocs/ -d httpd
原本在 http://localhost:8001/
應該會出現 It Works!
,現在變成**This is new data
。**
這代表,目前已經將我綁定的本機目錄與容器連上了,資料雙向流通。
那為什麼原本是 It Works!
,現在變了。那是因為在容器裡, /usr/local/apache2/htdocs/
底下,原本有 index.html
檔案,現在經過約定掛載後,將原本容器內的資料給覆蓋過去。如上面說明的第三點。
大家可以嘗試建立一個無掛載的 httpd 跟有掛載的 httpd,並使用 inspect
看一下兩者容器內的 Mounts
。
今天的東西可能會比較難一點,我們來做個總結吧。
現在我們知道,容器的資料可以存放在暫時性的可寫層,但可寫層會跟容器一起被刪掉,導致資料無法長存於世,這對 production 來說,不堪使用。
於是我們有掛載的方法,將資料長期存放。透過約定掛載,我們可以將容器的資料存放在本機的資料夾 (目錄) 中,同時我們也可以更改本機裡的資料。
因為內容有點龐大,用一篇寫完後發現,東西實在太多了 (汗),為了減輕讀者負擔,所以今天先只說明檔案系統跟約定掛載,明天我們會來講解另一個神秘空間 volume。
關於「層」,我們會在之後特別寫一篇文章為大家解釋。今天我們先暫時為了可寫層,間單對映像檔做個基本介紹。
這一系列的鐵人賽文章,都同步更新在我的部落格: https://wl02599509.github.io/
嗨嗨,關於掛載的參數,「容器資料夾目錄」與「本機資料夾目錄」是不是寫反了呢?
我是用 Windows,寫成
--mount type=bind,source="本機目錄",target="容器目錄"
-v "本機目錄":"容器目錄"
例如:-v "C:\Users\Vincent\Desktop\foo":"/bar"
這樣才有順利掛載到
沒錯沒錯,是我寫反了,非常感謝您的閱讀與回饋!!! 也不好意思,造成您的困擾!!!