使用 Volume 同步程式
Volume 也是 Docker 的元件,它提供 container 保存資料或共享資料的機制。
情境說明
在開始說明 volume 前,先來看下面這個情境。
昨天學到了如何在背景開啟 HTTP server,指令如下:
$ docker run -d --name web -p 8080:80 httpd |
Server 是開好了,但如果 server 的內容不能依需求修改的話,最終只是拿來玩 Hello world 而已。
因此現在有了新的目標--更新裡面的程式。可以使用 docker exec
加上 shell 進入 container:
# 啟動 Apache |
docker exec
是在一個運行中的 container 上,再執行一個新的指令。參數為上例的 CONTAINER ID
與啟動 shell 的指令 bash
,執行的結果是進入 Apache container 的世界裡,在裡面可以找得到 curl 取到的 HTML 原始文件。
只要修改這個檔案,即可讓 curl 獲得修改後的檔案。
# 使用 exec 進入 container |
上面這個範例,我們成功修改了 index.html
的內容。但先別開心,我們把舊的移除,然後用 docker run
跑一個新的 Apache container 看看:
# 確認內容 |
這個實驗會發現,It works! 又回來了?原因很簡單,在介紹 port forwarding 的時候,有提到隔離特性,也有提到每個 container 都是各自獨立的,這也代表剛剛被砍掉的 container 與現在建立的 container 是不同一個。而使用 docker run
指令產生的 container,每次都會是全新跟重灌好一樣,這就是一次性的特性。
Bind Mount
只要開新的 container 就會被砍掉重練,那該如何讓我們寫好的程式出現在 container 裡面呢?方法有很多種,今天說明馬上就能使用的 Bind Mount。
Bind Mount 的概念很簡單,它可以把本機的某個目錄或檔案,綁定在 container 裡的某個目錄或檔案。比方說把目前開發的程式,綁在 container 的 /source
,那 container 就能在它的 /source
裡看到本機的檔案。
綁定使用 -v
選項,下面範例是把目前目錄綁定在 Apache container 的 /usr/local/apache2/htdocs
目錄下:
# 執行 container |
這個方法可以簡單解決 docker run
產生新的 container 的情境下保有舊的資料。
指令補充說明
docker exec
在一個正在執行的 container 上執行指令,用法如下:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...] |
docker run
與 docker exec
做的事很相似,決定性差異在於:docker run
會產生新的 container,而 docker exec
需要運行中的 container。
-i|--interactive
和 -t|--tty
參數用法與 docker create
相同。
docker run
-v|--volume
掛載 volume 到這個 container 上,格式為[/host]:[/container]:[參數]
今日自我回顧
- 練習「進入」container 的方法
- 練習在 container 讀取修改目錄或檔案