多容器應用程式
解釋
啟動單容器應用程式很容易。例如,一個執行特定資料處理任務的 Python 指令碼,可以在一個容器內執行,幷包含其所有依賴項。同樣,一個為靜態網站提供服務的 Node.js 應用程式,帶有一個小型 API 端點,也可以有效地將其所有必要的庫和依賴項容器化。然而,隨著應用程式規模的增長,將它們作為單個容器進行管理變得更加困難。
想象一下,資料處理 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 儀表盤,可以看到這些容器並深入瞭解它們的配置。
一切正常執行後,你可以在瀏覽器中開啟 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 可能會以輪詢的方式在兩個後端容器之間分配傳入的請求。這意味著每個請求可能會以輪流的方式被導向到不同的容器(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 儀表盤,透過選擇應用程式堆疊並點選 刪除 按鈕來移除容器。
在本指南中,你學習了與容易出錯且難以管理的 `docker run` 相比,使用 Docker Compose 啟動和停止多容器應用程式是多麼簡單。