共用方式為


教學課程:使用 MySQL 和 Docker Compose 建立多容器應用程式

本文說明如何使用 MySQLDocker Compose建立多容器應用程式。 具有多個容器的應用程式可讓您為特製化工作指定容器,讓每個容器可以專注於單一工作。 使用多容器應用程式有許多優點:

  • 不同的容器可讓您以不同於資料庫的方式管理 API 和前端資源。
  • 多個容器可讓您獨立管理並更新不同版本。
  • 本地資料庫可以維護在容器中,並使用受控服務來管理生產環境中的資料庫。
  • 多容器應用程式比使用進程管理員執行多個進程更有效率,這會增加容器啟動/關機的複雜性。

在本教學課程中,您會:

  • 啟動 MySQL
  • 使用 MySQL 執行多容器應用程式
  • 為您的應用程式建立 Docker Compose 檔案
  • 使用 Docker Compose 執行應用程式堆疊

先決條件


Visual Studio Code

本教程系列說明 Visual Studio Code(VS Code)的程序。 檢視以下在這個環境中工作時的考量:

  • 使用左側功能表,在 DOCKER (Docker 延伸模組) 檢視或 EXPLORER (檔案和資料夾) 檢視之間切換:

    顯示 Visual Studio Code 中 Docker 延伸模組檢視和檔案/資料夾總管檢視的螢幕快照。

  • 選取 [終端機]>[新增終端機],在 VS Code 中開啟命令行視窗。 您也可以使用 Ctrl+Shift+` (反引號)鍵盤快捷方式。

  • 除非另有指定,否則請在Bash視窗中執行命令。 標示為 Bash 大部分命令都會在Bash視窗或 VS Code 命令行視窗中執行。

啟動 MySQL 資料庫管理系統

根據預設,容器會以隔離方式執行。 容器不知道同一部電腦上的其他進程或其他容器。

若要啟用容器之間的通訊,它們必須連結至相同的網路。 相同網路上的多個容器可以彼此共用數據和處理資訊。

有兩種方式可將容器連結至網路。 您可以在建立期間將容器連結至網路,或稍後將現有的容器連結至網路。

在此範例中,您會建立網路並在啟動時連結 MySQL 容器。

  1. 建立名為 todo-app的網路:

    docker network create todo-app
    
  2. 啟動名為 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_PASSWORDMYSQL_DB 環境變數。 如需詳細資訊,請參閱 MySQL Docker Hub 清單

    警告

    本教學課程說明使用 MySQL 資料庫進行驗證的密碼認證,這不是最安全的方法。 請參閱 MySQL 檔,以深入瞭解更安全的驗證方法。

  3. 取得容器標識碼以供下一個步驟使用。

    docker ps
    
  4. 確認您可以連線到 mysql 網路上的容器。

    當您執行命令時,請輸入 <mysql-container-id> 佔位符號所對應的容器 ID。

    docker exec -it <mysql-container-id> mysql -p
    

    在提示字元中,輸入您在建立 todo-mysql-data 容器時所提供的密碼。

  5. 在 MySQL 殼層中,列出資料庫,並確認您能看到 todos 資料庫。

    SHOW DATABASES;
    

    您應該會看到下列輸出:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. 若要結束連線並返回命令列提示字元,請輸入 退出

使用 MySQL 執行您的應用程式

todo 應用程式支援設定特定環境變數來指定 MySQL 連線設定。 下表列出支援的變數,以及本節所呈現範例中使用的值。

變數名稱 範例值 描述
MYSQL_HOST mysql MySQL 伺服器的主機名。
MYSQL_USER root 要用於連線的用戶名稱。
MYSQL_PASSWORD <your-password> 要用於連線的密碼。 在此範例中,請將您的根密碼取代為 <your-password> 佔位符。
MYSQL_DB todos 建立連接之後要使用的資料庫名稱。

警告

使用環境變數來設定連線設定是可接受的開發,但不建議在生產環境中執行應用程式。 如需詳細資訊,請參閱 為何不應該將環境變數用於秘密資料

更安全的機制是使用容器協調流程架構所提供的秘密支援。 在大部分情況下,這些機密資訊會掛載為運行中容器內的檔案。

在下列範例中,您會啟動應用程式,並將應用程式容器連線到 MySQL 容器。

  1. 執行下列 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"
    
  2. 在 VS Code 編輯器中,開啟 Docker 擴充功能檢視,以滑鼠右鍵按兩下您的應用程式容器,然後選取 [檢視記錄]

    您也可以使用 docker logs 命令,從命令行檢視記錄。

  3. 查看記錄輸出。 請注意指出應用程式已連線到 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
    
  4. 在網瀏覽器中,移至執行中的應用程式:http://localhost:3000

  5. 在執行中的應用程式中,將一些專案新增至您的 Todo 清單。

  6. 線上到 mysql 網路上的 MySQL 容器資料庫,以便檢查資料庫。

    當您執行命令時,請用容器識別碼替換 <mysql-container-id> 佔位符。

    docker exec -ti <mysql-container-id> mysql -p todos
    

    在提示字元中,輸入您在建立 todo-mysql-data 容器時所提供的密碼。

  7. 在 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

  1. todo 應用程式專案的根目錄中,建立名為 docker-compose.yml的 Docker Compose 檔案。

    注意

    根據預設,YAML 架構版本會設定為最新版本。 當您執行應用程式時,如果您的架構版本已過時,您會收到警告訊息。 若要檢閱目前的架構版本和相容性矩陣,請參閱 概觀(撰寫檔案)

  2. docker-compose.yml 檔案中,新增下列元素。 指定您的應用程式 name,然後啟動您想要作為應用程式一部分執行的 services(或容器)清單。

    name: todo
    
    services:
    

    服務清單對您的應用程式而言是唯一的。 範例包括 appwebdbproxy等等。 您可以在後續步驟中擴充 services 項目的定義。

    提示

    縮排對於 .yml 檔案來說很重要。 如果您要在 VS Code 中編輯,Intellisense 會指出格式或語法中的任何錯誤。

  3. 在 [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 的應用程式容器

  4. 返回 docker-compose.yml 檔案中的 services 定義。 透過新增條目來定義 app 服務元素,以擴充定義,其中包括容器的映像檔。

    services:
      app:
        image: node:20-alpine
    

    您可以為服務挑選任何名稱。 當您定義 MySQL 服務時,名稱會自動變成網路別名。

  5. 擴充 app 項目定義,以指定要執行的 command

      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
    
  6. 定義 ports 以搭配 app 服務使用。 請注意,這些埠對應於執行應用程式的 MySQL 命令中的 -p 3000:3000 參數。

      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  7. 識別 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 磁碟區時,可以基於當前目錄使用相對路徑。

  8. 指定當您執行 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 根密碼。

  9. app 服務定義之後,新增 MySQL 服務的定義 mysql。 指定項目名稱和值,如所示,且具有相同縮排。

    services:
      app:
        ...
      mysql:
        image: mysql:5.7
    

    mysql 服務定義對應至你之前使用的 啟動 MySQL的命令。 當您定義服務時,它會自動接收網路別名。

  10. 識別 mysql 服務的對應 volumes

    services:
      app:
        ...
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
  11. 指定當您執行 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 根密碼。

  12. 定義整個應用程式的磁碟區對應。 在 services: 區段後面新增 volumes: 區段,並使用相同的縮排。

    services:
       ...
    
    volumes:
      todo-mysql-data:
    
  13. 確認您已完成的 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 檔案。

  1. 停止應用程式與資料庫的任何執行中實例。

    請遵循 VS Code 中的下列步驟:

    1. 開啟 DOCKER (Docker 擴充功能) 檢視。

    2. 針對每個執行中的容器,以滑鼠右鍵按下容器,然後選取 [移除]

  2. 啟動您的多容器應用程式和所有服務。

    請遵循 VS Code 中的下列步驟:

    1. 開啟 EXPLORER (檔案和資料夾) 檢視。

    2. 按一下滑鼠右鍵 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 會特別為應用程式堆疊建立網路。

  3. 查看執行中容器的記錄。

    請遵循 VS Code 中的下列步驟:

    1. 開啟 DOCKER (Docker 擴充功能) 檢視。

    2. 以滑鼠右鍵點擊應用程式容器,然後選取 [檢視記錄]。

    您應該會看到類似下列範例的輸出:

    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。 此格式可協助您依服務和實例區分訊息。 每個服務的記錄會交錯成單一數據流。 此方法可讓您監看計時相關問題。

  4. 您現在可以在網頁瀏覽器中開啟正在執行的應用程式:http://localhost:3000

停止 Docker Compose 並執行容器

當您完成應用程式和容器時,您可以將其移除。

請遵循 VS Code 中的下列步驟:

  1. 開啟 EXPLORER (檔案和資料夾) 檢視。

  2. 以滑鼠右鍵按 docker-compose.yml 檔案,然後選取 [Compose 下線]。

此作業會停止所有執行中的容器,並移除網路。

根據預設,不會移除 compose 檔案中的命名卷。 如果您想要移除這些磁碟區,您可以使用 docker-compose down --volumes 命令。

清除資源

如果您在本教學課程系列中將 必要條件 元件套用至安裝,您可以重複使用設定以供未來的 Docker 開發使用。 刪除或卸載任何元件並不重要。