mysql官方镜像的Dockerfile中,有这么一条设置,即用了VOLUME这个关键字,同时后面设置了一个路径,/var/lib/mysql,这个路径是用来存储数据库的各种表的数据的。

这一条设置会起到什么作用呢??

docker官方文档对VOLUME这个关键词做了解释,这个路径下的数据或者修改,再重新commit一个新的镜像时,该路径下的所有变化都会被discard,即所有的修改都会被抛弃,不会被保存到新镜像中。(详见官方文档)

那我们如果想把一些基础数据在docker run的时候,不用重新导入基础数据就能直接使用呢??(docker run很快,但是导入数据需要时间,两个表大概需要二十分钟,太影响效率!)

有两种方法:

1、在主机上创建不同的目录(每个人建一个自己的目录,拷贝一份基础数据,这样互不影响,各写各的),在docker run的时候使用-v参数将宿主机上的目录映射到容器里的/var/lib/mysql。

2、既然/var/lib/mysql这个目录被VOLUME关键词给限制了,我们就先把数据拷贝到容器里的其他目录,比如根目录,然后修改docker run的启动文件(姑且称为启动文件,各种软件的docker镜像都会有一个启动脚本,在docker run的时候执行,做一些初始配置、拉起服务的进程),增加这样一个逻辑: 将我们拷贝到镜像根目录中的基础数据拷贝或者移动到/var/lib/mysql目录下,比如cp -r /mysql-basic-data /var/lib/mysql,这样,我们的目的就达到了。

我们采用的第二种解决方法。

问题:

1、如何从宿主机拷贝数据到容器中?

有个命令叫docker cp  xxx  容器id:xxx

当然也能从容器中拷贝到宿主机上:

docker cp 容器id:xxx  xxx

还有一种场景会用到——很多容器里不能使用vi或者vim编辑文件的,那么你可以先拷贝到宿主机上,编辑修改保存,再拷贝回去。

2、区分Dockerfile和docker run的启动脚本

Dockerfile是在docker build的时候执行命的,而启动脚本是在docker run的时候执行的,注意区分其执行场景和时机!!

3、mysql 5.6版本官方镜像大小300+M,我们的数据大概300M,但是新的镜像竟然达到了900+M大小,为什么??

具体要看docker存储原理!!

docker使用的是联合文件系统(AUFS,网上介绍很多),这个文件系统会把你的修改重新从底层拷贝一份到上层,即使你只有一份数据,AUFS也会把它搞成两份数据。

同事说了一件事情,即使你在容器里执行一条chown命令,镜像的大小增加200M都是可能的!!

4、docker进程自动重启,导致所有容器挂掉

这时使用docker ps是查不出来了,需要使用docker ps -a,然后一个一个的docker start xxx 起来。

解决办法: docker run的时候加个参数——autorestart,docker daemon重启,容器也会自动拉起。

另外docker ps -l,是查看哪些容器有修改!!