多容器應用程式

說明

啟動單一容器應用程式非常簡單。例如,執行特定資料處理任務的 Python 指令碼可以連同其所有依賴項在容器中執行。同樣地,一個提供靜態網站與小型 API 端點的 Node.js 應用程式,也可以將其所有必要的函式庫與依賴項有效地容器化。然而,隨著應用程式規模的擴大,將它們作為獨立的容器來管理會變得更加困難。

想像一下,資料處理的 Python 指令碼需要連接到資料庫。這時,您不僅要管理指令碼,還要管理同一個容器內的資料庫伺服器。如果指令碼需要使用者登入,您還需要驗證機制,這會進一步導致容器臃腫。

容器的最佳實踐之一是:每個容器應專注於做好一件事。雖然這條規則有例外,但應避免讓一個容器執行多項任務的傾向。

現在您可能會問:「我需要將這些容器分開執行嗎?如果分開執行,我該如何將它們全部連接起來?」

雖然 docker run 是啟動容器的便利工具,但用它來管理不斷成長的應用程式堆疊會變得很困難。原因如下:

  • 試想一下,要為開發、測試與生產環境執行多個 docker run 指令(前端、後端與資料庫)並設定不同配置,不僅容易出錯,還非常耗時。
  • 應用程式之間通常存在依賴關係。隨著堆疊擴大,手動以特定順序啟動容器並管理網路連接會變得十分困難。
  • 每個應用程式都需要自己的 docker run 指令,這使得調整個別服務的規模變得困難。擴展整個應用程式可能意味著在不需要增強的元件上浪費資源。
  • 為每個應用程式持久化資料需要個別的磁碟區掛載 (volume mounts) 或在每個 docker run 指令中進行配置。這會導致資料管理方式變得四散。
  • 透過個別的 docker run 指令為每個應用程式設定環境變數既繁瑣又容易出錯。

這正是 Docker Compose 可以大顯身手的地方。

Docker Compose 使用名為 compose.yml 的單一 YAML 檔案來定義您的整個多容器應用程式。此檔案指定了所有容器的配置、它們的依賴關係、環境變數,甚至包括磁碟區與網路。透過 Docker Compose:

  • 您不需要執行多個 docker run 指令。您只需在單一 YAML 檔案中定義整個多容器應用程式。這集中了配置並簡化了管理。
  • 您可以輕鬆地按特定順序執行容器並管理網路連接。
  • 您可以在多容器設定中輕鬆地擴展或縮減個別服務的規模。這能根據即時需求實現高效的資源分配。
  • 您可以輕鬆實現持久化磁碟區。
  • 在 Docker Compose 檔案中一次性設定環境變數非常容易。

透過利用 Docker Compose 執行多容器設定,您可以建構以模組化、可擴展性與一致性為核心的複雜應用程式。

試試看

在本實作指南中,您將首先了解如何使用 docker run 指令來建構並執行一個基於 Node.js、Nginx 反向代理與 Redis 資料庫的計數器 Web 應用程式。您還將了解如何使用 Docker Compose 簡化整個部署流程。

設定

  1. 取得範例應用程式。如果您安裝了 Git,可以複製範例應用程式的儲存庫。否則,您可以下載範例應用程式。請選擇以下其中一個選項。

    在終端機中使用以下指令來複製範例應用程式儲存庫。

    $ git clone https://github.com/dockersamples/nginx-node-redis
    

    導覽至 nginx-node-redis 目錄

    $ cd nginx-node-redis
    

    在此目錄內,您會找到兩個子目錄 - nginxweb

    下載原始碼並解壓縮。

    下載原始碼

    導覽至 nginx-node-redis-main 目錄

    $ cd nginx-node-redis-main
    

    在此目錄內,您會找到兩個子目錄 - nginxweb

  2. 下載並安裝 Docker Desktop。

建置映像檔

  1. 導覽至 nginx 目錄,並執行以下指令來建置映像檔:

    $ docker build -t nginx .
    
  2. 導覽至 web 目錄,並執行以下指令來建置第一個 Web 映像檔:

    $ docker build -t web .
    

執行容器

  1. 在執行多容器應用程式之前,您需要為它們建立一個網路以便通訊。您可以使用 docker network create 指令來完成。

    $ docker network create sample-app
    
  2. 執行以下指令啟動 Redis 容器,這會將其連接到先前建立的網路,並建立網路別名(有助於 DNS 解析):

    $ docker run -d  --name redis --network sample-app --network-alias redis redis
    
  3. 執行以下指令啟動第一個 Web 容器:

    $ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
    
  4. 執行以下指令啟動第二個 Web 容器:

    $ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
    
  5. 執行以下指令啟動 Nginx 容器:

    $ docker run -d --name nginx --network sample-app  -p 80:80 nginx
    
    注意

    Nginx 通常用作 Web 應用程式的反向代理,將流量路由至後端伺服器。在本例中,它會路由至 Node.js 後端容器(web1 或 web2)。

  6. 執行以下指令驗證容器是否已啟動:

    $ docker ps
    

    您將會看到類似下方的輸出

    CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                NAMES
    2cf7c484c144   nginx     "/docker-entrypoint.…"   9 seconds ago        Up 8 seconds        0.0.0.0:80->80/tcp   nginx
    7a070c9ffeaa   web       "docker-entrypoint.s…"   19 seconds ago       Up 18 seconds                            web2
    6dc6d4e60aaf   web       "docker-entrypoint.s…"   34 seconds ago       Up 33 seconds                            web1
    008e0ecf4f36   redis     "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp             redis
  7. 如果您查看 Docker Desktop 儀表板,可以看到容器並深入了解它們的配置。

    A screenshot of the Docker Desktop Dashboard showing multi-container applications
  8. 當一切準備就緒後,您可以在瀏覽器中開啟 https:// 查看網站。重新整理頁面幾次,觀察處理請求的主機以及請求的總次數。

    web2: Number of visits is: 9
    web1: Number of visits is: 10
    web2: Number of visits is: 11
    web1: Number of visits is: 12
    
    注意

    您可能已經注意到,作為反向代理的 Nginx 很可能會以循環排程 (round-robin) 的方式在兩個後端容器之間分配傳入請求。這意味著每個請求可能會輪流指向不同的容器(web1 與 web2)。輸出顯示 web1 與 web2 容器的連續遞增,且儲存在 Redis 中的實際計數器值僅在回應傳回給客戶端後才會更新。

  9. 您可以使用 Docker Desktop 儀表板選取容器並按一下刪除 (Delete) 按鈕來移除容器。

    A screenshot of Docker Desktop Dashboard showing how to delete the multi-container applications

使用 Docker Compose 簡化部署

Docker Compose 為管理多容器部署提供了一種結構化且簡化的方法。如前所述,使用 Docker Compose,您不需要執行多個 docker run 指令。您只需要在名為 compose.yml 的單一 YAML 檔案中定義整個多容器應用程式。讓我們看看它是如何運作的。

導覽至專案目錄的根目錄。在此目錄內,您會找到一個名為 compose.yml 的檔案。這就是實現所有魔法的 YAML 檔案。它定義了構成您應用程式的所有服務及其配置。每個服務都指定了其映像檔、連接埠、磁碟區、網路以及其功能所需的任何其他設定。

  1. 使用 docker compose up 指令來啟動應用程式:

    $ docker compose up -d --build
    

    當您執行此指令時,您應該會看到類似以下的輸出:

    Running 5/5
    ✔ Network nginx-nodejs-redis_default    Created                                                0.0s
    ✔ Container nginx-nodejs-redis-web1-1   Started                                                0.1s
    ✔ Container nginx-nodejs-redis-redis-1  Started                                                0.1s
    ✔ Container nginx-nodejs-redis-web2-1   Started                                                0.1s
    ✔ Container nginx-nodejs-redis-nginx-1  Started
    
  2. 如果您查看 Docker Desktop 儀表板,可以看到容器並深入了解它們的配置。

    A screenshot of the Docker Desktop Dashboard showing the containers of the application stack deployed using Docker Compose
  3. 或者,您可以使用 Docker Desktop 儀表板選取應用程式堆疊並按一下刪除 (Delete) 按鈕來移除容器。

    A screenshot of Docker Desktop Dashboard that shows how to remove the containers that you deployed using Docker Compose

在本指南中,您了解了相較於容易出錯且難以管理的 docker run,使用 Docker Compose 來啟動與停止多容器應用程式有多麼簡單。

其他資源

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.