何时需要使用Docker Volume?
在前面的例子中,如果我们在MongoDB中创建了数据,那么每次重新启动容器的时候,先前数据都会丢失。在需要保持数据的时候,就需要使用Docker Volume。
Docker Volume介绍
Docker Volume的工作原理就是把host的一个目录挂载到容器中的虚拟目录中,这样即使容器重新启动或者被删除了,数据还在,进而实现了容器内数据的持久化。
比如,在运行docker run的时候:
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data mysql从本质上将,使用数据卷就是在容器内使用mount挂载主机的某个目录。数据全部保存在host的目录下,自然就不会受容器生命周期的影响了。
这里可以同时挂载多个不同的路径。
可能出现的问题及解决方法
如果出现如下错误提示:
cannot open directory .: Permission denied其原因在于,挂载容器卷的行为在有些Linux版本中被系统认为是不安全的行为,因此,系统的root权限受到限制。
解决方法很简单,添加一个–privileged=true参数就可以给root真正的管理员权限:
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data --privileged=true mysql读写权限
rw
默认情况下,容器内的目录是可以读写的,也就是说,默认的命令其实是:
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data:rw --privileged=true mysql只读
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data:ro --privileged=true mysql如果通过上面方式的话,在容器内只能读,不能写。
三种Volume类型
方式一:同时指定host目录和容器中目录
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data mysql方式二:只指定容器中目录(Anonymous Volumes)
在这种方式中,docker会自动管理host中对应的目录,它会在/var/lib/docker/volumes中创建一个临时目录(Anonymous Volumes),并挂载到容器中的虚拟目录。
docker run -v /var/lib/mysql/data mysql方式三:指定host中目录名及容器中目录(Named Volumes)
这是第二种方式的改进,这样就可以通过名字来引用volume。同时,这也是在production环境中推荐的方式。
docker run -v mysql-folder:/var/lib/mysql/data mysql容器卷的继承
可以使用volumes-from 父容器名参数来实现容器卷的继承。
比如:
docker run -it --volumes-from redis1 --name redis2 redis /bin/bash通过这种方式,就实现了多个容器间及主机的数据共享。
在docker-compose.yml中使用volume
其使用方式和docker命令行类似:
services:
mongodb:
image: mongo
ports:
- 27017:27017
volumes:
- mongo-data:/data/db
volumes:
mongo-data 通过上面这种方式,可以把host的同一个目录映射到不同容器中的不同虚拟目录,从而实现在不同容器中共享数据的目的。
常见几种数据库的数据存储路径:
- MongoDB: /data/db
- MySQL: /var/lib/mysql
- postgres: /var/lib/postgresql/data
Docker存储volume的路径:
- Windows: C:\ProgramData\docker\volumes
- Linux/Mac: /var/lib/docker/volumes (注意:在Mac中看不到这个目录,原因在于Docker for Mac会创建一个Linux VM,并把Docker对应的文件存储到这个VM中),这时可以输入以下命令进入Linux VM:~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
一个完整的例子
version: '3'
services:
lcoding-demo:
image: xxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/lcoding-demo:1.0
ports:
- 3000:3000
mongodb:
image: mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=12345
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express
ports:
- 8081:8081
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=12345
- ME_CONFIG_MONGODB_SERVER=mongodb
volumes:
mongo-data:
driver: local