利用 Docker Compose 管理多個容器


當想要佈署的 docker container 超過一個以上時,會突然發現 docker run 這個指令打到手軟,特別是當要跑起來的容器還要掛載一堆本地端資料夾,一直寫 -v /home/.../.../HostData1:/home/mountData -v /home/.../HostData2:/home/mountData2 簡直是記憶力大考驗。這時候就是拿出 Docker Compose 這個工具的時候了~~

什麼時候要使用 docker compose

  • 想要利用一份檔案管理多個 docker container 時。
  • 希望多個 docker container 彼此之間有所關聯時 (例如都在同一個網路內且大家都看得到對方)。
  • 希望建立類似 CI workflows,可以用來開發、測試、與建立 staging 環境。

安裝 docker compose

  1. 在 Windows 環境下
    • 當安裝完 docker 桌面版應用程式後,docker compose 工具也一併安裝完成
  2. 在 Ubuntu 環境下
  3. docker compose 也可以直接使用 pip 安裝
    pip3 install docker-compose
    

流程

  1. 使用 Dockerfile 確定你的服務環境和所需套件。
  2. 使用 docker-compose.yml 定義你的服務範圍,以及他們在 docker 環境內彼此的關係。
  3. 執行 docker-compose up,此時會依據 docker-compose.yml 文件內的描述開始執行整個 docker 環境和服務的建構。

docker compose 基本內容

  • docker-compose.yml
    • 用來定義 docker 環境及所有服務彼此之間的關係
  • command
    • docker-compose up -d
      會將 docker-compose.yml 裡所有定義的服務一起啟動,流程包括
      1. 先開創一個共同的網路,預設名稱為 {docker-compose.yml 所在的資料夾名稱}_default
      2. 依序啟動各個服務,並將每個服務加入至此預設網路內
      3. 後面加上 -d 參數代表 detach,跟 docker run -d 一樣意思
    • docker-compose down
      依序關閉每個服務,最後將預設的網路停止
    • docker-compose ps
      查看 Docker Container 的執行狀態
  • 縮排規定要空白鍵,而不是 tab。

docker-compose.yml 範例

研究 docker-compose 是因為我在目前的專案上有一些需求 (暫時稱呼我的專案叫作專案A好了),包括:

  1. 需要利用 docker 建立兩個 container,一個跑專案 A 的 server,一個跑 redis server
  2. A_server 跑 Django 框架,且需在本地端 build image
  3. A_server 需要掛載本地端的資料夾到容器內
  4. A_server 需要看得到 redis_server
  5. 兩個容器可以一起管理

依照我自己的需求我製作了以下的 docker-compose.yml 檔案

version: '3'
services:
  A_server:
     build: .
     depends_on:
       - redis_server
     ports:
       - "8000:8000"
     volumes:
       - ./AWebCode1:/home/smart/AWebCode1
       - ./AwebCode2:/home/smart/AWebCode2
     restart: always
     container_name: servicebox
  redis_server:
     image: redis:latest
     ports:
       - "6379:6379"
     restart: always
     container_name: redis_box

我們來看一下上面這份檔案

  1. 第一行 version 一定要寫。
  2. services 定義所有的容器內容及相關細項,這裡定義了兩個容器,包括 A_server 和 redis_server。
  3. 對於 A_server 來說
    • 因為需要在本地端編譯成 docker image,所以使用 build。後面使用 . 代表直接在 docker-compose.yml 這份檔案的所在地直接找尋 dockerfile 然後開始做編譯
    • depends_on 後面接 redis_server,代表當容器啟動時,會先將 redis_server 的容器啟動後再啟動 A_server 的容器
    • ports 這邊指明 8000:8000 的對映關係,就跟 docker run -p 8000:8000 一樣意思
    • volumes 這邊指定需要掛載本地端到容器內的資料夾,就跟 docker run -v aaa:bbb 一樣意思,甚至這邊可以掛載多個還可以一次寫滿寫好
    • container_name 可以指定當容器啟動時的預設名稱
  4. 對於 redis_server 來說
    • 因為直接使用 docker registry 上面的 image,所以可以直接利用 image 關鍵字指定需要 docker pull 的 image 名稱和 tag
  5. 還記得在使用 docker run -v 的時候,後面的資料夾必須寫完整路徑嗎?但是在 docker-compose 檔案裡可以使用相對路徑,是不是很方便?
  6. 如果 docker-compose 裡沒有特別指定網路的話,則會自動建立一個 default 網路,然後把兩個 service 都加入到此網路中,重點是他們要怎麼認到彼此呢?請記得在這個網路中,定義好的 service name 會自動代換成他們在這個網路中的 DNS name,因此對於 A_server 這個 container 來說,只要在網址列輸入 http://redis_server 就可以連到 redis_server 這個容器,相反的從 redis_server 要連到 A_server 也是一樣的道理。

這次的重點整理

  1. 由於我這次的專案主要是使用 Django 框架,而在 Django 的 settings 裡面應該要設定 redis server 的 url,原本我是寫 127.0.0.1 然後永遠連不到,現在知道要直接寫 yml 檔裡的 redis server 的名稱。以這個範例來說,要在 settings 裡面寫的 url 是 redis_server 這個字串。
  2. 使用 docker-compose 工具最明顯的優點
    • 設定檔可以使用相對路徑
    • 可以先寫好多個掛載點,不用每次 docker run 時再慢慢輸入
    • 可以建立容器之間的共同橋樑

Reference

Day 24:使用 Docker-Compose 啟動多個 Docker Container
Build a Multi-Container Docker Application with Docker Compose with a React, Node, and Postgres App
Docker Compose 初步閱讀與學習記錄
透過 Docker Compose 設定 network
官方快速教學範例
Docker Compose 配置檔案 Docker-Compose.yml 檔案詳解

#docker #Django #Python #devops






你可能感興趣的文章

先從變數開始談起

先從變數開始談起

一個有趣的 styled components bug

一個有趣的 styled components bug

有關 PySpark 的那些事

有關 PySpark 的那些事






留言討論