多容器應用程式
說明
啟動單容器應用程式很簡單。例如,執行特定資料處理任務的 Python 腳本可以在包含所有相依性的容器中執行。同樣,使用小型 API 端點提供靜態網站的 Node.js 應用程式可以有效地將其所有必要的程式庫和相依性容器化。然而,隨著應用程式規模的增長,將它們作為單獨容器管理變得更加困難。
想像一下,資料處理 Python 腳本需要連接到資料庫。突然之間,您現在不僅要管理腳本,還要管理同一個容器中的資料庫伺服器。如果腳本需要使用者登入,則您需要驗證機制,進一步增加容器大小。
容器的最佳實務之一是每個容器應該做一件事情並且把它做好。雖然此規則有例外,但要避免讓一個容器做多件事情的傾向。
現在您可能會問:「我需要單獨執行這些容器嗎?如果我單獨執行它們,我該如何將它們全部連接在一起?」
雖然 `docker run` 是一個用於啟動容器的便捷工具,但使用它來管理不斷增長的應用程式堆疊變得困難。原因如下:
- 想像一下,針對開發、測試和生產環境,使用不同的配置執行多個 `docker run` 命令(前端、後端和資料庫)。這很容易出錯且耗時。
- 應用程式通常相互依賴。隨著堆疊的擴展,以特定順序手動啟動容器和管理網路連線變得困難。
- 每個應用程式都需要其 `docker run` 命令,使得擴展個別服務變得困難。擴展整個應用程式意味著可能浪費資源在不需要提升的組件上。
- 為每個應用程式保存資料需要在每個 `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 儀表板,則可以看到容器並深入瞭解其配置。
一切準備就緒後,您可以在瀏覽器中開啟 http://localhost 來檢視網站。多次重新整理頁面,以檢視正在處理請求的主機和請求總數
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 作為反向代理,可能會以循環方式在兩個後端容器之間分配傳入請求。這表示每個請求可能會輪流定向到不同的容器(web1 和 web2)。輸出顯示 web1 和 web2 容器的連續增量,並且僅在將響應發送回客戶端後才更新 Redis 中儲存的實際計數器值。
您可以使用 Docker Desktop 儀表板刪除容器,方法是選擇容器,然後選擇 **刪除** 按鈕。
使用 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 Dashboard 來移除容器,方法是選擇應用程式堆疊,然後選擇「**刪除**」按鈕。
在本指南中,您了解到使用 Docker Compose 啟動和停止多容器應用程式是多麼容易,相較於容易出錯且難以管理的 docker run
。