MySQL Docker 部署:从入门到实践
随着容器化技术的日益普及,Docker 已成为现代软件开发和部署不可或缺的工具。将数据库部署在 Docker 容器中,不仅能简化环境配置、提高可移植性,还能更好地进行资源隔离和版本管理。本文将详细介绍如何从零开始,逐步实践 MySQL 在 Docker 中的部署。
1. 为什么选择 Docker 部署 MySQL?
在深入实践之前,我们先了解一下 Docker 部署 MySQL 的主要优势:
- 环境一致性: 避免了“在我的机器上可以运行”的问题。无论是开发、测试还是生产环境,MySQL 实例都运行在相同的容器镜像中。
- 快速启动与销毁: 几秒钟内即可启动一个新的 MySQL 实例,测试完成后也能轻松销毁,不留下任何残留,非常适合开发和测试场景。
- 版本管理: 轻松切换不同版本的 MySQL,例如测试 MySQL 5.7 或 8.0 的特性,而无需在宿主机上安装多个版本。
- 资源隔离: 容器为 MySQL 提供了独立的运行环境,与其他应用互不影响。
- 可移植性: 容器化后的 MySQL 可以在任何支持 Docker 的平台上运行,极大地简化了部署流程。
- 简化配置: 数据库的复杂配置可以通过 Docker 命令或
docker-compose文件进行统一管理。
2. Docker 环境准备
在开始部署 MySQL 之前,请确保您的系统已安装 Docker。您可以访问 Docker 官方网站(https://www.docker.com/get-started)下载并安装适用于您操作系统的 Docker Desktop(Windows/macOS)或 Docker Engine(Linux)。
安装完成后,打开终端或命令行工具,运行以下命令验证 Docker 是否正确安装:
bash
docker --version
docker compose version # 如果您计划使用 docker-compose
3. 入门篇:快速启动一个 MySQL 容器
最简单的 MySQL Docker 部署方式是直接运行一个官方镜像。
3.1 拉取 MySQL 镜像
首先,从 Docker Hub 拉取 MySQL 官方镜像。您可以指定版本,例如 mysql:8.0 或 mysql:5.7。如果不指定标签,默认会拉取 latest 版本。
bash
docker pull mysql:8.0
3.2 运行 MySQL 容器
使用 docker run 命令启动 MySQL 容器。这里有几个关键参数需要理解:
-d:后台运行容器。--name <container_name>:为容器指定一个名称,方便管理(例如my-mysql)。-p <host_port>:<container_port>:端口映射。将宿主机的<host_port>映射到容器内部的 MySQL 默认端口3306。这样您就可以通过localhost:<host_port>访问容器内的 MySQL 服务。-e MYSQL_ROOT_PASSWORD=<your_root_password>:设置 MySQLroot用户的密码。这是必须的!-e MYSQL_DATABASE=<your_database_name>(可选):在容器启动时创建一个指定的数据库。-v <host_path>:<container_path>:卷(Volume)挂载。将宿主机的<host_path>目录挂载到容器内部的 MySQL 数据目录<container_path>。这是非常重要的,用于持久化数据,防止容器删除后数据丢失。 对于 MySQL 8.0,数据目录通常是/var/lib/mysql。
“`bash
示例:启动一个名为 my-mysql 的容器,root密码为 ‘your_strong_password’
端口映射 3307:3306,数据持久化到宿主机的 ./mysql_data 目录
mkdir -p ./mysql_data # 先创建宿主机数据目录
docker run -d \
–name my-mysql \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=your_strong_password \
-v ./mysql_data:/var/lib/mysql \
mysql:8.0
“`
重要提示:
- 请将
your_strong_password替换为安全性高的实际密码。 ./mysql_data是一个相对路径,表示在当前目录下创建一个mysql_data文件夹来存储数据。在生产环境中,建议使用绝对路径。- 首次启动可能需要一些时间来初始化数据库。
3.3 验证 MySQL 容器状态
bash
docker ps
您应该能看到 my-mysql 容器正在运行,并且端口映射和名称都正确。
3.4 连接到 MySQL 容器
现在,您可以使用任何 MySQL 客户端工具(如 MySQL Workbench, DataGrip, Navicat, 或命令行 mysql 客户端)连接到您的 Docker 化 MySQL 实例:
- 主机/IP:
127.0.0.1或localhost - 端口:
3307(或您在-p参数中设置的宿主机端口) - 用户:
root - 密码:
your_strong_password
如果您宿主机上安装了 mysql-client,可以通过以下命令连接:
bash
mysql -h 127.0.0.1 -P 3307 -u root -p
然后输入您设置的密码。
4. 实践篇:使用 Docker Compose 管理 MySQL
对于更复杂的应用场景,例如同时部署多个服务(应用服务器、缓存、数据库等),docker-compose 是一个更优雅、更强大的解决方案。它允许您用一个 YAML 文件定义和管理多个 Docker 容器。
4.1 创建 docker-compose.yml 文件
在您的项目根目录创建一个名为 docker-compose.yml 的文件:
“`yaml
version: ‘3.8’ # Docker Compose 文件版本
services:
db: # 服务名称,可以自定义
image: mysql:8.0 # 使用的 MySQL 镜像
container_name: my-mysql-compose # 容器名称
restart: always # 容器异常退出时总是重启
environment: # 环境变量配置
MYSQL_ROOT_PASSWORD: your_strong_password_compose # root 用户密码
MYSQL_DATABASE: my_application_db # 自动创建的数据库
MYSQL_USER: app_user # 应用用户
MYSQL_PASSWORD: app_password # 应用用户密码
ports: # 端口映射
– “3306:3306” # 宿主机端口:容器端口,这里直接映射到默认端口
volumes: # 数据卷挂载
– ./mysql_data_compose:/var/lib/mysql # 宿主机持久化数据目录
– ./mysql_config:/etc/mysql/conf.d:ro # 挂载自定义配置文件 (可选)
command: –default-authentication-plugin=mysql_native_password # MySQL 8.0 可能需要的认证插件设置
healthcheck: # 健康检查 (可选,但推荐)
test: [“CMD”, “mysqladmin”, “ping”, “-h”, “localhost”, “-u”, “root”, “-pyour_strong_password_compose”]
interval: 10s
timeout: 5s
retries: 5
“`
docker-compose.yml 关键参数说明:
version: 指定 Docker Compose 文件的版本。3.x是当前主流。services: 定义应用中的各个服务(容器)。db: 这是一个服务名称,可以任意命名,通常代表数据库服务。image: 指定要使用的 Docker 镜像。container_name: 为这个服务创建的容器指定一个固定的名称。restart: always: 确保容器在停止或 Docker 守护进程重启后自动重启,增强服务的健壮性。environment: 定义容器内的环境变量。这是配置 MySQL 的关键:MYSQL_ROOT_PASSWORD:root用户密码。MYSQL_DATABASE:启动时自动创建的数据库名称。MYSQL_USER,MYSQL_PASSWORD:启动时自动创建的用户及其密码,并授予对MYSQL_DATABASE的完全权限。
ports: 端口映射,格式为宿主机端口:容器端口。volumes: 数据卷挂载。./mysql_data_compose:/var/lib/mysql:将宿主机当前目录下的mysql_data_compose文件夹挂载到容器的/var/lib/mysql路径,用于持久化数据库数据。./mysql_config:/etc/mysql/conf.d:ro:(可选但推荐) 挂载一个自定义的 MySQL 配置文件目录。ro表示只读。您可以在mysql_config文件夹中放置my.cnf或其他.cnf文件来定制 MySQL 配置。
command: 覆盖镜像默认的启动命令。--default-authentication-plugin=mysql_native_password在 MySQL 8.0 中有时是必要的,因为其默认认证插件caching_sha2_password可能不被一些旧版客户端或 ORM 框架支持。healthcheck: 定义容器的健康检查。Docker 会定期执行test命令,如果命令失败,容器将被标记为不健康,有助于监控服务状态。
4.2 启动和管理服务
在 docker-compose.yml 文件所在的目录中,运行以下命令:
“`bash
首次启动,会拉取镜像并创建容器
docker compose up -d
或使用老版本命令
docker-compose up -d
“`
up:构建、创建并启动服务。-d:后台运行。
查看服务状态:
bash
docker compose ps
停止服务:
bash
docker compose stop
停止并删除容器、网络、卷(但不删除匿名卷或您手动挂载的卷):
bash
docker compose down
5. 高级实践与注意事项
5.1 数据持久化策略
数据持久化是 Docker 部署数据库的重中之重。上文使用了绑定挂载 (Bind Mounts),将宿主机目录直接挂载到容器内。这是最常见且易于理解的方式。
另一种更推荐的方式是使用 Docker 卷 (Docker Volumes)。Docker 卷由 Docker 管理,通常位于 /var/lib/docker/volumes/ 下,具有更好的性能和管理特性。
使用 Docker 卷的 docker-compose.yml 示例:
“`yaml
version: ‘3.8’
services:
db:
image: mysql:8.0
container_name: my-mysql-volume
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_strong_password_volume
MYSQL_DATABASE: my_volume_db
ports:
– “3306:3306”
volumes:
– mysql_data_volume:/var/lib/mysql # 这里引用下方定义的命名卷
healthcheck:
test: [“CMD”, “mysqladmin”, “ping”, “-h”, “localhost”, “-u”, “root”, “-pyour_strong_password_volume”]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql_data_volume: # 定义一个名为 mysql_data_volume 的 Docker 卷
“`
使用命名卷的好处是,即使您删除了 docker-compose 栈,只要不执行 docker volume rm mysql_data_volume,数据仍然会保留。
5.2 自定义 MySQL 配置
您可能需要调整 MySQL 的配置,例如字符集、缓冲区大小等。可以通过挂载自定义配置文件来实现。
-
创建配置文件目录和文件:
bash
mkdir ./mysql_config
# 在 ./mysql_config/my_custom.cnf 中添加您的配置
echo "[mysqld]" > ./mysql_config/my_custom.cnf
echo "character-set-server=utf8mb4" >> ./mysql_config/my_custom.cnf
echo "collation-server=utf8mb4_unicode_ci" >> ./mysql_config/my_custom.cnf
echo "max_connections=500" >> ./mysql_config/my_custom.cnf
MySQL 容器会自动加载/etc/mysql/conf.d/目录下的.cnf文件。 -
修改
docker-compose.yml挂载此目录:
“`yaml
# … (services.db 部分)
volumes:- ./mysql_data_compose:/var/lib/mysql
- ./mysql_config:/etc/mysql/conf.d:ro # 挂载为只读
…
``docker compose restart db`
重启服务使配置生效:
5.3 数据库备份与恢复
虽然数据已经持久化,但定期备份仍然是最佳实践。
-
备份: 进入 MySQL 容器执行
mysqldump命令,然后将备份文件复制到宿主机。
bash
docker exec -it my-mysql-compose mysqldump -u root -pmy_strong_password_compose my_application_db > backup.sql
这会将备份输出到宿主机的文件中。 -
恢复:
bash
docker exec -i my-mysql-compose mysql -u root -pmy_strong_password_compose my_application_db < backup.sql
5.4 安全性考虑
- 强密码: 始终使用复杂的、不重复的密码。
- 限制访问: 除非必要,不要将 MySQL 端口直接暴露到公网。如果应用和数据库都在 Docker 内部的同一网络中,它们可以直接通过服务名称互相通信,无需端口映射到宿主机。
- 非 root 用户: 在
docker-compose.yml中创建MYSQL_USER和MYSQL_PASSWORD是一个好习惯,应用程序应该使用这些权限受限的用户,而不是root。 - 最新镜像: 定期更新 Docker 镜像以获取安全补丁:
docker pull mysql:8.0然后重建容器。
5.5 连接其他 Docker 容器中的应用
如果您的应用程序也运行在 Docker 容器中,并且与 MySQL 容器在同一个 docker-compose.yml 文件中定义,那么它们会自动在 Docker 的内部网络中互相发现。
例如,一个 Node.js 应用连接到 db 服务:
javascript
// Node.js 代码
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'db', // 这里的 'db' 是 docker-compose.yml 中定义的 MySQL 服务名称
user: 'app_user',
password: 'app_password',
database: 'my_application_db'
});
// ...
6. 总结
通过本文的介绍,您应该已经掌握了 MySQL Docker 部署从入门到实践的各种方法和技巧。从简单的 docker run 命令到功能强大的 docker-compose,再到数据持久化、自定义配置和安全性等高级考量,Docker 为 MySQL 带来了前所未有的部署灵活性和便利性。在未来的项目中,积极拥抱容器化,将为您的开发和运维工作带来显著的效率提升。