使用容器化資料庫

使用本地容器化資料庫提供了靈活性和易於設定的優勢,讓您可以緊密地模擬生產環境,而無需傳統資料庫安裝的開銷。Docker 簡化了這一過程,使您只需幾個命令即可在隔離的容器中部署、管理和擴充套件資料庫。

在本指南中,您將學習如何:

  • 執行本地容器化資料庫
  • 訪問容器化資料庫的 shell
  • 從主機連線到容器化資料庫
  • 從另一個容器連線到容器化資料庫
  • 將資料庫資料持久化到卷中
  • 構建自定義資料庫映象
  • 使用 Docker Compose 執行資料庫

本指南使用 MySQL 映象作為示例,但這些概念也適用於其他資料庫映象。

先決條件

要跟隨本指南,您必須安裝 Docker。要安裝 Docker,請參閱獲取 Docker

執行本地容器化資料庫

包括 MySQL、PostgreSQL 和 MongoDB 在內的大多數流行資料庫系統,在 Docker Hub 上都有 Docker 官方映象。這些映象是經過精心策劃的一組遵循最佳實踐的映象,確保您能夠獲得最新的功能和安全更新。要開始使用,請訪問 Docker Hub 並搜尋您感興趣的資料庫。每個映象的頁面都提供了詳細的說明,教您如何執行容器、自定義設定以及根據您的需求配置資料庫。有關本指南中使用的 MySQL 映象的更多資訊,請參閱 Docker Hub MySQL 映象頁面。

要執行資料庫容器,您可以使用 Docker Desktop GUI 或 CLI。

要使用 CLI 執行容器,請在終端中執行以下命令

$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest

在此命令中

  • --name my-mysql 將您的容器命名為 my-mysql,以便於引用。
  • -e MYSQL_ROOT_PASSWORD=my-secret-pw 將 MySQL 的 root 密碼設定為 my-secret-pw。請將 my-secret-pw 替換為您選擇的安全密碼。
  • -e MYSQL_DATABASE=mydb 可選地建立一個名為 mydb 的資料庫。您可以將 mydb 更改為您想要的資料庫名稱。
  • -d 以分離模式執行容器,意味著它在後臺執行。
  • mysql:latest 指定您要使用最新版本的 MySQL 映象。

要驗證容器是否正在執行,請在終端中執行 docker ps

要使用 GUI 執行容器

  1. 在 Docker Desktop 儀表板中,選擇視窗頂部的全域性搜尋。

  2. 在搜尋框中指定 mysql,如果尚未選擇,請選擇 Images 選項卡。

  3. 將滑鼠懸停在 mysql 映象上,然後選擇 Run。將出現執行新容器模式視窗。

  4. 展開可選設定

  5. 在可選設定中,指定以下內容

    • 容器名稱: my-mysql
    • 環境變數:
      • MYSQL_ROOT_PASSWORDmy-secret-pw
      • MYSQL_DATABASEmydb
    The optional settings screen with the options specified.
  6. 選擇 Run

  7. 在 Docker Desktop 儀表板中開啟容器檢視,以驗證您的容器是否正在執行。

訪問容器化資料庫的 shell

當資料庫在 Docker 容器內執行時,您可能需要訪問其 shell 來管理資料庫、執行命令或執行管理任務。Docker 提供了一種使用 docker exec 命令的簡單方法。此外,如果您更喜歡圖形介面,可以使用 Docker Desktop 的 GUI。

如果您還沒有正在執行的資料庫容器,請參閱執行本地容器化資料庫

要使用 CLI 訪問 MySQL 容器的終端,您可以使用以下 docker exec 命令。

$ docker exec -it my-mysql bash

在此命令中

  • docker exec 告訴 Docker 您想在正在執行的容器中執行一個命令。
  • -it 確保您訪問的終端是互動式的,這樣您就可以在其中輸入命令。
  • my-mysql 是你的 MySQL 容器的名稱。如果你在執行時給容器起了不同的名字,請使用那個名字。
  • bash 是你想在容器內執行的命令。它會開啟一個 bash shell,讓你與容器的檔案系統和已安裝的應用程式進行互動。

執行此命令後,您將可以訪問 MySQL 容器內的 bash shell,從而可以直接管理您的 MySQL 伺服器。您可以執行 exit 返回到您的終端。

  1. 開啟 Docker Desktop 儀表板並選擇容器檢視。
  2. 在容器的操作列中,選擇顯示容器操作,然後選擇在終端中開啟

在這個終端中,你可以訪問 MySQL 容器內的 shell,從而可以直接管理你的 MySQL 伺服器。

一旦您訪問了容器的終端,就可以執行該容器中可用的任何工具。以下示例展示了在容器中使用 mysql 列出資料庫。

# mysql -u root -p
Enter password: my-secret-pw

mysql> SHOW DATABASES;

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

從主機連線到容器化資料庫

從主機連線到容器化資料庫涉及將容器內的埠對映到主機上的埠。此過程可確保容器內的資料庫可透過主機的網路訪問。對於 MySQL,預設埠是 3306。透過暴露此埠,您可以使用主機上的各種資料庫管理工具或應用程式與您的 MySQL 資料庫進行互動。

在開始之前,您必須移除之前為此指南執行的任何容器。要停止並移除一個容器,可以:

  • 在終端中,執行 docker rm --force my-mysql 以移除名為 my-mysql 的容器。
  • 或者,在 Docker Desktop 儀表板中,在容器檢視中選擇容器旁邊的刪除圖示。

接下來,您可以使用 Docker Desktop GUI 或 CLI 來執行帶有埠對映的容器。

在終端中執行以下命令。

$ docker run -p 3307:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest

在此命令中,-p 3307:3306 將主機上的埠 3307 對映到容器中的埠 3306。

要驗證埠是否已對映,請執行以下命令。

$ docker ps

您應該會看到類似以下的輸出。

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
6eb776cfd73c   mysql:latest   "docker-entrypoint.s…"   17 minutes ago   Up 17 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp   my-mysql

要使用 GUI 執行容器

  1. 在 Docker Desktop 儀表板中,選擇視窗頂部的全域性搜尋。

  2. 在搜尋框中指定 mysql,如果尚未選擇,請選擇 Images 選項卡。

  3. 將滑鼠懸停在 mysql 映象上,然後選擇 Run。將出現執行新容器模式視窗。

  4. 展開可選設定

  5. 在可選設定中,指定以下內容

    • 容器名稱: my-mysql
    • 3306/tcp 埠的主機埠3307
    • 環境變數:
      • MYSQL_ROOT_PASSWORDmy-secret-pw
      • MYSQL_DATABASEmydb
    The optional settings screen with the options specified.
  6. 選擇 Run

  7. 容器檢視中,驗證埠是否在列下對映。您應該看到 my-mysql 容器的 3307:3306

此時,在您的主機上執行的任何應用程式都可以透過 localhost:3307 訪問容器中的 MySQL 服務。

從另一個容器連線到容器化資料庫

從另一個容器連線到容器化資料庫是微服務架構和開發過程中的常見場景。Docker 的網路功能使得建立這種連線變得容易,而無需將資料庫暴露給主機網路。這是透過將資料庫容器和需要訪問它的容器放在同一個 Docker 網路上來實現的。

在開始之前,您必須移除之前為此指南執行的任何容器。要停止並移除一個容器,可以:

  • 在終端中,執行 docker rm --force my-mysql 以移除名為 my-mysql 的容器。
  • 或者,在 Docker Desktop 儀表板中,在容器檢視中選擇容器旁邊的刪除圖示。

要建立一個網路並在其上執行容器:

  1. 執行以下命令建立一個名為 my-network 的 Docker 網路。

    $ docker network create my-network
    
  2. 執行您的資料庫容器,並使用 --network 選項指定網路。這將在 my-network 網路上執行容器。

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb --network my-network -d mysql:latest
    
  3. 執行你的其他容器,並使用 --network 選項指定網路。在本例中,你將執行一個可以連線到資料庫的 phpMyAdmin 容器。

    1. 執行一個 phpMyAdmin 容器。使用 --network 選項指定網路,使用 -p 選項讓您可以從主機訪問該容器,並使用 -e 選項為此映象指定一個必需的環境變數。

      $ docker run --name my-phpmyadmin -d --network my-network -p 8080:80 -e PMA_HOST=my-mysql phpmyadmin
      
  4. 驗證容器之間可以通訊。在此示例中,您將訪問 phpMyAdmin 並驗證它是否連線到資料庫。

    1. 開啟 https://:8080 訪問您的 phpMyAdmin 容器。
    2. 使用 root 作為使用者名稱和 my-secret-pw 作為密碼登入。您應該會連線到 MySQL 伺服器並看到您的資料庫列出。

此時,在您的 my-network 容器網路上執行的任何應用程式都可以透過 my-mysql:3306 訪問容器中的 MySQL 服務。

將資料庫資料持久化到卷中

在 Docker 卷中持久化資料庫資料對於確保您的資料在容器重啟和移除後仍然存在是必要的。Docker 卷允許您將資料庫檔案儲存在容器的可寫層之外,從而可以在不丟失資料的情況下升級容器、切換基礎映象以及共享資料。以下是如何使用 Docker CLI 或 Docker Desktop GUI 將卷附加到您的資料庫容器。

在開始之前,您必須移除之前為此指南執行的任何容器。要停止並移除一個容器,可以:

  • 在終端中,執行 docker rm --force my-mysql 以移除名為 my-mysql 的容器。
  • 或者,在 Docker Desktop 儀表板中,在容器檢視中選擇容器旁邊的刪除圖示。

接下來,您可以使用 Docker Desktop GUI 或 CLI 來執行帶有卷的容器。

要執行附加了卷的資料庫容器,請在 docker run 命令中包含 -v 選項,指定卷名和資料庫在容器記憶體儲資料的路徑。如果卷不存在,Docker 會自動為您建立它。

要執行一個帶有附加捲的資料庫容器,然後驗證資料是否持久化:

  1. 執行容器並附加捲。

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -v my-db-volume:/var/lib/mysql -d mysql:latest
    

    該命令將名為 my-db-volume 的卷掛載到容器內的 /var/lib/mysql 目錄。

  2. 在資料庫中建立一些資料。使用 docker exec 命令在容器內執行 mysql 並建立一個表。

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
    

    此命令使用容器中的 mysql 工具建立一個名為 mytable 的表,該表有一個名為 column_name 的列,並最後插入一個值為 value 的記錄。

  3. 停止並移除容器。如果沒有卷,您建立的表將在移除容器時丟失。

    $ docker rm --force my-mysql
    
  4. 啟動一個附加了卷的新容器。這次,您無需指定任何環境變數,因為配置已儲存在卷中。

    $ docker run --name my-mysql -v my-db-volume:/var/lib/mysql -d mysql:latest
    
  5. 驗證您建立的表仍然存在。再次使用 docker exec 命令在容器內執行 mysql

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
    

    此命令使用容器中的 mysql 工具從 mytable 表中選擇所有記錄。

    您應該會看到類似以下的輸出。

    column_name
    value
    

要執行一個帶有附加捲的資料庫容器,然後驗證資料是否持久化:

  1. 執行一個附加了卷的容器。

    1. 在 Docker Desktop 儀表板中,選擇視窗頂部的全域性搜尋。

    2. 在搜尋框中指定 mysql,如果尚未選擇,請選擇 Images 選項卡。

    3. 將滑鼠懸停在 mysql 映象上並選擇 Run。將出現 Run a new container 模式視窗。

    4. 展開可選設定

    5. 在可選設定中,指定以下內容

      • 容器名稱: my-mysql
      • 環境變數:
        • MYSQL_ROOT_PASSWORDmy-secret-pw
        • MYSQL_DATABASEmydb
      • :
        • my-db-volume/var/lib/mysql
      The optional settings screen with the options specified.

      這裡,卷的名稱是 my-db-volume,它被掛載在容器的 /var/lib/mysql 位置。

    6. 選擇 Run

  2. 在資料庫中建立一些資料。

    1. 容器檢視中,在您的容器旁邊選擇顯示容器操作圖示,然後選擇在終端中開啟

    2. 在容器的終端中執行以下命令以新增一個表。

      # mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
      

      此命令使用容器中的 mysql 工具建立一個名為 mytable 的表,該表有一個名為 column_name 的列,並最終插入一個值為 `value` 的記錄。

  3. 容器檢視中,選擇容器旁邊的刪除圖示,然後選擇永久刪除。如果沒有卷,您建立的表在刪除容器時會丟失。

  4. 執行一個附加了卷的容器。

    1. 在 Docker Desktop 儀表板中,選擇視窗頂部的全域性搜尋。

    2. 在搜尋框中指定 mysql,如果尚未選擇,請選擇 Images 選項卡。

    3. 將滑鼠懸停在 mysql 映象上並選擇 Run。將出現 Run a new container 模式視窗。

    4. 展開可選設定

    5. 在可選設定中,指定以下內容

      • 容器名稱: my-mysql
      • 環境變數:
        • MYSQL_ROOT_PASSWORDmy-secret-pw
        • MYSQL_DATABASEmydb
      • :
        • my-db-volume/var/lib/mysql
      The optional settings screen with the options specified.
    6. 選擇 Run

  5. 驗證您建立的表仍然存在。

    1. 容器檢視中,在您的容器旁邊選擇顯示容器操作圖示,然後選擇在終端中開啟

    2. 在容器的終端中執行以下命令,以驗證您建立的表仍然存在。

      # mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
      

      此命令使用容器中的 mysql 工具從 mytable 表中選擇所有記錄。

      您應該會看到類似以下的輸出。

      column_name
      value
      

此時,任何掛載了 my-db-volume 的 MySQL 容器都能夠訪問和儲存持久化資料。

構建自定義資料庫映象

自定義您的資料庫映象可以讓您在基礎資料庫伺服器之外包含額外的配置、指令碼或工具。這對於建立一個符合您特定開發或生產環境需求的 Docker 映象特別有用。以下示例概述瞭如何構建和執行一個包含表初始化指令碼的自定義 MySQL 映象。

在開始之前,您必須移除之前為此指南執行的任何容器。要停止並移除一個容器,可以:

  • 在終端中,執行 docker rm --force my-mysql 以移除名為 my-mysql 的容器。
  • 或者,在 Docker Desktop 儀表板中,在容器檢視中選擇容器旁邊的刪除圖示。

構建並執行您的自定義映象:

  1. 建立一個 Dockerfile。

    1. 在您的專案目錄中建立一個名為 Dockerfile 的檔案。例如,您可以在您選擇的空目錄中建立 Dockerfile。此檔案將定義如何構建您的自定義 MySQL 映象。

    2. 將以下內容新增到 Dockerfile 中。

      # syntax=docker/dockerfile:1
      
      # Use the base image mysql:latest
      FROM mysql:latest
      
      # Set environment variables
      ENV MYSQL_DATABASE mydb
      
      # Copy custom scripts or configuration files from your host to the container
      COPY ./scripts/ /docker-entrypoint-initdb.d/

      在這個 Dockerfile 中,您設定了 MySQL 資料庫名稱的環境變數。您還可以使用 COPY 指令將自定義配置檔案或指令碼新增到容器中。在此示例中,主機 ./scripts/ 目錄中的檔案被複制到容器的 /docker-entrypoint-initdb.d/ 目錄中。在此目錄中,當容器首次啟動時,將執行 .sh.sql.sql.gz 指令碼。有關 Dockerfile 的更多詳細資訊,請參閱 Dockerfile 參考

    3. 建立一個指令碼檔案來初始化資料庫中的表。在 Dockerfile 所在的目錄中,建立一個名為 scripts 的子目錄,然後建立一個名為 create_table.sql 的檔案,內容如下。

    CREATE TABLE IF NOT EXISTS mydb.myothertable (
      column_name VARCHAR(255)
    );
    
    INSERT INTO mydb.myothertable (column_name) VALUES ('other_value');

    您現在應該有以下目錄結構。

    ├── your-project-directory/
    │ ├── scripts/
    │ │ └── create_table.sql
    │ └── Dockerfile
  2. 構建您的映象。

    1. 在終端中,將目錄更改為您的 Dockerfile 所在的目錄。

    2. 執行以下命令來構建映象。

      $ docker build -t my-custom-mysql .
      

      在此命令中,-t my-custom-mysql 將您的新映象標記(命名)為 my-custom-mysql。命令末尾的句點 (.) 指定當前目錄為構建上下文,Docker 將在此處查詢 Dockerfile 和構建所需的任何其他檔案。

  3. 像在執行本地容器化資料庫中那樣執行您的映象。這一次,指定您的映象名稱而不是 mysql:latest。此外,您不再需要指定 MYSQL_DATABASE 環境變數,因為它現在由您的 Dockerfile 定義。

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d my-custom-mysql
    
  4. 使用以下命令驗證您的容器正在執行。

    $ docker ps
    

    您應該會看到類似以下的輸出。

    CONTAINER ID   IMAGE              COMMAND                  CREATED        STATUS          PORTS                 NAMES
    f74dcfdb0e59   my-custom-mysql   "docker-entrypoint.s…"    2 hours ago    Up 51 minutes   3306/tcp, 33060/tcp   my-mysql
    
  5. 驗證您的初始化指令碼已執行。在終端中執行以下命令以顯示 myothertable 表的內容。

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.myothertable;"
    

    您應該會看到類似以下的輸出。

    column_name
    other_value
    

任何使用您的 my-custom-mysql 映象執行的容器,在首次啟動時都會初始化該表。

使用 Docker Compose 執行資料庫

Docker Compose 是一個用於定義和執行多容器 Docker 應用程式的工具。透過單個命令,您可以配置應用程式的所有服務(如資料庫、Web 應用等)並進行管理。在本例中,您將建立一個 Compose 檔案,並使用它來執行一個 MySQL 資料庫容器和一個 phpMyAdmin 容器。

要使用 Docker Compose 執行您的容器:

  1. 建立一個 Docker Compose 檔案。

    1. 在您的專案目錄中建立一個名為 compose.yaml 的檔案。此檔案將定義服務、網路和卷。

    2. 將以下內容新增到 compose.yaml 檔案中。

      services:
        db:
          image: mysql:latest
          environment:
            MYSQL_ROOT_PASSWORD: my-secret-pw
            MYSQL_DATABASE: mydb
          ports:
            - 3307:3306
          volumes:
            - my-db-volume:/var/lib/mysql
      
        phpmyadmin:
          image: phpmyadmin/phpmyadmin:latest
          environment:
            PMA_HOST: db
            PMA_PORT: 3306
            MYSQL_ROOT_PASSWORD: my-secret-pw
          ports:
            - 8080:80
          depends_on:
            - db
      
      volumes:
        my-db-volume:

      對於資料庫服務:

      • db 是服務的名稱。
      • image: mysql:latest 指定該服務使用 Docker Hub 上的最新 MySQL 映象。
      • environment 列出了 MySQL 用於初始化資料庫的環境變數,例如 root 密碼和資料庫名稱。
      • ports 將主機上的 3307 埠對映到容器內的 3306 埠,允許您從主機連線到資料庫。
      • volumesmy-db-volume 掛載到容器內的 /var/lib/mysql 以持久化資料庫資料。

      除了資料庫服務,還有一個 phpMyAdmin 服務。預設情況下,Compose 會為您的應用程式設定一個單一網路。每個服務的容器都會加入預設網路,並且可以被該網路上的其他容器訪問,並透過服務名稱發現。因此,在 PMA_HOST 環境變數中,您可以指定服務名稱 db,以便連線到資料庫服務。有關 Compose 的更多詳細資訊,請參閱Compose 檔案參考

  2. 執行 Docker Compose。

    1. 開啟一個終端,並將目錄更改為您的 compose.yaml 檔案所在的目錄。

    2. 使用以下命令執行 Docker Compose。

      $ docker compose up
      

      現在,您可以在 https://:8080 訪問 phpMyAdmin,並使用 root作為使用者名稱和 my-secret-pw 作為密碼連線到您的資料庫。

    3. 要停止容器,請在終端中按 ctrl+c

現在,有了 Docker Compose,您可以透過一個命令啟動您的資料庫和應用程式、掛載卷、配置網路等等。

摘要

本指南向您介紹了使用容器化資料庫(特別是 MySQL)的基礎知識,以增強開發環境的靈活性、設定簡易性和一致性。本指南中涵蓋的用例不僅簡化了您的開發工作流程,還為您準備了更高階的資料庫管理和部署場景,確保您的資料驅動型應用程式保持健壯和可擴充套件。

相關資訊