教學課程:使用 MySQL 和 Docker Compose 建立多容器應用程式
本文說明如何使用 MySQL 和 Docker Compose建立多容器應用程式。 具有多個容器的應用程式可讓您為特製化工作指定容器,讓每個容器可以專注於單一工作。 使用多容器應用程式有許多優點:
- 不同的容器可讓您以不同於資料庫的方式管理 API 和前端資源。
- 多個容器可讓您獨立管理並更新不同版本。
- 本地資料庫可以維護在容器中,並使用受控服務來管理生產環境中的資料庫。
- 多容器應用程式比使用進程管理員執行多個進程更有效率,這會增加容器啟動/關機的複雜性。
在本教學課程中,您會:
- 啟動 MySQL
- 使用 MySQL 執行多容器應用程式
- 為您的應用程式建立 Docker Compose 檔案
- 使用 Docker Compose 執行應用程式堆疊
先決條件
本文是教學課程系列的一部分。 這些程序是以需要 Docker Desktop 的 Linux 容器範例為基礎建置。
建議的方法是完成第一個教學課程,建立 Docker 容器應用程式,包括滿足必要條件,以及教學課程,將數據保存在您的應用程式。 完成這些教學課程之後,繼續進行本篇文章中所描述的步驟。
本文中的範例使用 Docker Compose。
Visual Studio Code
本教程系列說明 Visual Studio Code(VS Code)的程序。 檢視以下在這個環境中工作時的考量:
使用左側功能表,在 DOCKER (Docker 延伸模組) 檢視或 EXPLORER (檔案和資料夾) 檢視之間切換:
選取 [終端機]>[新增終端機],在 VS Code 中開啟命令行視窗。 您也可以使用 Ctrl+Shift+` (反引號)鍵盤快捷方式。
除非另有指定,否則請在Bash視窗中執行命令。 標示為
Bash
大部分命令都會在Bash視窗或 VS Code 命令行視窗中執行。
啟動 MySQL 資料庫管理系統
根據預設,容器會以隔離方式執行。 容器不知道同一部電腦上的其他進程或其他容器。
若要啟用容器之間的通訊,它們必須連結至相同的網路。 相同網路上的多個容器可以彼此共用數據和處理資訊。
有兩種方式可將容器連結至網路。 您可以在建立期間將容器連結至網路,或稍後將現有的容器連結至網路。
在此範例中,您會建立網路並在啟動時連結 MySQL 容器。
建立名為
todo-app
的網路:docker network create todo-app
啟動名為
todo-mysql-data
的 MySQL 容器,並將其連結至todo-app
網路。 此命令會為 MySQL 資料庫todos
建立網路別名mysql
。當您執行 命令時,請輸入
<your-password>
佔位元的 MySQL 根密碼。docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DB=todos mysql:5.7
此命令也會定義
MYSQL_ROOT_PASSWORD
和MYSQL_DB
環境變數。 如需詳細資訊,請參閱 MySQL Docker Hub 清單。警告
本教學課程說明使用 MySQL 資料庫進行驗證的密碼認證,這不是最安全的方法。 請參閱 MySQL 檔,以深入瞭解更安全的驗證方法。
取得容器標識碼以供下一個步驟使用。
docker ps
確認您可以連線到
mysql
網路上的容器。當您執行命令時,請輸入
<mysql-container-id>
佔位符號所對應的容器 ID。docker exec -it <mysql-container-id> mysql -p
在提示字元中,輸入您在建立
todo-mysql-data
容器時所提供的密碼。在 MySQL 殼層中,列出資料庫,並確認您能看到
todos
資料庫。SHOW DATABASES;
您應該會看到下列輸出:
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | todos | +--------------------+ 5 rows in set (0.00 sec)
若要結束連線並返回命令列提示字元,請輸入 退出。
使用 MySQL 執行您的應用程式
todo
應用程式支援設定特定環境變數來指定 MySQL 連線設定。 下表列出支援的變數,以及本節所呈現範例中使用的值。
變數名稱 | 範例值 | 描述 |
---|---|---|
MYSQL_HOST |
mysql |
MySQL 伺服器的主機名。 |
MYSQL_USER |
root |
要用於連線的用戶名稱。 |
MYSQL_PASSWORD |
<your-password> |
要用於連線的密碼。 在此範例中,請將您的根密碼取代為 <your-password> 佔位符。 |
MYSQL_DB |
todos |
建立連接之後要使用的資料庫名稱。 |
警告
使用環境變數來設定連線設定是可接受的開發,但不建議在生產環境中執行應用程式。 如需詳細資訊,請參閱 為何不應該將環境變數用於秘密資料。
更安全的機制是使用容器協調流程架構所提供的秘密支援。 在大部分情況下,這些機密資訊會掛載為運行中容器內的檔案。
在下列範例中,您會啟動應用程式,並將應用程式容器連線到 MySQL 容器。
執行下列
docker
命令。 請注意命令如何指定稍早所述的環境變數。當您執行 命令時,請記得輸入
<your-password>
佔位元的 MySQL 根密碼。docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:20-alpine sh -c "yarn install && yarn run dev"
在 VS Code 編輯器中,開啟 Docker 擴充功能檢視,以滑鼠右鍵按兩下您的應用程式容器,然後選取 [檢視記錄]。
您也可以使用
docker logs
命令,從命令行檢視記錄。查看記錄輸出。 請注意指出應用程式已連線到 MySQL 資料庫的行:
Connected to mysql db at host mysql
。# Previous log messages omitted $ nodemon src/index.js [nodemon] 1.19.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Connected to mysql db at host mysql Listening on port 3000
在網瀏覽器中,移至執行中的應用程式:
http://localhost:3000
。在執行中的應用程式中,將一些專案新增至您的 Todo 清單。
線上到
mysql
網路上的 MySQL 容器資料庫,以便檢查資料庫。當您執行命令時,請用容器識別碼替換
<mysql-container-id>
佔位符。docker exec -ti <mysql-container-id> mysql -p todos
在提示字元中,輸入您在建立
todo-mysql-data
容器時所提供的密碼。在 MySQL 命令列介面中,確認您新增的
todo_items
已寫入todos
資料庫。use todos; select * from todo_items;
您應該會看到類似下列範例的輸出:
+--------------------------------------+--------------------+-----------+ | id | name | completed | +--------------------------------------+--------------------+-----------+ | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! | 0 | | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome! | 0 | +--------------------------------------+--------------------+-----------+
您現在有一個應用程式,會將資料儲存在在另一個容器中執行的外部資料庫中。 此程式示範如何使用網路功能來啟用容器之間的通訊。
建立 Docker Compose 檔案
Docker Compose 可協助您定義及共用多容器應用程式。 Docker Compose 檔案可以指定所有必要的服務,因此您可以使用單一命令啟動或結束所有相關進程。 您可以在位於專案存放庫根目錄的 Docker Compose 檔案中定義應用程式堆疊,並在版本控制下維護您的組態。 此方法可讓其他人在複製存放庫時參與您的專案。
在下列範例中,您會為多容器應用程式設定 Docker Compose 檔案,todo
。
在
todo
應用程式專案的根目錄中,建立名為 docker-compose.yml的 Docker Compose 檔案。注意
根據預設,YAML 架構版本會設定為最新版本。 當您執行應用程式時,如果您的架構版本已過時,您會收到警告訊息。 若要檢閱目前的架構版本和相容性矩陣,請參閱 概觀(撰寫檔案)。
在 docker-compose.yml 檔案中,新增下列元素。 指定您的應用程式
name
,然後啟動您想要作為應用程式一部分執行的services
(或容器)清單。name: todo services:
服務清單對您的應用程式而言是唯一的。 範例包括
app
、web
、db
、proxy
等等。 您可以在後續步驟中擴充services
項目的定義。提示
縮排對於 .yml 檔案來說很重要。 如果您要在 VS Code 中編輯,Intellisense 會指出格式或語法中的任何錯誤。
在 [
services
] 區段之後,將下列程式代碼新增至您的 docker-compose.yml 檔案。docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:20-alpine sh -c "yarn install && yarn run dev"
請記得輸入
<your-password>
佔位符的 MySQL 根密碼。 您先前使用相同的命令來執行帶有 MySQL 的應用程式容器。返回 docker-compose.yml 檔案中的
services
定義。 透過新增條目來定義app
服務元素,以擴充定義,其中包括容器的映像檔。services: app: image: node:20-alpine
您可以為服務挑選任何名稱。 當您定義 MySQL 服務時,名稱會自動變成網路別名。
擴充
app
項目定義,以指定要執行的command
。app: image: node:20-alpine command: sh -c "yarn install && yarn run dev"
定義
ports
以搭配app
服務使用。 請注意,這些埠對應於執行應用程式的 MySQL 命令中的-p 3000:3000
參數。app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000
識別
app
服務的工作目錄working_dir
,以及對應的volumes
。app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app
當您定義 Docker Compose 磁碟區時,可以基於當前目錄使用相對路徑。
指定當您執行
app
服務的命令時要使用的environment
變數定義。app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: <your-password> MYSQL_DB: todos
請記得輸入
<your-password>
佔位符的 MySQL 根密碼。在
app
服務定義之後,新增 MySQL 服務的定義mysql
。 指定項目名稱和值,如所示,且具有相同縮排。services: app: ... mysql: image: mysql:5.7
mysql
服務定義對應至你之前使用的 啟動 MySQL的命令。 當您定義服務時,它會自動接收網路別名。識別
mysql
服務的對應volumes
。services: app: ... mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql
指定當您執行
mysql
服務的命令時要使用的environment
變數定義。services: app: ... mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: <your-password> MYSQL_DB: todos
請記得輸入
<your-password>
佔位符的 MySQL 根密碼。定義整個應用程式的磁碟區對應。 在
services:
區段後面新增volumes:
區段,並使用相同的縮排。services: ... volumes: todo-mysql-data:
確認您已完成的 docker-compose.yml 檔案看起來像下列範例。 您應該會看到
<your-password>
佔位符的 MySQL 根密碼。name: todo services: app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: <your-password> MYSQL_DB: todos mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: <your-password> MYSQL_DB: todos volumes: todo-mysql-data:
使用 Docker Compose 執行應用程式堆疊
現在您可以嘗試執行 docker-compose.yml 檔案。
停止應用程式與資料庫的任何執行中實例。
請遵循 VS Code 中的下列步驟:
開啟 DOCKER (Docker 擴充功能) 檢視。
針對每個執行中的容器,以滑鼠右鍵按下容器,然後選取 [移除]。
啟動您的多容器應用程式和所有服務。
請遵循 VS Code 中的下列步驟:
開啟 EXPLORER (檔案和資料夾) 檢視。
按一下滑鼠右鍵 docker-compose.yml 檔案,然後選擇 啟動。
您應該會看到類似下列範例的輸出:
[+] Building 0.0s (0/0) [+] Running 2/2 ✔ Container app-app-1 Started 0.9s ✔ Container app-mysql-1 Running
此作業會為應用程式和網路建立已映射的磁碟區。 根據預設,Docker Compose 會特別為應用程式堆疊建立網路。
查看執行中容器的記錄。
請遵循 VS Code 中的下列步驟:
開啟 DOCKER (Docker 擴充功能) 檢視。
以滑鼠右鍵點擊應用程式容器,然後選取 [檢視記錄]。
您應該會看到類似下列範例的輸出:
mysql_1 | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections. mysql_1 | Version: '5.7.27' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) app_1 | Connected to mysql db at host mysql app_1 | Listening on port 3000
記錄會顯示服務名稱和實例編號,例如每一行開頭的
app_1
。 此格式可協助您依服務和實例區分訊息。 每個服務的記錄會交錯成單一數據流。 此方法可讓您監看計時相關問題。您現在可以在網頁瀏覽器中開啟正在執行的應用程式:
http://localhost:3000
。
停止 Docker Compose 並執行容器
當您完成應用程式和容器時,您可以將其移除。
請遵循 VS Code 中的下列步驟:
開啟 EXPLORER (檔案和資料夾) 檢視。
以滑鼠右鍵按 docker-compose.yml 檔案,然後選取 [Compose 下線]。
此作業會停止所有執行中的容器,並移除網路。
根據預設,不會移除 compose 檔案中的命名卷。 如果您想要移除這些磁碟區,您可以使用 docker-compose down --volumes
命令。
清除資源
如果您在本教學課程系列中將 必要條件 元件套用至安裝,您可以重複使用設定以供未來的 Docker 開發使用。 刪除或卸載任何元件並不重要。