什麼是 Docker Compose?基本觀念和實際應用

在上一篇文章 什麼是 Docker?基本觀念和實際應用 中我們講了什麼是 Docker,介紹了他的基本原理還有實際應用。

今天我們要來介紹 Docker Compose。一樣我們會先介紹他的基本原理,最後帶一個實際應用來讓大家更加了解這個工具!

什麼是 Docker Compose

所以到底什麼是 Docker Compose 呢?Docker Compose 它是一個工具,這個工具的主要目的是定義並運行多個容器 containers。

有了 Docker Compose,我們可以在 YAML 檔中定義所要運行的服務 service,並透過運行一個指令來啟動或停止所有的服務。

如果沒有 Docker Compose,我們就必須透過上一章提到的指令 docker run 來與 docker stop 一個一個運行並停止 container。

如果只有兩三個容器,那麼這還是可行的,但實際案例中常常會遇到多達十幾個容器,這在操作起來就非常不方便。

Docker Compose 另外一個優點就在於,所有服務與容器的設置參數都可以在同一份 YAML 檔案中一目瞭然。

設定檔 YAML 介紹

Docker Compose 的核心也是唯一的文件就是一個叫 docker-compose.yml 的設定檔。這個文件是按照 YAML格式 編寫,因此可讀性非常高。

我們會把所有 container 的設置都寫在這個設定檔中,並在最後執行指令 docker-compose up 來啟動全部的 containers。這讓我們省去了非常多的 docker 或是 Bash 指令。

基本上 docker-compose.yml 包含了以下幾個部分。

  • version
  • services
  • volumesnetworks

其中 version 是必須的,並且要至少建立一個 servicesvolumesnetworks 則是額外的設置。

version 是用來確定你所使用的 Docker Compose 版本。services 基本上就是 container,有幾個 services 就是有幾個 container。volumesnetworks 則是共用空間和網路配置,這兩個就是比較進階的應用。

version: "3.9"
services:
  ...
volumes:
  ...
networks:
  ...

接下來我們來看看 services 裡面到底是什麼!

Services 介紹

Services 就是每個 Container 的設置!

比如說,如果我們要建立一個網站,我們可能會將這個專案分為三個部分:前端、後端、資料庫。

我們可以將這三個部分拆為三個映像檔,並在設定檔裡面分別定義三個不同的 services。

services:
  frontend:
    image: my-frontend
    ...
  backend:
    image: my-backend
    ...
  db:
    image: my-database
    ...

在上面的例子中,我們定義了三個 containers,並且分別定義了每個 container 會用到的 image。

因此,在我們執行指令 docker-compose up 後,就會有三個 containers 被執行。

Service 裡除了可以定義映像檔以外,還有很多其他的設置。我們會在接下來的文章提到一些。

Networks 和 Volumes 介紹

Networks 定義了主機和 containers 之間、以及各個 containers 之間的溝通渠道以及方法。

在默認設置中,Docker Compose 會自動建立一個單一的網路,各個 containers 可以加入此網路和彼此溝通,主機也可以透過此網路直接和 container 取得聯繫。

Volumes 是一個在主機上的共享資料夾。透過這個資料夾,不同的 containers 之間可以分享資料,containers 也可以取得主機的資料。

什麼時候會需要用到 volume 呢?比如說當我們在 container 裡面做了一些資料處理後,而我們想要將這些更新過的資料儲存下來,這樣我們就可以將這些資料儲存在 volume 中。

如果我們不儲存在 volume 中,那麼這些資料就會隨著 container 被刪除而也跟著不見。

這邊只是講了一下 Networks 和 Volumes 的基本觀念,以後如果有機會我們會再更深入的介紹這兩個東西!

實際範例

這邊我們來透過實際範例來看一些比較常見的參數以及他們的意義。

version: '3.7'
services:
  frontend:
    # Dockerfile的路徑
    # '.' 代表當前docker-compose.yml所在的路徑
    build: .

    # container port和主機port的配對
    ports:
      - "5000:5000"

    # 將主機的資料夾mount到container中
    volumes:
      - "/usr/:/user"
    
  db:
    # 來自Docker Hub的映像檔
    image: mysql/mysql-server:5.7

    # 環境參數
    environment:
      - "MY_USER=user"
      - "MY_PASSWORD=0123"
      - "MY_DATABASE=database"
  • build:如果沒有提供映像檔,我們可以透過這個參數來指定這個 container 所要使用的 Dockerfile。. 表示當前 docker-compose.yml 所在的路徑。
  • ports:container port 和主機 port 的配對。我們可以利用這個 port 來達到主機和容器的溝通。
  • volumes:這裡的 volumes 和在使用 Docker 時的 -v 參數是一樣的。在這個例子中,我們將本機上的 /usr 資料夾搬移到 container 中的 /user 資料夾。這樣一來,更改後的資料就不會遺失了。
  • environment:這裡就是在設置環境參數。這些參數在 Container 被啟動與建立時就會被使用。

Docker Compose 常用指令

介紹完基本的設定檔後,接下來我們就來介紹一些常用的 Docker Compose 指令吧!

這邊我們只講一些常用的指令,如果想知道更多指令,官方網站 已經有很好的介紹文了!

  • docker-compose build:這個指令是用來建立我們在 docker-compose.yml 中所需要的 image。這些 images 是為了在之後創建 containers 的時候所需要的。如果在設定檔中,有一個 service 是使用一個早就已經建立好的 image,比如說你所需要的 image 在 Docker Hub 裏面,那麼這個指令就不會為那一個 service 建立映像檔。
  • docker-compose run:這個指令基本上跟 docker run 是一樣的。只是這個指令會一次建立所有的 container。當然,所使用的 image 就是透過前一個指令所建立出來的。
  • docker-compose up:這個指令其實就是 docker-compose build + docker-compose run。因此,如果你確定你的設定檔正確無誤的話,可以直接跑這個指令。非常方便!
  • docker-compose images:這個指令會列下所有你使用 docker-compose build 所建立的映像檔。類似於 docker images
  • docker-compose stop:這個指令會停止所有的 container。
  • docker-compose ps:這個指令會列下所有的 container。
  • docker-compose down:這個指令會停止並刪除所有的 containers、images、networks 等等。類似於 docker system prune

總結

到這邊基本上就講完 Docker Compose 的基本觀念和應用了!當然 Docker Compose 的能力遠遠不止於此,他還有一系列的指令和參數可以讓我們在開發上更為快速及方便。

以後我還會寫其他有關 Docker Compose 的教學文章,但這章目前就到這邊啦!希望有幫助你們學到新東西!