教學課程:使用 MySQL 和 Docker Compose 建立多容器應用程式
在本教學課程中,您將了解如何建立多容器應用程式。 本教學課程是以使用者入門教學課程開始使用 Docker 和 Visual Studio Code 為基礎。 在本進階教學課程中,您將更新應用程式,以如此圖表所述運作,並了解如何:
- 啟動 MySQL。
- 使用 MySQL 執行您的應用程式。
- 建立撰寫檔案。
- 執行應用程式堆疊。
使用多個容器可讓您將容器專用於特製化工作。 每個容器都應該執行一項操作並妥善處理。
以下是您可能需要使用多容器應用程式的一些原因:
- 將容器分開,以不同於資料庫的方式管理 API 和前端。
- 容器可讓您以隔離的方式設定版本及更新版本。
- 雖然您可能會在本機使用資料庫的容器,但您可能需要針對生產中的資料庫使用受控服務。
- 執行多個處理序需要處理序管理員,這會增加容器啟動/關機的複雜性。
必要條件
本教學課程會繼續進行一系列教學課程,從建立容器應用程式開始。 從這一項開始,其中包含必要條件。 然後執行教學課程在應用程式中保存資料。
您也需要下列項目:
-
適用於 Windows 或 Mac 的 Docker Desktop 包含 Docker Compose。 執行此命令以確認:
docker-compose version
如果您使用 Linux 作業系統,請安裝 Docker Compose。
如同先前的教學課程,您可以從 VS Code EXPLORER 檢視或 DOCKER 檢視完成大部分工作。 您可以選取 [終端機]>[新終端機],以在 VS Code 中開啟命令列視窗。 您也可以在 Bash 視窗中執行命令。 除非指定,否則標示為 Bash 的任何命令都可以在 Bash 視窗或 VS Code 終端機中執行。
啟動 MySQL
根據預設,容器會以隔離方式執行。 各容器不知道同一部電腦上的其他處理序或容器。 若要允許一個容器與另一個容器交談,請使用網路功能。
如果兩個容器位於相同的網路上,其可以彼此交談。 如果容器不是位於相同的網路上,則無法彼此交談。
有兩種方式可將容器放在網路上:在啟動時指派容器,或連線現有的容器。 在此範例中,您會先建立網路,並在啟動時連結 MySQL 容器。
使用此命令建立網路。
docker network create todo-app
啟動 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_DATABASE=todos mysql:5.7
此命令也會定義環境變數。 如需詳細資訊,請參閱 MySQL Docker Hub 清單。
命令會指定網路別名
mysql
。使用
docker ps
命令取得容器識別碼。若要確認資料庫已啟動並執行,請連線到資料庫。
docker exec -it <mysql-container-id> mysql -p
出現提示時,請輸入您在上方所使用的密碼。
在 MySQL 殼層中,列出資料庫,並確認您看到
todos
資料庫。SHOW DATABASES;
您應該會看見下列輸出。
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | todos | +--------------------+ 5 rows in set (0.00 sec)
當您準備好返回終端機命令提示字元時,請輸入
exit
。
使用 MySQL 執行您的應用程式
Todo 應用程式支援環境變數的設定,以指定 MySQL 連線設定。
MYSQL_HOST
MySQL 伺服器的主機名稱。MYSQL_USER
要用於連線的使用者名稱。MYSQL_PASSWORD
要用於連線的密碼。MYSQL_DB
連線後要使用的資料庫。
警告
使用環境變數來設定連線設定為可接受進行開發。 建議針對在生產環境中執行應用程式的做法。 如需詳細資訊,請參閱為何您不應該將環境變數用於秘密資料。
更安全的機制是使用容器協調流程架構所提供的秘密支援。 在大部分情況下,這些秘密會掛接為執行中容器內的檔案。
此程序會啟動您的應用程式,並將該容器連線到 MySQL 容器。
使用下列 docker run 命令。 其會指定上述環境變數。
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 資料庫。
# 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 資料庫。 執行此命令,以確認項目正在寫入資料庫。
docker exec -ti <mysql-container-id> mysql -p todos
在 MySQL 殼層中,執行下列命令。
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.yml
的檔案。在撰寫檔案中,從定義結構描述版本開始。
version: "3.7"
在大部分情況下,最好使用最新的支援版本。 如需目前的結構描述版本和相容性矩陣,請參閱撰寫檔案。
定義您要做為應用程式一部分執行的服務或容器。
version: "3.7" services:
提示
縮排在 .yml 檔案中很重要。 如果您要在 VS Code 中進行編輯,Intellisense 表示錯誤。
以下是您用於應用程式容器的命令。 您會將此資訊新增至 .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"
定義容器的服務項目和映像。
version: "3.7" services: app: image: node:20-alpine
您可以為服務挑選任何名稱。 名稱會自動變成網路別名,這在定義 MySQL 服務時很有用。
新增命令。
version: "3.7" services: app: image: node:20-alpine command: sh -c "yarn install && yarn run dev"
指定服務的連接埠,此連接埠會對應至上述命令中的
-p 3000:3000
。version: "3.7" services: app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000
指定工作目錄和磁碟區對應
version: "3.7" services: app: image: node:20-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app
在 Docker Compose 磁碟區定義中,您可以使用來自目前目錄的相對路徑。
指定環境變數定義。
version: "3.7" 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 服務的定義。 以下是您在上方使用的命令:
docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DATABASE=todos mysql:5.7
定義新的服務,並將其命名為 mysql。 在
app
定義之後,在相同層級的縮排中新增您的文字。version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7
服務會自動取得網路別名。 指定要使用的映像。
定義磁碟區對應。
使用與
services:
相同層級的volumes:
區段指定磁碟區。 指定映像下的磁碟區對應。version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql volumes: todo-mysql-data:
指定環境變數。
version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: <your-password> MYSQL_DATABASE: todos volumes: todo-mysql-data:
此時,完整的 docker-compose.yml
看起來會像這樣:
version: "3.7"
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_DATABASE: todos
volumes:
todo-mysql-data:
執行應用程式堆疊
現在您已擁有 docker-compose.yml
檔案,請試試看。
請確定應用程式和資料庫沒有其他複本正在執行。 在 Docker 流程執行中,以滑鼠右鍵按一下任何執行中的容器,然後選取 [移除]。 或者,在命令列中,使用
docker rm
命令,如先前的範例中所示。在 VS Code 總管中,以滑鼠右鍵按一下 docker-compose.yml,然後選取 [向上撰寫]。 或者,在命令列使用這個 docker 命令。
docker-compose up -d
-d
參數會使命令在背景中執行。您應該會看到類似下列結果的輸出。
[+] Building 0.0s (0/0) [+] Running 2/2 ✔ Container app-app-1 Started 0.9s ✔ Container app-mysql-1 Running
已建立磁碟區以及網路。 根據預設,Docker Compose 會特別為應用程式堆疊建立網路。
在 Docker 延伸模組中,以滑鼠右鍵按一下應用程式容器,然後選取 [檢視記錄]。 若要從命令列檢視記錄,請使用
docker logs
命令。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
每個服務的記錄會交錯成單一串流。 透過此行為,您可以監看時間相關問題。
服務名稱會顯示在行開頭,以協助區分訊息。 若要檢視特定服務的記錄,請將服務名稱新增至 logs 命令的結尾。
此時,您應該能夠開啟應用程式。 輸入您的
http://localhost:3000
瀏覽器。
使用完這些容器時,只要移除這些容器即可。
- 在 VS Code 總管中,以滑鼠右鍵按一下 docker-compose.yml,然後選取 [向下撰寫]。
- 請在命令列執行
docker-compose down
。
容器隨即停止。 網路已移除。
根據預設,不會移除撰寫檔案中的具名磁碟區。
如果您要移除磁碟區,請執行 docker-compose down --volumes
。
清除資源
您在本教學課程系列中使用的必要條件可用於未來的 Docker 開發。 沒有任何理由刪除或解除安裝任何項目。
下一步
在本教學課程中,您已了解多容器應用程式和 Docker Compose。 Docker Compose 可大幅簡化多重服務應用程式的定義和共用。
以下是一些對您有用的資源: