很多后端开发者第一次接触 Docker,最常部署的服务之一就是 MySQL。
以前安装 MySQL:
text
下载 MySQL
↓
安装依赖
↓
修改配置
↓
初始化数据库
↓
创建用户
↓
配置权限
↓
启动服务
换一台服务器,又重新来一遍。
Docker 之后:
bash
docker run mysql
几秒钟启动一个完整 MySQL 环境。
MySQL 官方也提供了维护的 Docker 镜像,可以直接通过 Docker Hub 获取。(Docker Hub)
但是生产环境真正使用 Docker 部署 MySQL,并不是只会:
bash
docker run mysql
还需要考虑:
- 数据持久化
- 用户权限
- 配置文件
- 字符集
- 数据备份
- 容器升级
- Docker Compose 管理
这篇文章从开发环境到生产实践,完整讲清楚 Docker 部署 MySQL。
一、为什么推荐用 Docker 部署 MySQL?
传统安装:
text
服务器
↓
Linux
↓
安装 MySQL
↓
修改配置
↓
启动服务
问题:
1. 环境不一致
开发:
text
MySQL 8.0
测试:
text
MySQL 5.7
生产:
text
MySQL 8.4
容易出现:
text
开发正常
线上报错
2. 多版本切换麻烦
比如:
项目 A:
text
MySQL 5.7
项目 B:
text
MySQL 8.0
传统安装:
需要不停卸载。
Docker:
直接:
bash
docker run mysql:5.7
docker run mysql:8.0
两个环境同时存在。
3. 新机器部署速度慢
Docker:
bash
docker compose up -d
几分钟恢复环境。
二、安装 Docker
Ubuntu 安装 Docker
更新:
bash
sudo apt update
安装:
bash
sudo apt install docker.io
启动:
bash
sudo systemctl start docker
设置开机启动:
bash
sudo systemctl enable docker
查看版本:
bash
docker version
输出:
text
Docker version 27.x
三、拉取 MySQL Docker 镜像
MySQL 官方镜像:
bash
docker pull mysql:8.0
查看:
bash
docker images
结果:
text
REPOSITORY TAG
mysql 8.0
建议生产环境不要使用:
bash
mysql:latest
因为:
未来版本变化可能导致兼容问题。
推荐:
bash
mysql:8.0
或者:
bash
mysql:8.4
固定版本。
四、最简单启动 MySQL
执行:
bash
docker run \
-d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
解释:
-d
后台运行:
text
detached
--name
容器名字:
bash
mysql8
以后:
bash
docker stop mysql8
-p
端口映射:
bash
-p 3306:3306
表示:
text
宿主机3306
↓
容器3306
MYSQL_ROOT_PASSWORD
初始化 root 密码:
bash
-e MYSQL_ROOT_PASSWORD=123456
查看:
bash
docker ps
看到:
text
mysql8
0.0.0.0:3306->3306
说明启动成功。
五、进入 MySQL 容器
查看:
bash
docker exec -it mysql8 bash
进入:
text
root@container
登录:
bash
mysql -uroot -p
输入密码:
text
123456
进入:
sql
mysql>
查看数据库:
sql
show databases;
创建数据库:
sql
CREATE DATABASE demo;
查看:
sql
show databases;
六、为什么直接 docker run MySQL 不够?
刚才启动:
bash
docker run mysql
有一个严重问题:
数据在哪里?
如果:
bash
docker rm mysql8
删除容器。
数据可能一起消失。
数据库最重要的是:
text
数据
所以必须使用 Volume。
七、MySQL 数据持久化 Volume
创建目录:
bash
mkdir -p /data/mysql
启动:
bash
docker run \
-d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:8.0
关键:
bash
-v
宿主机目录
:
容器目录
这里:
text
/data/mysql
↓
/var/lib/mysql
MySQL 数据文件:
text
ibdata1
binlog
数据库文件
都会保存。
现在删除容器:
bash
docker rm -f mysql8
重新启动:
bash
docker run \
-d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:8.0
数据仍然存在。
八、使用 Docker Compose 部署 MySQL(推荐)
实际项目中,我更推荐:
text
docker-compose.yml
因为配置可以保存到 Git。
创建:
bash
mkdir mysql-docker
cd mysql-docker
创建:
bash
vim docker-compose.yml
内容:
yaml
version: "3.8"
services:
mysql:
image: mysql:8.0
container_name: mysql8
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: demo
MYSQL_USER: app
MYSQL_PASSWORD: app123
ports:
- "3306:3306"
volumes:
- ./mysql-data:/var/lib/mysql
- ./conf:/etc/mysql/conf.d
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
启动:
bash
docker compose up -d
查看:
bash
docker compose ps
九、Docker Compose 配置详解
image
yaml
image:mysql:8.0
使用 MySQL 官方镜像。
restart
yaml
restart: always
服务器重启:
自动恢复。
生产环境非常重要。
environment
初始化:
yaml
MYSQL_DATABASE: demo
自动创建:
sql
demo
创建普通用户:
yaml
MYSQL_USER: app
MYSQL_PASSWORD: app123
避免业务直接使用 root。
十、MySQL 字符集配置
很多项目遇到:
中文乱码:
text
???
原因:
默认字符集:
text
latin1
推荐:
text
utf8mb4
配置:
yaml
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
进入 MySQL:
sql
show variables like 'character%';
查看:
text
utf8mb4
十一、连接 MySQL
本机连接
bash
mysql \
-h127.0.0.1 \
-P3306 \
-uroot \
-p
Navicat / DataGrip
配置:
text
Host:
127.0.0.1
Port:
3306
User:
root
Password:
123456
十二、后端项目连接 Docker MySQL
例如 SpringBoot:
错误:
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo
为什么?
因为:
localhost 指向当前容器。
如果后端也是 Docker:
应该:
yaml
spring:
datasource:
url: jdbc:mysql://mysql:3306/demo
因为:
Compose 会自动提供 DNS:
text
mysql
↓
MySQL容器
Go 项目:
go
dsn := "root:123456@tcp(mysql:3306)/demo"
十三、查看 MySQL 日志
启动失败:
第一步:
bash
docker logs mysql8
实时:
bash
docker logs -f mysql8
常见:
密码错误
text
MYSQL_ROOT_PASSWORD missing
解决:
重新创建:
bash
-e MYSQL_ROOT_PASSWORD=password
端口占用
错误:
text
Bind for 0.0.0.0:3306 failed
查看:
bash
netstat -tunlp | grep 3306
修改:
yaml
ports:
- "3307:3306"
十四、备份 MySQL 数据
生产环境最重要:
备份。
导出:
bash
docker exec mysql8 \
mysqldump \
-u root \
-p demo \
> demo.sql
恢复:
bash
docker exec -i mysql8 \
mysql \
-u root \
-p demo \
< demo.sql
十五、升级 MySQL 版本
例如:
MySQL 8.0
升级:
MySQL 8.4
流程:
1. 备份
bash
mysqldump
2. 停止
bash
docker compose down
3. 修改版本
之前:
yaml
image:mysql:8.0
改:
yaml
image:mysql:8.4
4. 启动
bash
docker compose up -d
十六、国内 Docker Hub 镜像访问问题
很多国内开发者遇到:
bash
docker pull mysql:8.0
速度慢。
甚至:
text
timeout
connection reset
原因:
默认:
text
Docker Hub
↓
海外节点
↓
国内网络
访问不稳定。
针对 Docker Hub 镜像访问问题,我维护了:
https://github.com/Rodert/dockerhub
核心思路:
text
Docker Hub
↓
国内镜像源
↓
开发者
配置:
编辑:
bash
vim /etc/docker/daemon.json
添加:
json
{
"registry-mirrors":[
"你的镜像地址"
]
}
重启:
bash
systemctl restart docker
查看:
bash
docker info
确认:
text
Registry Mirrors
十七、王仕宇对 Docker + MySQL 的理解
我一直认为:
Docker 最大价值不是让安装 MySQL 变简单,而是让数据库环境变得可复制。
以前:
一个新人加入项目:
text
安装 MySQL
配置账号
导入 SQL
修改配置
踩坑
可能半天。
现在:
项目提供:
text
docker-compose.yml
新人:
bash
docker compose up -d
几分钟启动完整环境。
但是数据库和普通应用不同。
MySQL 最大的问题不是启动。
而是:
text
数据安全
配置管理
备份恢复
版本升级
权限控制
所以真正生产级 Docker MySQL:
不是:
bash
docker run mysql
而是:
text
固定版本
+
Volume
+
备份
+
配置文件
+
权限隔离
+
监控
十八、总结
Docker 部署 MySQL 核心流程:
text
安装 Docker
↓
拉取 MySQL 镜像
↓
创建容器
↓
配置端口
↓
配置 Volume
↓
创建用户
↓
连接数据库
↓
备份数据
开发环境:
bash
docker compose up -d
生产环境:
需要额外考虑:
text
数据持久化
安全
备份
监控
升级
Docker 不是简单替代 MySQL 安装方式。
它真正改变的是:
数据库环境从"人工配置"变成"代码化管理"。
这也是未来 AI Coding 时代非常重要的一环:
AI 可以帮你生成业务代码,但最终项目能不能稳定运行,依然离不开 Docker、数据库和部署工程能力。