使用容器化数据库

使用本地容器化数据库提供了灵活性和易于设置的优势,让您可以紧密地模拟生产环境,而无需传统数据库安装的开销。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)的基础知识,以增强开发环境的灵活性、设置简易性和一致性。本指南中涵盖的用例不仅简化了您的开发工作流程,还为您准备了更高级的数据库管理和部署场景,确保您的数据驱动型应用程序保持健壮和可扩展。

相关信息

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.