
https://unsplash.com/photos/dyu466BfWj8
一個系統至少有前端、後端、資料庫等部件要運行。若還進一步切分成微服務,或導入其他軟體(如訊息佇列、全文檢索引擎),那麼就必須下好幾個指令來啟動這些容器。在廣泛使用 Docker 的團隊,不論是在各個環境部署,或者工程師本地開發,這一點將是個麻煩的地方。
本文介紹 Docker Compose,我們可將原本啟動容器時要用的參數,集中寫在一個檔案。最後只要執行一個 Docker 指令,便能一併啟動所有容器,十分便利。
此篇內容轉載自本人在 iThome 的文章。
一、認識 Docker Compose 配置檔
本節筆者以 MySQL 資料庫為對象,示範如何使用 Docker Compose。
(一)配置檔概觀
回顧一下當初建立 MySQL 容器時,Docker 指令是如何寫的。以下是個簡單的例子,指定了映像檔來源、容器的名稱、port 號,以及環境變數。
docker container create -p 3306:3306 --name DemoMySQL -e MYSQL_ROOT_PASSWORD=000000 mysql:8.2.0
請準備一個資料夾,當作 compose 的根目錄,筆者取名為「my-project」。接著在裡面建立叫做「docker-compose.yml」的檔案,它是 Docker Compose 的配置檔。這個副檔名「yml」的檔案,叫做「yaml」檔。其內容是有階層之分的,並以兩個空格為縮排。
請在配置檔撰寫如下的內容,我們再逐一認識它們。
services: | |
db: | |
image: mysql:8.2.0 | |
container_name: DemoMySQL | |
ports: | |
- 3306:3306 | |
environment: | |
- MYSQL_ROOT_PASSWORD=000000 | |
- MYSQL_USER=user | |
- MYSQL_PASSWORD=123456 | |
- MYSQL_DATABASE=demo |
仔細觀察,可發覺這些內容其實就是將 Docker 建立容器的參數寫上去,讓人一目了然。
(二)參數介紹
在配置檔的 services 階層下,可撰寫各個容器的相關參數。我們用「service」來稱呼一個提供服務的容器。
上面的例子提供了 MySQL 的參數,另外也給服務取名(必須是小寫),此處取名為「db」。服務名稱可用於 Docker Compose 的一些指令,或是在配置檔中做為 key 來指向。
在服務名稱底下的階層,可撰寫建立容器的參數。
Docker Compose 參數 | 意義 | 對應 docker run 指令參數 |
---|---|---|
image | 映像檔名稱 | (寫在最後面) |
container_name | 容器名稱 | --name |
port | port 的轉發(左邊為主機的 port 號,而右邊是容器) | -p |
environment | 環境變數 | -e |
二、啟動 Compose
寫好 docker-compose.yml 配置檔後,就能透過指令來啟動容器了。
(一)啟動
啟動 compose 的指令寫法為 docker compose -f {配置檔名稱} up -d。
Docker 會在 command line 當前的路徑下讀取名為「docker-compose.yml」的檔案。若讀者取了其他名稱,請用 -f 參數來指定。而加上 -d 選項則是讓 Docker Compose 在背景運行。
假設我們已經位於該配置檔的所在路徑(如本文的「my-project」資料夾),則啟動的範例指令如下。
docker compose up -d
執行後,配置檔中描述的容器便會一一啟動。此時再執行 docker container ls 指令,讀者也能看見目前運行中的容器。
這個 docker compose up 指令,相當於在背後執行了多個 docker container run。當映像檔不存在時,會先從 Docker Hub 下載回來。若容器名稱重複,或是 port 號被佔用,Docker 也會顯示錯誤訊息。
(二)異動配置檔
接下來讓我們在配置檔中,添加第二個服務。此處以訊息佇列 RabbitMQ 為例,並給予服務名稱「mq」。
services: | |
db: | |
# ... | |
mq: | |
image: rabbitmq:3.12.4-management | |
container_name: DemoRabbitMQ | |
ports: | |
- 5672:5672 | |
- 15672:15672 | |
environment: | |
- RABBITMQ_DEFAULT_USER=user | |
- RABBITMQ_DEFAULT_PASS=123456 |
三、操作 Compose 服務
現在這個 compose 中有兩個服務,在配置檔中分別取名為「db」與「mq」。服務的名稱可用於 docker compose 的相關指令,本節就來認識其中幾個。
(一)停止
使用 docker compose stop 指令,可停止 compose 中的所有服務。
若加上服務名稱,則是停止指定的服務,範例指令如下:
docker compose stop db
(二)移除
使用 docker compose down 指令,可移除整個 compose。
若加上服務名稱,則是移除指定的服務,範例指令如下:
docker compose down db
如果 compose 中的服務均被移除,則 compose 本身也將被移除。
(三)啟動
使用 docker compose start 指令,可啟動 compose 中的所有服務。
若加上服務名稱,則是啟動指定的服務,範例指令如下:
docker compose start db
這個指令與 docker compose up 的不同之處,在於「up」會讀取配置檔的參數,重新建立 compose。而「start」純粹是啟動,配置是沿用原本的。
此外,如果 compose 曾經有服務被移除,那這個指令是不會啟動該服務的。
(四)查看 Log
使用 docker compose logs 指令,可查看 compose 中所有服務的的 log。

若加上服務名稱,則是查看指定的服務,範例指令如下:
docker compose logs -f db
讀者也能加上 -f 選項,讓 command line 上顯示的 log 能即時更新。
四、從外部帶入環境變數
配置檔中的「db」與「mq」這兩個服務,都有各自的環境變數。然而一個產品在不同環境運行時,所需要的環境變數也不盡相同,例如連線的帳密。
此時讀者有兩種選擇,一種是撰寫不同的配置檔,將變數值都寫死(hard code)。另一種是本節要介紹的,透過外部檔案來帶入變數值。
請在 compose 的根目錄或其子資料夾下,建立兩個副檔名為「.env」的檔案,而主檔名隨意,方便辨識即可。用途是分別存放 MySQL 與 RabbitMQ 的環境變數。以下範例為目前的檔案相對位置。
my-project |_ docker-compose.yml |_ service-env-files |_ mysql.env |_ rabbitmq.env
請在「mysql.env」檔案寫入以下參數。
MYSQL_ROOT_PASSWORD=000000 MYSQL_USER=user MYSQL_PASSWORD=123456 MYSQL_DATABASE=demo
也在「rabbitmq.env」檔案寫入以下參數。
RABBITMQ_DEFAULT_USER=user RABBITMQ_DEFAULT_PASS=123456
最後調整配置檔的內容,將「environment」這個階層,以「env_file」取代,並分別提供 env 檔案的路徑。
services: | |
db: | |
# ... | |
env_file: ./service-env-files/mysql.env | |
mq: | |
# ... | |
env_file: ./service-env-files/rabbitmq.env |
留言
張貼留言