用官方的mysql 镜像需要修改一些内容,比如配置文件的修改,DB数据文件的目录等,更改之后如果重新运行容器,改过的文件就无效了,新生成的容器不会有之前改变的内容
第一种是修改官方下载的镜像,修改之后 提交一个新的镜像文件 docker commit -m 等新生成的镜像信息,
第二种MYSQL的DB数据,容器关闭后 如果用 docker restart 重启同一容器,那么数据是正常的,如果重新docker run 容器那么数据就不会显示,因为每个容器都有一个文件地址
这就需要把数据文件挂载出来,供其它容器读取,
在docker中启动mysql容器,在mysql容器中对数据库的更改(如创建数据库,更改数据等),在commit后再次进入容器发现之前的更改全部没有保存
1.后台运行mysql容器,设置容器名称为mysql:
[root@localhost ~]# docker run --name=mysql -p 3306:3306 -d owenchen1992/mysql
f80791a0daf194fdba94f16a9d89ebec8ba8fbd8af28d3ea8b599b9d705f85ba
2.进入容器bash和mysql,创建一个数据库TEST_DB,并验证TEST_DB创建成功:
[root@localhost ~]# docker exec -it mysql bash root@f80791a0daf1:/# mysql -uroot -p
show databases;
create database TEST_DB;
3.退出容器,并commit更改到镜像: 这个数据其实是在宿主机上修改,不是mysql镜像的东西。所以不生效
mysql> exit
Bye
root@f80791a0daf1:/# exit
exit
[root@localhost ~]# docker commit mysql owenchen1992/mysql
4.重新启动容器并进入bash和mysql,发现之前创建的TEST_DB不见了,说明之前的更改无效:
[root@localhost ~]# docker container stop mysql
mysql
[root@localhost ~]# docker container rm mysql
mysql
[root@localhost ~]# docker run --name=mysql -p 3306:3306 -d owenchen1992/mysql
a1a1b4174caaadda0ec4b01b9fe5f92d6b3464d85284042274f71aebde0915dd
[root@localhost ~]# docker exec -it mysql bash
root@a1a1b4174caa:/# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.20 MySQL Community Server (GPL)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
问题原因:
在mysql的Dockerfile中有这样一行:
VOLUME /var/lib/mysql
这意味在容器中的目录/var/lib/mysql的所有修改会对应到宿主机的某个位置,可以通过命令查看具体对应的宿主机目录:docker inspect containerID/name. 当运行docker commit时,容器中的/var/lib/mysql目录的更改并不会提交到镜像中,但这些更改是随时与宿主机对应的目录同步的。当重新启动commit后的镜像时,container会重新在宿主机中创建一个目录来保存其数据更新,因此并不是原先的宿主机目录,所以新开启的容器看不到之前的数据更改。
解决方法:
我们已经知道了问题发生的原因,就不难解决这个问题了,步骤如下:
可以直接去这个目录下查看为每个容器生成的数据目录
1.找到mysql容器对应的宿主机目录"/var/lib/docker/volumes/8496bbf33782bdadc027cdcf23197e5ebc36d11deb69ee833d63b557b3a7183d/_data":
[root@localhost ~]# docker inspect mysql
[
......
"Source": "/var/lib/docker/volumes/8496bbf33782bdadc027cdcf23197e5ebc36d11deb69ee833d63b557b3a7183d/_data",
"Destination": "/var/lib/mysql",
......
]
把之前的创建容器运行的步骤再执行一步,运行新的容器,然后建一张TEST表,先关闭容器后删除容器服务
4.后台运行容器新的容器,并将宿主机对应的目录挂载到容器的/var/lib/mysql目录下并开启读写权限(关键步骤):
[root@localhost ~]# docker run --name=mysql -p 3306:3306 -v /var/lib/docker/volumes/8496bbf33782bdadc027cdcf23197e5ebc36d11deb69ee833d63b557b3a7183d/_data:/var/lib/mysql:rw -d owenchen1992/mysql
5.此时进入新开启的容器,并查看数据库:发现刚才创建的数据库TEST_DB没有因为重新运行容器而消失,问题解决
步骤是,1 新建一张表,2 关掉建表的容器,3重新运行容器,并且挂载数据目录到/var/lib/mysql下,问题就解决了