【Docker】利用 Docker Compose 完成多容器部署(一)


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
portport 的轉發(左邊為主機的 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


上一篇:【Docker】撰寫 Dockerfile 製作映像檔(以 Spring Boot 為例)

下一篇:【Docker】利用 Docker Compose 完成多容器部署(二)

留言