使用容器化数据库
使用本地容器化数据库提供了灵活性和易于设置的优点,让你能够密切镜像生产环境,而无需传统数据库安装的开销。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 运行容器
在 Docker Desktop 控制面板中,选择窗口顶部的全局搜索。
在搜索框中指定
mysql
,如果尚未选中,则选择“镜像”选项卡。将鼠标悬停在
mysql
镜像上,然后选择“运行”(Run)。将出现运行新容器(Run a new container)模态框。展开可选设置(Optional settings)。
在可选设置中,指定以下内容
- 容器名称:
my-mysql
- 环境变量:
MYSQL_ROOT_PASSWORD
:my-secret-pw
MYSQL_DATABASE
:mydb
- 容器名称:
选择“运行”(Run)。
在 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
返回到终端。
- 打开 Docker Desktop 控制面板并选择容器视图。
- 在你容器的操作列中,选择显示容器操作,然后选择在终端中打开。
在此终端中,你可以访问 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 运行容器
在 Docker Desktop 控制面板中,选择窗口顶部的全局搜索。
在搜索框中指定
mysql
,如果尚未选中,则选择“镜像”选项卡。将鼠标悬停在
mysql
镜像上,然后选择“运行”(Run)。将出现运行新容器(Run a new container)模态框。展开可选设置(Optional settings)。
在可选设置中,指定以下内容
- 容器名称:
my-mysql
- 主机端口,对应 3306/tcp 端口:
3307
- 环境变量:
MYSQL_ROOT_PASSWORD
:my-secret-pw
MYSQL_DATABASE
:mydb
- 容器名称:
选择“运行”(Run)。
在容器视图中,在端口列下验证端口是否已映射。你应看到 my-mysql 容器的 3307:3306。
此时,在主机上运行的任何应用程序都可以通过 localhost:3307
访问容器中的 MySQL 服务。
从另一个容器连接到容器化数据库
从另一个容器连接到容器化数据库是微服务架构和开发过程中的常见场景。Docker 的网络功能使其易于建立此连接,而无需将数据库暴露给主机网络。这可以通过将数据库容器和需要访问它的容器放置在同一 Docker 网络上来实现。
在你开始之前,你必须移除之前为本指南运行的任何容器。要停止并移除容器,可以使用
- 在终端中,运行
docker remove --force my-mysql
以移除名为my-mysql
的容器。 - 或者,在 Docker Desktop 控制面板中,在容器视图中,选择容器旁边的删除图标。
创建网络并在其上运行容器
运行以下命令创建名为
my-network
的 Docker 网络。$ docker network create my-network
运行你的数据库容器,并使用
--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
运行你的其他容器,并使用
--network
选项指定网络。在本例中,你将运行一个可以连接到数据库的 phpMyAdmin 容器。运行一个 phpMyAdmin 容器。使用
--network
选项指定网络,使用-p
选项让你从主机访问容器,以及使用-e
选项为此镜像指定所需的环境变量。$ docker run --name my-phpmyadmin -d --network my-network -p 8080:80 -e PMA_HOST=my-mysql phpmyadmin
验证容器是否可以通信。在本例中,你将访问 phpMyAdmin 并验证它是否连接到数据库。
- 打开http://localhost:8080 以访问你的 phpMyAdmin 容器。
- 使用
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 会自动为你创建它。
运行带有卷的数据库容器,然后验证数据是否持久化
运行容器并附加卷。
$ 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
目录。在数据库中创建一些数据。使用
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
的记录。停止并移除容器。如果没有卷,你在移除容器时创建的表将会丢失。
$ docker remove --force my-mysql
启动一个带有附加卷的新容器。这次,你无需指定任何环境变量,因为配置已保存在卷中。
$ docker run --name my-mysql -v my-db-volume:/var/lib/mysql -d mysql:latest
验证你创建的表仍然存在。再次使用
docker exec
命令在容器内部运行mysql
。$ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
此命令使用容器中的
mysql
工具从mytable
表中选择所有记录。你应看到类似如下的输出。
column_name value
运行带有卷的数据库容器,然后验证数据是否持久化
运行带有附加卷的容器。
在 Docker Desktop 控制面板中,选择窗口顶部的全局搜索。
在搜索框中指定
mysql
,如果尚未选中,则选择镜像选项卡。将鼠标悬停在 mysql 镜像上,然后选择运行(Run)。将出现运行新容器(Run a new container)模态框。
展开可选设置(Optional settings)。
在可选设置中,指定以下内容
- 容器名称:
my-mysql
- 环境变量:
MYSQL_ROOT_PASSWORD
:my-secret-pw
MYSQL_DATABASE
:mydb
- 卷:
my-db-volume
:/var/lib/mysql
此处,卷的名称为
my-db-volume
,并将其挂载到容器中的/var/lib/mysql
目录。- 容器名称:
选择“运行”(Run)。
在数据库中创建一些数据。
在容器视图中,在容器旁边选择显示容器操作图标,然后选择在终端中打开。
在容器的终端中运行以下命令以添加一张表。
# 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` 的记录。
在容器视图中,选择容器旁边的删除图标,然后选择永久删除。如果没有卷,你在删除容器时创建的表将会丢失。
运行带有附加卷的容器。
在 Docker Desktop 控制面板中,选择窗口顶部的全局搜索。
在搜索框中指定
mysql
,如果尚未选中,则选择镜像选项卡。将鼠标悬停在 mysql 镜像上,然后选择运行(Run)。将出现运行新容器(Run a new container)模态框。
展开可选设置(Optional settings)。
在可选设置中,指定以下内容
- 容器名称:
my-mysql
- 环境变量:
MYSQL_ROOT_PASSWORD
:my-secret-pw
MYSQL_DATABASE
:mydb
- 卷:
my-db-volume
:/var/lib/mysql
- 容器名称:
选择“运行”(Run)。
验证你创建的表仍然存在。
在容器视图中,在容器旁边选择显示容器操作图标,然后选择在终端中打开。
在容器的终端中运行以下命令,验证你创建的表仍然存在。
# 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 控制面板中,在容器视图中,选择容器旁边的删除图标。
构建并运行你的自定义镜像
创建 Dockerfile 文件。
在项目目录中创建名为
Dockerfile
的文件。在本例中,你可以在你选择的空目录中创建Dockerfile
。此文件将定义如何构建你的自定义 MySQL 镜像。将以下内容添加到
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 参考。创建一个脚本文件以初始化数据库中的表。在
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
构建你的镜像。
在终端中,更改到
Dockerfile
所在的目录。运行以下命令构建镜像。
$ docker build -t my-custom-mysql .
在此命令中,
-t my-custom-mysql
将你的新镜像标记(命名)为my-custom-mysql
。命令末尾的点(.)指定当前目录作为构建上下文,Docker 会在该目录中查找 Dockerfile 以及构建所需的任何其他文件。
按照运行本地容器化数据库的方式运行你的镜像。这次,指定你的镜像名称而不是
mysql:latest
。此外,你不再需要指定MYSQL_DATABASE
环境变量,因为它已在你的 Dockerfile 中定义。$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d my-custom-mysql
使用以下命令验证容器是否正在运行。
$ 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
验证你的初始化脚本已运行。在终端中运行以下命令,显示
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 运行容器
创建 Docker Compose 文件。
在项目目录中创建一个名为
compose.yaml
的文件。此文件将定义服务、网络和卷。将以下内容添加到
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 端口,允许你从主机连接到数据库。volumes
将my-db-volume
挂载到容器内部的/var/lib/mysql
,以持久化数据库数据。
除了数据库服务,还有一个 phpMyAdmin 服务。默认情况下,Compose 会为你的应用程序设置一个单一网络。每个服务的容器都会加入默认网络,并且可以被同一网络上的其他容器访问,也可以通过服务的名称进行发现。因此,在
PMA_HOST
环境变量中,你可以指定服务名称db
,以便连接到数据库服务。有关 Compose 的更多详细信息,请参阅Compose 文件参考。
运行 Docker Compose。
打开终端,并更改到
compose.yaml
文件所在的目录。使用以下命令运行 Docker Compose。
$ docker compose up
你现在可以通过http://localhost:8080 访问 phpMyAdmin,并使用
root
作为用户名,my-secret-pw
作为密码连接到数据库。要停止容器,请在终端中按
ctrl
+c
。
现在,使用 Docker Compose,你只需一个命令就可以启动你的数据库和应用程序、挂载卷、配置网络等等。
总结
本指南介绍了使用容器化数据库的基本知识,特别是重点讲解了 MySQL,以增强开发环境中的灵活性、易于设置和一致性。本指南涵盖的用例不仅可以简化你的开发工作流程,还可以让你为更高级的数据库管理和部署场景做好准备,确保你的数据驱动应用程序保持健壮和可扩展。
相关信息