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

在本教學課程中,您將瞭解如何建立多容器應用程式。 本教學課程是以開始使用教學課程為基礎, 使用 Visual Studio Code 建立和共用 Docker 應用程式。 在本進階教學課程中,您將更新應用程式以如此圖表所述運作,並瞭解如何:

  • 啟動 MySQL。
  • 使用 MySQL 執行您的應用程式。
  • 建立撰寫檔案。
  • 執行應用程式堆疊。

Diagram shows two containers labeled Todo App and MySQL connected with a line.

使用多個容器可讓您為特製化工作指定容器。 每個容器都應該執行一件事並妥善執行。

以下是您可能想要使用多容器應用程式的一些原因:

  • 分隔容器,以不同于資料庫的方式管理 API 和前端。
  • 容器可讓您以隔離方式版本和更新版本。
  • 雖然您可能會在本機使用資料庫的容器,但您可能想要在生產環境中針對資料庫使用受控服務。
  • 執行多個進程需要進程管理員,這會增加容器啟動/關機的複雜度。

必要條件

本教學課程會繼續進行一系列教學課程,從 使用 Visual Studio Code 建立和共用 Docker 應用程式開始。 從該開始,其中包含必要條件。 然後執行下列教學課程:

您也需要下列項目:

  • Docker Compose

    適用于 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 容器。

  1. 使用此命令建立網路。

    docker network create todo-app
    
  2. 啟動 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

  3. 使用 docker ps 命令取得您的容器識別碼。

  4. 若要確認您已啟動並執行資料庫,請連線到資料庫。

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

    出現提示時,輸入您在上方所使用的密碼。

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

    SHOW DATABASES;
    

    您應該會看見下列輸出。

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    

使用 MySQL 執行您的應用程式

待辦事項應用程式支援環境變數的設定,以指定 MySQL 連線設定。

  • MYSQL_HOST MySQL 伺服器的主機名稱。
  • MYSQL_USER 用於連線的使用者名稱。
  • MYSQL_PASSWORD 用於連線的密碼。
  • MYSQL_DB 連接之後要使用的資料庫。

警告

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

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

此程式會啟動您的應用程式,並將該容器連線到 MySQL 容器。

  1. 使用下列 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:12-alpine 
      sh -c "yarn install && yarn run dev"
    
  2. 在 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
    
  3. 輸入您的 http://localhost:3000 瀏覽器。 將一些專案新增至待辦事項清單。

  4. 如同您在上一節中所做的一樣,連線到 MySQL 資料庫。 執行此命令,以確認專案正在寫入資料庫。

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

    在 MySQL 殼層中,執行下列命令。

    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,您可以建立檔案來定義服務。 使用單一命令,您可以啟動所有專案,或將其全部卸載。

您可以在檔案中定義應用程式堆疊,並將該檔案保留在專案存放庫根目錄的版本控制之下。 這種方法可讓其他人參與您的專案。 他們只需要複製您的存放庫。

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

  2. 在撰寫檔案中,從定義架構版本開始。

    version: "3.7"
    

    在大部分情況下,最好使用最新的支援版本。 如需目前的架構版本和相容性矩陣,請參閱 撰寫檔案

  3. 定義您想要作為應用程式一部分執行的服務或容器。

    version: "3.7"
    
    services:
    

    提示

    縮排在 .yml 檔案中相當重要。 如果您是在 VS Code 中編輯,Intellisense 會指出錯誤。

  4. 以下是您用來應用程式容器的命令。 您會將此資訊新增至 .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:12-alpine 
      sh -c "yarn install && yarn run dev"
    

    定義容器的服務專案和映射。

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
    

    您可以挑選服務的任何名稱。 名稱會自動變成網路別名,這在定義 MySQL 服務時很有用。

  5. 新增 命令。

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
    
  6. 指定服務埠,其對應至 -p 3000:3000 上述命令中的 。

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  7. 指定工作目錄和磁片區對應

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    

    在 Docker Compose 磁片區定義中,您可以使用來自目前目錄的相對路徑。

  8. 指定環境變數定義。

    version: "3.7"
    
    services:
      app:
        image: node:12-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
    
  9. 新增 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
    

    服務會自動取得網路別名。 指定要使用的映射。

  10. 定義磁片區對應。

    使用與 volumes: 相同層級 services: 的區段來指定磁片區。 指定影像底下的磁片區對應。

    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:
    
  11. 指定環境變數。

    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:12-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 檔案,請嘗試它。

  1. 請確定應用程式與資料庫沒有其他複本正在執行。 在 Docker 擴充功能中,以滑鼠右鍵按一下任何執行中的容器,然後選取 [ 移除]。 或者,在命令列中使用 命令 docker rm ,如先前範例所示。

  2. 在 VS Code 總管中,以滑鼠右鍵按一下 docker-compose.yml ,然後選取 [ 撰寫 Up]。 或者,在命令列使用這個 docker 命令。

    docker-compose up -d
    

    參數 -d 會讓命令在背景中執行。

    您應該會看到類似下列結果的輸出。

    Creating network "app_default" with the default driver
    Creating volume "app_todo-mysql-data" with default driver
    Creating app_app_1   ... done
    Creating app_mysql_1 ... done
    

    磁片區已建立,以及網路。 根據預設,Docker Compose 會特別為應用程式堆疊建立網路。

  3. 在 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 命令的結尾。

  4. 此時,您應該能夠開啟您的應用程式。 輸入您的 http://localhost:3000 瀏覽器。

當您完成這些容器時,您可以直接將它們全部移除。

  • 在 VS Code Explorer 中,以滑鼠右鍵按一下 docker-compose.yml ,然後選取 [ 向下撰寫]。
  • 在命令列上執行 docker-compose down

容器會停止。 網路已移除。

根據預設,不會移除撰寫檔案中的具名磁片區。 如果您想要移除磁片區,請執行 docker-compose down --volumes

清除資源

您在本教學課程系列中使用的必要條件可用於未來的 Docker 開發。 沒有任何理由可以刪除或卸載任何專案。

後續步驟

在本教學課程中,您已瞭解多容器應用程式和 Docker Compose。 Docker Compose 有助於大幅簡化多服務應用程式的定義和共用。

以下是一些對您有用的資源: