使用容器化数据库

使用本地容器化数据库提供了灵活性和易于设置的优势,使您能够紧密地镜像生产环境,而无需传统数据库安装的开销。Docker简化了这一过程,使您只需几个命令即可在隔离的容器中部署、管理和扩展数据库。

在本指南中,您将学习如何:

  • 运行本地容器化数据库
  • 访问容器化数据库的shell
  • 从主机连接到容器化数据库
  • 从另一个容器连接到容器化的数据库
  • 将数据库数据持久化在卷中
  • 构建一个定制的数据库镜像
  • 使用 Docker Compose 运行数据库

本指南使用MySQL镜像作为示例,但这些概念可以应用于其他数据库镜像。

先决条件

要跟随本指南操作,您必须安装Docker。要安装Docker,请参阅 Get 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

要使用图形用户界面运行容器:

  1. 在Docker桌面仪表板中,选择窗口顶部的全局搜索。

  2. 在搜索框中指定mysql,如果尚未选择,请选择Images标签。

  3. 将鼠标悬停在msyql图像上并选择Run运行一个新容器模型将出现。

  4. 展开可选设置

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

    • Container name: my-mysql
    • Environment variables:
      • MYSQL_ROOT_PASSWORD:my-secret-pw
      • MYSQL_DATABASE:mydb
    The optional settings screen with the options specified.
  6. 选择 Run

  7. 打开Docker桌面仪表板中的容器视图,以验证您的容器是否正在运行。


访问容器化数据库的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 remove --force my-mysql 以删除名为 my-mysql 的容器。
  • 或者,在Docker桌面仪表板中,在容器视图中选择您容器旁边的删除图标。

接下来,您可以使用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

要使用图形用户界面运行容器:

  1. 在Docker桌面仪表板中,选择窗口顶部的全局搜索。

  2. 在搜索框中指定mysql,如果尚未选择,请选择Images标签。

  3. 将鼠标悬停在msyql图像上并选择Run运行一个新容器模型将出现。

  4. 展开可选设置

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

    • Container name: my-mysql
    • Host port for the 3306/tcp port: 3307
    • Environment variables:
      • 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桌面仪表板中,在容器视图中选择您容器旁边的删除图标。

要创建一个网络并在其上运行容器:

  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. Open http://localhost:8080 to access your phpMyAdmin container.
    2. Log in using root as the username and my-secret-pw as the password. You should connect to the MySQL server and see your database listed.

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

在卷中持久化数据库数据

在Docker卷中持久化数据库数据是确保数据在容器重启和删除后仍然存在的必要措施。Docker卷允许您将数据库文件存储在容器的可写层之外,从而可以在不丢失数据的情况下升级容器、切换基础镜像以及共享数据。以下是您可以使用Docker CLI或Docker Desktop GUI将卷附加到数据库容器的方法。

在开始之前,您必须移除之前为本指南运行的所有容器。要停止并移除容器,可以执行以下任一操作:

  • 在终端中,运行 docker remove --force my-mysql 以删除名为 my-mysql 的容器。
  • 或者,在Docker桌面仪表板中,在容器视图中选择您容器旁边的删除图标。

接下来,您可以使用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桌面仪表板中,选择窗口顶部的全局搜索。

    2. 在搜索框中指定mysql,如果尚未选择,请选择图片标签。

    3. 将鼠标悬停在mysql图像上并选择运行运行新容器模型将出现。

    4. 展开可选设置

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

      • Container name: my-mysql
      • Environment variables:
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • Volumes:
        • 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桌面仪表板中,选择窗口顶部的全局搜索。

    2. 在搜索框中指定mysql,如果尚未选择,请选择图片标签。

    3. 将鼠标悬停在mysql图像上并选择运行运行新容器模型将出现。

    4. 展开可选设置

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

      • Container name: my-mysql
      • Environment variables:
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • Volumes:
        • 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桌面仪表板中,在容器视图中选择您容器旁边的删除图标。

构建并运行您的自定义镜像:

  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脚本在容器首次启动时被执行。有关Dockerfiles的更多详细信息,请参阅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 is the name of the service.
      • image: mysql:latest specifies that the service uses the latest MySQL image from Docker Hub.
      • environment lists the environment variables used by MySQL to initialize the database, such as the root password and the database name.
      • ports maps port 3307 on the host to port 3306 in the container, allowing you to connect to the database from your host machine.
      • volumes mounts my-db-volume to /var/lib/mysql inside the container to persist database data.

      除了数据库服务外,还有一个phpMyAdmin服务。默认情况下,Compose为您的应用程序设置了一个单一的网络。每个服务的容器都会加入默认网络,并且可以被该网络上的其他容器访问,也可以通过服务名称被发现。因此,在PMA_HOST环境变量中,您可以指定服务名称db,以便连接到数据库服务。有关Compose的更多详细信息,请参阅Compose文件参考

  2. 运行 Docker Compose。

    1. 打开终端并更改目录到您的compose.yaml文件所在的目录。

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

      $ docker compose up
      

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

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

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

摘要

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

相关信息: