在 Docker 容器中使用 MySQL,可以说是天作之合。如果您之前使用过 Docker,那么它的所有优势同样适用于 MySQL Docker 容器:
- 隔离性与一致性:MySQL 实例将与其他软件和依赖分离,避免潜在冲突。
- 版本控制:Docker 允许您与 MySQL 一起为整套软件栈做版本化。您可以随时复现环境,便于开发与测试。
- 可扩展与资源管理:借助 Docker,您可以通过轻松分配更多内存或 CPU 来扩展 MySQL 应用。
- 依赖管理:Docker 封装您的 MySQL 实例,让您可以管理不同版本,而不影响本机的其他内容。
最重要的是,您的 MySQL 应用可以在任何地方运行,而不仅仅是您的电脑上。
如果您想将 MySQL 与其第二受欢迎的竞争对手进行对比,欢迎查看我们的深度比较文章 PostgreSQL 与 MySQL。
今天,您将学习如何将 MySQL 与 Docker 协同运行的基础知识。让我们开始吧!
先决条件
由于本文聚焦于 MySQL Docker 容器,跟进实践需要满足以下前提:
- 命令行/终端访问:您需要一个可访问终端的本地环境。如果您在 Colab 等 Jupyter 环境中,请现在切换。
- 正在运行的 Docker 实例:您应已安装 Docker Desktop(可参考我们的 面向数据科学的 Docker 教程)。完全就绪后,界面左下角会出现绿色小鲸鱼:

并且在终端中运行 docker --help 命令不会报错。
- 具备 Docker 基础:尽管我会讲解文中使用的所有命令,但具备基本的 Docker 理解,会显著提升您从本文获得的收益。
- SQL:SQL 同理——本文不讲解出现的 SQL 命令,以免偏离主题。如果您的 SQL 技能有些生疏,可在这门 SQL 课程中回顾重点。
下载官方 MySQL Docker 镜像
我们先用下面的命令下载官方 MySQL Docker 镜像:
$ docker pull mysql:latest
docker pull 需要以 image:version 的语法指定镜像名称和版本。使用关键字 latest 将下载最新的稳定版。
如果访问 Docker Hub 上的官方 MySQL 镜像页面,您会看到为不同用途提供的许多版本。

例如,以下命令用于下载 v8.2:
$ docker pull mysql:8.2
下载完成后,镜像应会出现在您现有的 Docker 镜像列表中:

也可以通过终端列出 Docker 镜像:
$ docker images

请记住:Docker 镜像是构建容器的蓝图。就像蓝图能指导建房一样,Docker 镜像包含创建某个应用或服务运行实例所需的全部指令与组件。
如果您有 OOP 背景,可以把 Docker 镜像类比为类(class)。正如一个类能实例化出多个对象,Docker 镜像也能基于它们创建多个容器。
运行与管理 MySQL 服务器容器
现在,让我们基于 mysql 镜像创建第一个容器。使用如下命令:
$ docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -d mysql
run:创建一个新容器或启动现有容器--name CONTAINER_NAME:为容器命名。名称应简短易读。本例为test-mysql。-e ENV_VARIABLE=value:-e标记用于在容器内创建可访问的环境变量。必须设置MYSQL_ROOT_PASSWORD,以便稍后能在容器中运行 SQL 命令。请务必妥善保存您的强密码(别只记在脑子里)。-d:即 detached,表示让容器在后台运行。若去掉此标签,命令会持续打印日志直到容器停止。image_name:最后一个参数是用于构建容器的镜像名。此处为mysql。
如果命令返回一长串字符(容器 ID),说明容器已启动。您可以用 docker ps 查看其状态:

请记住:Docker 容器是功能强大的操作系统“仿真环境”。除了运行 MySQL,您还可以在容器内完成任何通常在电脑终端中进行的任务。
要进入容器内的终端,可使用:
$ docker exec -it container_name bash
这会启动一个 bash 会话。
在本机连接 MySQL 服务器容器
所有 MySQL 容器都会启动一个MySQL 服务器,它包含用于用 SQL 创建和管理数据库的一切。同时,容器也带有用于连接服务器的MySQL 客户端,让我们可以运行 SQL 查询。客户端其实就是 mysql 终端命令的“好听名字”。我们在 test-mysql 的终端里试用它:
1. 打开 test-mysql 的 bash 终端:
$ docker exec -it test-mysql bash
2. 以 root 用户连接客户端:
$ mysql -u root -p
Enter password: ...
mysql>
我们使用 -u 指定用户名(root),并加上 -p 在提示时输入密码。

也可以在容器外连接 MySQL 服务器。例如,您可以在主机上手动安装 MySQL 客户端进行连接。
在 Windows 上安装 MySQL 及其客户端,可参照官方 MySQL 安装指南。
Mac 上可用 Homebrew:
$ brew install mysql
Linux 或 WSL2(我个人的选择)上可使用 sudo:
$ sudo apt update
$ sudo apt install mysql-client
安装完成后,如果容器正在运行,请先停止并移除:
$ docker stop test-mysql
test-mysql
$ docker rm test-mysql
接下来,我们将通过映射端口的方式重新启动容器:
$ docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -p 3307:3306 mysql
该命令的作用如下:
-p 3307:3306:将容器的 3306 端口(MySQL 默认端口)映射到本地 3307 端口。也就是说,发往您本地 3307 端口的流量会被转发到容器内的 3306 端口,您的 MySQL 服务器将通过该端口可达。-d:再次以分离模式运行容器。--name test-mysql:继续使用容器名 "test-mysql"。-e MYSQL_ROOT_PASSWORD=strong_password:再次为 MySQL 服务器设置 root 密码。mysql:指定要运行的 Docker 镜像,即官方 MySQL 镜像。
终端输出新容器 ID 后,我们可以查看端口映射:
$ docker port test-mysql
3306/tcp -> 0.0.0.0:3307
映射成功!现在,您可以在本机上通过端口 3307 使用 mysql 客户端连接服务器:
$ mysql --host=127.0.0.1 --port=3307 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.2.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates…
配置 MySQL 容器
您可以通过配置文件对 MySQL 容器进行大量设置。该文件通常存放在容器的以下目录之一:
/etc/mysql//etc/mysql/conf.d/etc/mysql/mysql.conf.d
不同镜像的目录可能不同。但配置文件的标准文件名与扩展名为 my.cnf。如果在上述任一目录都不存在该文件,说明该容器需要自定义配置文件。我们的 test-mysql 容器正是这种情况:
$ ls /etc/mysql/conf.d/ # Returns no output
遇到这种情况,我们需要谨慎地按以下步骤操作:
1. 停止并移除容器:
$ docker stop test-mysql; docker rm test-mysql
2. 在本地(您的机器上)创建一个空配置文件:
$ sudo mkdir -p /etc/docker/test-mysql # Create a dir
$ sudo touch /etc/docker/test-mysql/my.cnf # Create a config file inside dir
3. 通过关联这两个空的 .cnf 文件来重启容器:
$ docker run \
--name test-mysql \
-v /etc/docker/test-mysql:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=strong_password \
-d mysql
这里我们使用了一个新标签:-v,即 volume。该标签用于在容器与本机之间关联目录。在计算机科学术语中,这个过程称为挂载。
因此,在上面的命令中,我们将本地的 /etc/docker/test-mysql 目录挂载到容器的 /etc/mysql/conf.d 目录。这样会同步两个目录的内容。在任一目录所做的更改都会体现在两边。
通过挂载,我们可以在本机编辑 my.cnf 文件,从而更改 Docker 容器的配置。更棒的是,即使容器被停止或移除,修改过的配置仍会保存在本机,可重复使用。
那么,完成这一步之后,可以修改哪些配置?答案取决于您的使用场景。我们将在下文介绍。
想要获得 Docker 认证吗?请查看我们的Docker 认证指南!
应该配置哪些选项?
尽管 MySQL Docker 容器的默认配置适用于许多常见场景,但为优化性能、安全性和资源使用,您应当调整某些设置。以下是最常见的一些配置项:
性能
- innodb_buffer_pool_size:决定分配给 InnoDB 缓冲池的内存大小,缓冲池会缓存常用数据以加快读取。增大该值可提升读密集型负载的性能,但会占用更多内存。
- query_cache_size:控制查询缓存的大小,存储已执行的查询以加快重复执行。增大该值有助于提升重复性查询的性能,但会占用更多内存,对高度动态的查询可能效果不佳。
- thread_pool_size:决定服务器可处理的最大并发连接数。根据预期流量调整该值可优化资源利用并防止瓶颈。
安全
- bind-address:限制 MySQL 服务器仅监听特定网络接口,阻止未授权来源的访问。
- mysql_bind_host:允许将 MySQL 服务器绑定到特定 IP 地址,而非监听所有接口。
- validate_password_policy:启用更严格的密码要求,以提升安全性。
资源利用
- max_connections:控制允许的最大并发连接数。适当调整可避免资源耗尽,确保服务器高效运行。
- innodb_file_per_table:将每个 InnoDB 表存储在单独文件中,可能提升性能,但会增加存储占用。
- innodb_io_capacity:设置存储系统的预估 IOPS(每秒输入/输出操作数),以便引擎优化缓冲池使用与磁盘操作。
其他常见修改
- character_set_server:设置服务器的默认字符集,确保数据编码和处理一致。
- collation_server:决定字符数据排序与比较所使用的默认校对规则。
- log_bin:启用服务器活动的二进制日志,有助于故障排查与复制。
要查看完整的配置选项列表,可以运行以下命令:
$ docker run -it --rm mysql:tag --verbose --help
您可以使用任意文本编辑器编辑 .cnf 文件。语法如下:
[mysqld]
max_connections=200
other_params=value
...
如何持久化 MySQL Docker 容器中的数据
将 MySQL 容器中的数据持久化至关重要,原因包括:
- 数据持久性:停止或移除容器时,所有数据(包括数据库)都会丢失。将数据与容器解耦可确保随时可访问。
- 在容器之间共享数据:将数据从容器中分离,允许多个容器访问同一份数据,从而避免数据重复,简化使用相同数据的项目之间的同步。
- 可移植性与备份:持久化的数据易于独立备份与共享,可为数据丢失或误删提供可靠的恢复途径。
- 更好的性能与可扩展性:将常用数据存放在 SSD 等持久化存储上,相比依赖通常较慢的容器可写层,可提升应用性能。
流程与我们已经见过的类似——创建一个卷并将其挂载到容器中存储数据的位置。步骤如下:
1. 创建一个卷:
$ docker volume create test-mysql-data
volume create 命令会在本地文件系统上为该卷创建专用存储。卷被挂载后,所有容器数据都将与其关联。
2. 挂载该卷后重启容器:
$ docker stop test-mysql; docker rm test-mysql
$ docker run \
--name test-mysql \
-v test-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=strong_password \
-d mysql
这次的语法为:-v volume_name:directory_in_container。按照 MySQL 镜像文档,所有创建的卷都应挂载到 /var/lib/mysql 目录。
现在,在 test-mysql 中创建的任何数据库或表都会在本地持久化,即使容器被停止或移除也不受影响。
最终命令
在本文中,我们的 docker run 命令经历了多次演进。现在,让我们把所有变体整合成一个最终“总命令”。我们需要再次停止并移除容器,同时移除卷以便从头开始:
$ docker stop test-mysql; docker rm test-mysql
$ docker volume rm test-mysql-data
下面是最终的总命令:
$ docker run \
--name final-mysql \
-e MYSQL_ROOT_PASSWORD=strong_password \
-p 3307:3306 \
-v /etc/docker/test-mysql:/etc/mysql/conf.d \
-v final-mysql-data:/var/lib/mysql \
-d mysql
该命令会将我们之前的本地 my.cnf 文件挂载到目标位置,同时创建并挂载名为 final-mysql-data 的新卷。
使用 Docker Compose 管理复杂的 MySQL 部署
对于涉及多个容器的高级场景(例如将 MySQL 与其他服务一起运行,如 Web 服务器或应用后端),Docker Compose 通过单个配置文件定义和管理多容器应用,从而简化流程。
以下是一个用于 MySQL 容器的基础 docker-compose.yml 示例:
version: '3.9'
services:
db:
image: mysql:8.3.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: strong_password
MYSQL_DATABASE: example_db
MYSQL_USER: user
MYSQL_PASSWORD: user_password
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
- ./mysql-config:/etc/mysql/conf.d
volumes:
db_data:
使用 Docker Compose 的步骤:
- 创建
docker-compose.yml文件:将配置文件保存在您的项目目录中。 - 启动服务:运行以下命令启动文件中定义的所有服务:
docker-compose up -d
- 停止服务:完成后关闭服务:
docker-compose down
Docker Compose 对 MySQL 的好处:
- 配置更简化:在单个文件中管理 MySQL 配置、端口与卷。
- 更易扩展:轻松扩展数据库,或将其与应用栈中的其他服务集成。
- 数据持久化:在容器重启间自动管理卷,确保数据持久化。
在管理多个环境(如开发、预发布和生产)或与团队协作时,使用 Docker Compose 尤其有帮助。
结语
本文介绍了在 Docker 容器中运行与管理 MySQL 数据库的关键要点。我们学习了如何下载与设置 MySQL 镜像、在容器内启动 MySQL 服务器、如何修改容器并通过卷实现自定义配置与数据持久化。
若想进一步学习,推荐以下资源:
感谢阅读!
FAQs
Can I use Docker Compose to manage multiple MySQL containers?
可以。Docker Compose 是管理多个 Docker 容器(包括 MySQL)的优秀工具。您可以在 docker-compose.yml 文件中定义 MySQL 服务配置,从而用一条命令启动、停止并管理多个服务。
How do I upgrade MySQL to a newer version in a Docker container?
要在 Docker 容器中升级 MySQL,您需要先拉取新版本的 MySQL Docker 镜像,然后用该新镜像重新创建容器。升级前请确保已备份数据。
Can I run multiple MySQL containers on the same host?
可以,您可以在同一主机上运行多个 MySQL 容器。每个容器都必须通过 -p 选项在主机上分配唯一端口,以避免端口冲突。
What are the security best practices for running MySQL containers?
安全最佳实践包括:在没有完善安全措施的情况下,不要将 MySQL 容器暴露在公网;使用强密码;定期更新 Docker 与 MySQL 镜像;对密码等敏感信息使用 Docker secrets。
How can I automate the backup of MySQL databases in Docker?
您可以在主机上创建一个定时任务(cron job),使用 docker exec 在容器内运行 mysqldump。或者,您也可以使用 Docker 卷来持久化数据,并直接在主机上执行备份。
Can I connect to the MySQL Docker container from another container?
可以。只要确保两个容器位于同一 Docker 网络上,就可以从另一个容器进行连接。连接时可以使用该容器的名称作为主机名。
How do I troubleshoot connection issues with my MySQL container?
可通过以下方式排查连接问题:检查容器是否正在运行(docker ps),验证端口映射(docker port),检查网络配置,并确保容器内的 MySQL 服务器已配置为接受来自主机或其他容器的连接。
Is it possible to use a custom MySQL configuration file without mounting it from the host?
可以,您可以在容器内创建自定义配置文件。不过,更常见的做法是从主机进行挂载,便于管理与持久化。
How can I monitor the performance of my MySQL container?
您可以使用 mysqladmin 等工具监控 MySQL 专属指标,使用 Docker 内置的统计命令(docker stats),或使用 Prometheus 等第三方监控方案,配合 Docker 与 MySQL 的导出器。
What should I do if my MySQL Docker container crashes?
如果容器崩溃,首先使用 docker logs <container_name> 查看日志以定位错误。确保配置与环境变量正确,并确认不存在资源(CPU、内存)限制。重启容器并监控其运行状况。

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。
MySQL 是最受欢迎的关系型数据库工具,市场份额超过 40%。与其竞争对手 PostgreSQL(16%)和 Oracle Database(11%)相比,数据相当亮眼。
MySQL 之所以流行,是因为它简单却强大。以下是它的一些最佳特性: