使用容器化数据库

使用本地容器化数据库提供了灵活性和易于设置的优点,让你能够密切镜像生产环境,而无需传统数据库安装的开销。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,如果尚未选中,则选择“镜像”选项卡。

  3. 将鼠标悬停在 mysql 镜像上,然后选择“运行”(Run)。将出现运行新容器(Run a new container)模态框。

  4. 展开可选设置(Optional settings)。

  5. 在可选设置中,指定以下内容

    • 容器名称my-mysql
    • 环境变量:
      • MYSQL_ROOT_PASSWORD:my-secret-pw
      • MYSQL_DATABASE:mydb
    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,如果尚未选中,则选择“镜像”选项卡。

  3. 将鼠标悬停在 mysql 镜像上,然后选择“运行”(Run)。将出现运行新容器(Run a new container)模态框。

  4. 展开可选设置(Optional settings)。

  5. 在可选设置中,指定以下内容

    • 容器名称my-mysql
    • 主机端口,对应 3306/tcp 端口: 3307
    • 环境变量:
      • MYSQL_ROOT_PASSWORD:my-secret-pw
      • MYSQL_DATABASE:mydb
    The optional settings screen with the options specified.
  6. 选择“运行”(Run)。

  7. 容器视图中,在端口列下验证端口是否已映射。你应看到 my-mysql 容器的 3307:3306


此时,在主机上运行的任何应用程序都可以通过 localhost:3307 访问容器中的 MySQL 服务。

从另一个容器连接到容器化数据库

从另一个容器连接到容器化数据库是微服务架构和开发过程中的常见场景。Docker 的网络功能使其易于建立此连接,而无需将数据库暴露给主机网络。这可以通过将数据库容器和需要访问它的容器放置在同一 Docker 网络上来实现。

在你开始之前,你必须移除之前为本指南运行的任何容器。要停止并移除容器,可以使用

  • 在终端中,运行 docker remove --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. 打开http://localhost:8080 以访问你的 phpMyAdmin 容器。
    2. 使用 root 作为用户名,my-secret-pw 作为密码登录。你应成功连接到 MySQL 服务器并看到你的数据库列表。

此时,在你的 my-network 容器网络上运行的任何应用程序都可以通过 my-mysql:3306 访问容器中的 MySQL 服务。

将数据库数据持久化到卷中

将数据库数据持久化到 Docker 卷中对于确保数据在容器重启和移除后仍然存在至关重要。Docker 卷让你能够将数据库文件存储在容器的可写层之外,使得在升级容器、切换基础镜像和共享数据时不会丢失数据成为可能。以下介绍了如何使用 Docker CLI 或 Docker Desktop GUI 将卷附加到数据库容器。

在你开始之前,你必须移除之前为本指南运行的任何容器。要停止并移除容器,可以使用

  • 在终端中,运行 docker remove --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 remove --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,如果尚未选中,则选择镜像选项卡。

    3. 将鼠标悬停在 mysql 镜像上,然后选择运行(Run)。将出现运行新容器(Run a new container)模态框。

    4. 展开可选设置(Optional settings)。

    5. 在可选设置中,指定以下内容

      • 容器名称my-mysql
      • 环境变量:
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • :
        • 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,如果尚未选中,则选择镜像选项卡。

    3. 将鼠标悬停在 mysql 镜像上,然后选择运行(Run)。将出现运行新容器(Run a new container)模态框。

    4. 展开可选设置(Optional settings)。

    5. 在可选设置中,指定以下内容

      • 容器名称my-mysql
      • 环境变量:
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • :
        • 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 remove --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
      

      你现在可以通过http://localhost:8080 访问 phpMyAdmin,并使用 root 作为用户名,my-secret-pw 作为密码连接到数据库。

    3. 要停止容器,请在终端中按 ctrl+c

现在,使用 Docker Compose,你只需一个命令就可以启动你的数据库和应用程序、挂载卷、配置网络等等。

总结

本指南介绍了使用容器化数据库的基本知识,特别是重点讲解了 MySQL,以增强开发环境中的灵活性、易于设置和一致性。本指南涵盖的用例不仅可以简化你的开发工作流程,还可以让你为更高级的数据库管理和部署场景做好准备,确保你的数据驱动应用程序保持健壮和可扩展。

相关信息

页面选项