多容器應用程式
說明
啟動單一容器應用程式非常簡單。例如,執行特定資料處理任務的 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 簡化整個部署流程。
設定
取得範例應用程式。如果您安裝了 Git,可以複製範例應用程式的儲存庫。否則,您可以下載範例應用程式。請選擇以下其中一個選項。
在終端機中使用以下指令來複製範例應用程式儲存庫。
$ git clone https://github.com/dockersamples/nginx-node-redis導覽至
nginx-node-redis目錄$ cd nginx-node-redis在此目錄內,您會找到兩個子目錄 -
nginx與web。下載原始碼並解壓縮。
導覽至
nginx-node-redis-main目錄$ cd nginx-node-redis-main在此目錄內,您會找到兩個子目錄 -
nginx與web。下載並安裝 Docker Desktop。
建置映像檔
導覽至
nginx目錄,並執行以下指令來建置映像檔:$ docker build -t nginx .導覽至
web目錄,並執行以下指令來建置第一個 Web 映像檔:$ docker build -t web .
執行容器
在執行多容器應用程式之前,您需要為它們建立一個網路以便通訊。您可以使用
docker network create指令來完成。$ docker network create sample-app執行以下指令啟動 Redis 容器,這會將其連接到先前建立的網路,並建立網路別名(有助於 DNS 解析):
$ docker run -d --name redis --network sample-app --network-alias redis redis執行以下指令啟動第一個 Web 容器:
$ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web執行以下指令啟動第二個 Web 容器:
$ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web執行以下指令啟動 Nginx 容器:
$ docker run -d --name nginx --network sample-app -p 80:80 nginx注意Nginx 通常用作 Web 應用程式的反向代理,將流量路由至後端伺服器。在本例中,它會路由至 Node.js 後端容器(web1 或 web2)。
執行以下指令驗證容器是否已啟動:
$ 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如果您查看 Docker Desktop 儀表板,可以看到容器並深入了解它們的配置。

當一切準備就緒後,您可以在瀏覽器中開啟 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 中的實際計數器值僅在回應傳回給客戶端後才會更新。
您可以使用 Docker Desktop 儀表板選取容器並按一下刪除 (Delete) 按鈕來移除容器。

使用 Docker Compose 簡化部署
Docker Compose 為管理多容器部署提供了一種結構化且簡化的方法。如前所述,使用 Docker Compose,您不需要執行多個 docker run 指令。您只需要在名為 compose.yml 的單一 YAML 檔案中定義整個多容器應用程式。讓我們看看它是如何運作的。
導覽至專案目錄的根目錄。在此目錄內,您會找到一個名為 compose.yml 的檔案。這就是實現所有魔法的 YAML 檔案。它定義了構成您應用程式的所有服務及其配置。每個服務都指定了其映像檔、連接埠、磁碟區、網路以及其功能所需的任何其他設定。
使用
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如果您查看 Docker Desktop 儀表板,可以看到容器並深入了解它們的配置。

或者,您可以使用 Docker Desktop 儀表板選取應用程式堆疊並按一下刪除 (Delete) 按鈕來移除容器。

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