[Docker] 使用 Docker Compose 統一管理 Container

會展示如何安裝、使用 Docker Compose,以及簡單講解 docker-compose.yml 的指令。

 

 

 

前言

使用 Docker CLI 的指令(docker run)能夠輕鬆建立單個 Container,但是如果要添加很多其他的設置(ex:env、port、network 等),docker run 的指令會很長很長,並且如果要部屬多個 Container 的話,都要一個一個手動打這麼長的指令,不只很容易打錯,也不方便設置,所以需要使用一個叫 Docker Compose 的工具來做統一定義。

 

以下為單台 Server 控管多個 Container 的教學,如果要控管多台 Server 的部分要使用容器調度工具(Docker Swarm / K8s),這個之後有空我會再另外寫文章說明。

 

 

示範環境

Linux OS Version:Ubuntu 20.04.4 LTS

Docker Version:20.10.12

Example Image TargetFramework:.NET 6

 

 

安裝 Docker Compose

使用 apt 安裝

apt-get install docker-compose-plugin

 

查看版本 確認是否有安裝成功

docker compose version

 

 

Docker Compose 架構

Docker Compose 主要由三個單位組成

Compose Project:一個 docker-compose.yml 會運行一個 Compose Project

Service:一個 docker-compose.yml 裡面可能會有多個 Service,一個 Service 對應一個 image

Container:一個 image 基本會起一個 Container (不過不一定,也有些 image 裡面會起多個 Container)

 

 

建立 docker-compose.yml

在 Server 根目錄新增一個 docker-compose.yml

touch docker-compose.yml

 

docker-compose.yml 內容

version: "3.9"
services:
  demowebapi:
        image: docker.private.net/demowebapi:SIT
        restart: always
        ports:
          - 19977:9999
        networks:
          - my_net
        environment:
          - ASPNETCORE_ENVIRONMENT=SIT
        extra_hosts:
          - "MyDB:10.10.10.11"
          - "MyDB2:10.10.10.12"
          - "MyDB3:10.10.10.13"
networks:
  my_net:

 

這裡為求示範內容簡易,所以我只寫一個 Service,實際上這裡可以指定多個,格式會像這樣 👇

version: "3.9"
services:
  api1:
    ......
  api2:
    ......
  api3:
    ......

 

接著說明一下這個 Compose yaml 的設置內容

 

最上層的 3 個項目:

version:Compose 文件格式的版本,會根據 Server 上安裝的 Docker 版本有關,詳情請參考 Compose file version 3 reference | Docker Documentation,由於我的 Docker Version 是 20.10.12,所以這裡我可以使用最新版的 3.9 沒有問題

services:你的服務們,以及服務們要設置的各種配置

networks:Service 們要連接的虛擬網路

 

接著講 services 底下的項目:

demowebapi:Service Name

image:要使用的 docker image

restart:設置此 Container 在 Server 重啟的時候需不需要重新啟動,預設是 Server 重啟 Container 會消失,這裡設置 always,表示改成每次 Server 重啟 Container 也會重啟

ports:<host port> : <container port>

networks:Container 要連接的虛擬網路

如果沒有設置 network,default 會使用 bridge network_mode,當建立此 Service 時,他也會同時 create 一個 <Compose Project Name>_default 的 network

environment:環境變數的設置位置,可以將環境變數傳遞給 Container

像上面的範例這裡是設置 .NET Core 專案執行時要用到的 ASPNETCORE_ENVIRONMENT 環境變數

(等於這個  ⬇)

 

extra_hosts:設置 Host Name mapping 用的,如果你的 DB Connection String 是用 Host Name 來指定,那麼 Host Name 與 Host IP 就需要在 hosts 檔案內設置好。

如果將此設置添加在 extra_hosts的話,他就會在 Container 內的 /etc/hosts 中添加像這樣的 host 清單   ⬇

 

 

使用 docker-compose.yml 部屬服務

新增好 docker-compose.yml 後,就來啟動服務吧~

 

pull docker-compose.yml 中 service 要用到的 image

docker compose pull

如果什麼都沒有指定,他會預設讀取當前路徑中檔名為 docker-compose.yml 的檔案

 

如果 docker-compose.yml 的路徑 & 檔名都是自訂的,可以添加 -f 另外指定

docker compose -f customfolder/demowebapi-docker-compose.yml pull

 

 

 

Create & Start Container

docker compose up --force-recreate -d

 

這裡我多設置了 3 個 Options,你們可以視情況增減,不一定要跟我一樣

 

--force-recreate:強制重新建置 Container(不管 imge 或 docker-compose.yml 有無更新)

-d:d 是 detached 的簡稱,意旨分離模式(detached mode),在後台運行 Container,服務的 log 不會直接顯示在終端機視窗上

--remove-orphans:刪除 docker-compose.yml 中沒有定義的 Service

假設同個 Compose Project 在先前已經在 Server 中啟動 2 個 Service 了,但是 docker-compose.yml 更新後只剩下一個 Service,那麼在執行此指令的時候,他會順便幫你刪掉那個在 docker-compose.yml 中被你拿掉的 Service

(ex:我刪掉了 docker-compose.yml 中 demowebapi_2的 Service 設置  ⬇ )

 

關於這指令的其他附加選項,有興趣的可以參考 docker compose up | Docker Documentation

 

上述動作做完後,可以用 docker ps 指令查詢,就可以看到 Docker Compose 幫你啟動的 Container 了

 

接下來即可用 http://localhost:19977 訪問

 

END

 

更多 docker compose 指令可參考官方教學文章 docker compose | Docker Documentation