Docker运行MySQL,数据持久化配置
前言
用Docker跑MySQL,删了容器数据就没了?那是没挂数据卷。本文讲怎么用Docker跑MySQL并持久化数据。
一、基本运行
最简单的跑法
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
问题: 删了容器,数据库里的数据全没了。
二、加数据卷持久化
完整命令
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
解释
-p 3306:3306端口映射-e MYSQL_ROOT_PASSWORD=123456设置root密码-v /data/mysql:/var/lib/mysql数据卷挂载- 宿主机
/data/mysql目录 - 容器里
/var/lib/mysql目录
- 宿主机
这样容器删了,数据还在宿主机上。
三、其他常用配置
1. 设置字符集
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
2. 创建数据库和用户
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=myuser \
-e MYSQL_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
3. 挂载配置文件
先在宿主机创建my.cnf:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=1000
然后挂载:
docker run -d \
--name mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
四、Docker Compose方式
version: '3'
services:
mysql:
image: mysql:5.7
container_name: mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- /data/mysql:/var/lib/mysql
- /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
启动:
docker-compose up -d
五、连接MySQL
进入容器连接
docker exec -it mysql mysql -uroot -p123456
从宿主机连接
mysql -h127.0.0.1 -P3306 -uroot -p123456
用Navicat等工具
- 主机:服务器IP
- 端口:3306
- 用户名:root
- 密码:123456
六、备份和恢复
备份数据库
docker exec mysql mysqldump -uroot -p123456 mydb > /data/backup/mydb.sql
恢复数据库
docker exec -i mysql mysql -uroot -p123456 mydb < /data/backup/mydb.sql
七、常见坑
坑1:密码不对
报错:
Access denied for user 'root'@'localhost'
检查: 环境变量 MYSQL_ROOT_PASSWORD 设了没?
坑2:权限问题
宿主机 /data/mysql 目录权限不对:
chmod -R 777 /data/mysql
坑3:端口被占用
3306端口被宿主机的MySQL占了:
Bind for 0.0.0.0:3306 failed: port is already allocated
解决: 换个端口:
-p 3307:3306
坑4:数据没持久化
没加 -v 挂载,删了容器数据就没了。
检查: 有没有 -v /data/mysql:/var/lib/mysql?
坑5:第一次启动慢
MySQL第一次启动要初始化数据,要等个十几秒。
等不及就先别连,过一会再试。
坑6:字符集不对,中文乱码
加参数:
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
八、推荐配置
docker run -d \
--name mysql \
--restart=always \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=你的密码 \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
mysql:5.7
--restart=always开机自动启动- 数据挂载到
/data/mysql - 配置文件挂载
总结
记住:
- 一定要挂数据卷,不然删容器数据就没了
- 用
-e MYSQL_ROOT_PASSWORD设密码 - 用
-p 3306:3306映射端口 - 配置文件也可以挂载进去
最常用:
docker run -d --name mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
遇到问题加QQ23979811 协助处理
Docker数据卷挂载,容器数据持久化
前言
删了Docker容器,数据全没了?那是因为你没挂数据卷。本文讲怎么用数据卷让容器数据持久化。
一、为什么需要数据卷
容器里的数据,容器删了就没了。
docker run -d --name mysql mysql:5.7
# 删了容器,数据就没了
docker rm -f mysql
解决: 把数据存到宿主机,容器删了数据还在。
二、三种数据持久化方式
1. 绑定挂载(bind mount)
把宿主机的目录直接挂到容器里。
docker run -v /宿主机路径:/容器路径 镜像名
例子:
docker run -d \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
特点: 简单直接,数据在你自己的目录里。
2. 命名卷(named volume)
Docker管理的数据卷。
docker volume create mydata
docker run -v mydata:/var/lib/mysql mysql:5.7
特点: Docker帮你管理位置,不用你关心存在哪。
3. 临时挂载(tmpfs)
存在内存里,重启就没。
docker run --tmpfs /tmp 镜像名
特点: 临时用,存敏感数据。
三、常用场景
场景1:MySQL数据持久化
docker run -d \
--name mysql \
-v /data/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
场景2:Nginx挂载网站文件
docker run -d \
--name nginx \
-v /data/www:/usr/share/nginx/html \
-p 80:80 \
nginx
场景3:挂载配置文件
docker run -d \
-v /data/nginx/nginx.conf:/etc/nginx/nginx.conf \
nginx
场景4:挂载日志
docker run -d \
-v /data/logs/nginx:/var/log/nginx \
nginx
四、Docker Compose里的挂载
services:
mysql:
image: mysql:5.7
volumes:
- /data/mysql:/var/lib/mysql
# 或者用命名卷
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
五、常用命令
查看所有数据卷
docker volume ls
查看数据卷详情
docker volume inspect 数据卷名
删除没用的数据卷
docker volume prune
查看容器挂载
docker inspect -f '{{.Mounts}}' 容器名
六、只读挂载
只想让容器读,不让写:
docker run -v /data/www:/usr/share/nginx/html:ro nginx
后面加个 :ro 就是只读。
七、常见坑
坑1:改了配置文件不生效
挂了配置文件,改了宿主机的文件,重启容器还是旧的。
原因: 容器没真正重启。
解决:
docker restart 容器名
坑2:权限问题
挂载的目录,容器里的用户读不了。
原因: 宿主机目录权限不对。
解决:
chmod -R 777 /data/mysql
坑3:Windows/Mac路径问题
Windows路径写法不一样:
docker run -v D:\data:/var/lib/mysql mysql
Mac/Linux用:
docker run -v /Users/xxx/data:/var/lib/mysql mysql
坑4:挂载文件不存在
宿主机的文件不存在,Docker会自动建一个目录。
比如:
docker run -v /data/nginx.conf:/etc/nginx/nginx.conf nginx
如果 /data/nginx.conf 不存在,Docker会建一个叫 nginx.conf 的目录,容器里就挂错了。
解决: 先创建文件:
touch /data/nginx.conf
坑5:数据卷删了数据就没了
docker volume rm mydata
数据卷删了,里面的数据也没了。
解决: 重要数据定期备份。
八、最佳实践
- 数据库一定要挂载数据卷,不然容器删了数据就没了
- 配置文件挂载到宿主机,改起来方便
- 日志挂载到宿主机,方便查看和切割
- 网站文件挂载到宿主机,更新代码不用重新打镜像
总结
记住:
-v 宿主机路径:容器路径就是挂载- 数据库一定要挂数据卷
- 删容器不删数据,因为数据在宿主机
- 挂载文件不存在会变成目录,要注意
最常用:
docker run -v /data/mysql:/var/lib/mysql mysql
遇到问题加QQ23979811 协助处理