動手玩Windows 10 Docker(7) - 用Docker Compose來製作起動Container的劇本

Windows 10 Docker 是2016年度更新後很大的一個進步但(好像)被很多人忽略沒有話題性

這個系列是我的學習筆記也順便推廣這好用的東西

今天要談的是Docker Compose這個功能

Docker 好用的地方是它的組件式裝嵌方式

像以往一樣我們可以把一個個Container當作是一個系統去看待

但通常我們會把一個系統分作前後端, 甚至中間有寫處理單元

例如一個部落格編寫的熱門軟體Wordpress就有Wordpress的前端和Mysql資料庫

Wordpress算是非常顯淺明白的方案, 用他來做Docker Compose示範作入門是很適合的

而Docker inc也是選用wordpress作為其中一篇教育文章

如果我們拿取了Wordpress和Mysql的Docker Image, 怎樣要它們一起工作?

怎樣把他們弄成一個微系統? Docker Compose正是為這個已存在的功能

Docker Compose是Docker Toolbox裡其中一個元件

https://www.docker.com/products/docker-toolbox

而Docker for Windows預設已經安裝了Docker Toolbox, 所以我們也不用特別去另外安裝了

Docker Compose功能好比一個劇本, 說明了有那些演員 (Docker Image), 他們的角色 (Network Port)

出場的順序(depends on), 戲份, 劇目, 對白(Environment, Volume) 等等

在導演說上場了大家就做好自己的東西變身成Containers.

但要了解Docker Compose, 必須先要了解前面6篇基本的Docker指令

這樣會更易明白Docker Compose的劇本怎樣編寫出來

通常我們會把一個個劇本放到獨立的資料夾了, 例如我先建立一個docker_wordpress資料夾

之後要建立一個叫docker-compose.yml的檔案 (也可以是yaml的檔尾)

這個是Docker Compose專用的檔案名稱

以Wordpress為例, 劇本可以這樣編寫

version: '2'

services:
   db:
     image: mysql:5.7.9
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8001:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:


內容物都有甚麼意思呢?

我們見到幾個分層, 頂端說明這個Docker Compose的版本,

Version: "2" 是告訴Docker Compose請用Version 2的方式去演譯這個劇本

暫時版本有1, 2, 2.1和 3,往後可以還有其他, version 1,2很類似, version 3也些功能的定義字符會有不同

所以要真的清楚明瞭就要回去看看Docker Compose的說明文件

https://docs.docker.com/compose/compose-file/

之後定義的是services, 在Services裡面我們說明了有兩個演員, 戲裡的名稱是db和wordpress

他們的角色在image: 裡定義了, 是mysql:5.7.9和Wordpress最新的版本

之後就是他們仔細的設定部份了

volumes: 裡面把 db_data和/var/lib/mysql做了一個儲存區對接

情況和我們在第4篇裡所用的 -v 參數不一樣

不過在後面在Container啟動後再解釋這是做了甚麼東西

 

restart: always 是指在docker或host重啟後container要不要一起跟隨起動

wordpress部份的ports: "8001:80" 是把container的80埠映射到host的8001埠上

第3篇裡所用的-p 參數是相同的用法, 如果你還有443埠, 你可以在下面增加一句 - "4431:443" 即可達成

environment: 下面一整段和第2篇所用的環境變數 -e 是一樣的

最後wordpress有一個特別的東西叫

depends_on:

- db

這是要告訴wordpress, 你一定要先等db出場才可以開始起動

很多系統有起動的順序要求, 前台沒有了後台根本不能運作甚至出現奇怪的錯誤

如果你的系統要有一個很有條理的順序, 你可以善用depends_on來決定container的起動時間

如果wordpress建基於兩個資料庫db和db2之上(只是如果), 而db,db2那一個先啟動也不緊要

你也可以將這樣去定義

wordpress:

depends_on:

- db

- db2

最後volumes: 

db_data: 

是要告訴docker compose永遠要把db_data這個docker volume (後注) 掛載起來.

劇本準備好料, 那導演要怎樣說開始?

指令是 docker-compose up, 也可以是docker-copose up -d 

如以往一樣 -d 是要讓Container在背景運作

可以看到, 由於我沒有曾經下載過wordpress的docker image, 

docker compose自動從docker hub上抓取wordpress:lastest最新的版本來使用

首先他建立了一個新的docker network 叫dockerwordpress_default 而且預設是用bridge作network driver

而自動建立的Network會如以下的設定, 如果你要仔細微調

建議先建立好你的network, 再在docker-compose.yml裡以network部份來定義,

例如如果Wordpress需要連接兩個已建立的網絡JustinNetwork和FionaNetwork

networks:

- JustinNetwork

- FionaNetwork

再來我們看看這組系統能不能運作

在host上的瀏覽器輸入 http://localhost:8001 ,會出現wordpress的安裝頁面

證明wordpress是有正常運作的

好了再來解釋上面volume的部份, 我們說了, 這個跟我們的 -v 參數對映Host的Shared volume不是同一樣的東西

如果我們看看docker_wordpress的資料夾, 也沒有甚麼db_data製造出來

要寫出volume對映到db_data的目的是我們不想把mysql資料庫放到Container裡面

我們想把它分離出來, 那一天我們的Container被移除了, 也不會連帶資料庫一起消失

這是要做個防呆設定, 那究竟db_data在那裡? 

原來docker製造了一個儲存區塊, 我們可以用docker volume ls 來查看

結果可能是類似以下的輸出

根據我們的資料, Docker做出來dockerwordpress_db_data這個掛載點

docker volume inspect dockerwordpress_db_data 指令可以更深入的了解

可以看到真實的掛載位置在

Mountpoint": "/var/lib/docker/volumes/dockerwordpress_db_data/_data"

原來故事要回到Windows 10為什麼能運行Linux的Container...

如果我們打開Windows 10的Hyper-V Manager
原來Windows 10是以Hyper-V 運行一台Linux Server來達成這個創舉的

可是你不能輕易地跑去控制這台VM...在Beta測試時我們曾經是可以的

但現在他們已經封瑣了直接控制這台VM的方式, 說是要控制Docker for Windows的使用者體驗 (?)

不過我們最少知道了, db_data是放在這裡的, 不能直接控制這個volume算是Docker for Windows一個小小的問題吧

但以結果論來說, 把資料從container裡分離出來也是非常好的習慣.

這個Docker Compose習作算是非常簡單的入門, 其實Docker Compose 還有其他部件

再日後的文章中會再介紹玩法, 要把起動了的整個wordpress系統卸載

只要在C:\docker_wordpress目錄簡單輸入docker compose down就可以了

但這個指令不會移除db_data, 如果你常要斬草除根, 則要輸入

docker-compose down --volumes