我有一个Docker容器,我只是通过在Ubuntu上安装Docker来创建并执行:
sudo docker run -i -t ubuntu /bin/bash
我立即开始安装Java和其他一些工具,花一些时间用它来停止容器
exit
然后我想添加一个卷,并意识到这并不像我想象的那么简单。如果我使用sudo docker -v /somedir run ...
,那么我最终会得到一个全新的容器,所以我已经安装了Java并执行我之前已经完成的操作,只是为了到达装有卷的容器。
有关从主机安装文件夹的所有文档似乎都暗示在创建容器时可以安装卷。因此,我必须避免从头开始重新配置新容器的唯一选择是将现有容器提交到存储库,并在安装卷时将其用作新容器的基础。
这确实是向现有容器添加卷的唯一方法吗?
答案 0 :(得分:268)
您可以提交现有容器(即从容器的更改中创建新图像),然后使用新安装程序运行它。
示例:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a8f89adeead ubuntu:14.04 "/bin/bash" About a minute ago Exited (0) About a minute ago agitated_newton
$ docker commit 5a8f89adeead newimagename
$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash
如果一切正常,请停止旧容器,然后使用这个新容器。
就是这样:))
答案 1 :(得分:56)
我们没有办法在正在运行的容器中添加音量,但要实现此目标,您可以使用以下命令:
在容器和本地文件系统之间复制文件/文件夹: -
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
供参考:
答案 2 :(得分:10)
Jérôme Petazzoni有一篇关于如何Attach a volume to a container while it is running的非常有趣的博客文章。这不是开箱即用的Docker内置的东西,但可以实现。
正如他也指出的那样
这不适用于不基于块设备的文件系统。
只有在/ proc / mounts正确列出块设备节点时才会起作用(正如我们上面所看到的那样,它不一定是真的)。
另外,我只在我的本地环境中测试了这个;我甚至没有尝试云实例或类似的东西
YMMV
答案 3 :(得分:7)
不幸的是,只能在run
命令中找到安装卷的switch选项。
docker run --help
-v, --volume list Bind mount a volume (default [])
有一种方法可以解决这个问题,因此您不必重新安装已经在容器上设置的应用程序。
docker container export -o ./myimage.docker mycontainer
docker import ./myimage.docker myimage
docker run -i -t -v /somedir --name mycontainer myimage /bin/bash
答案 4 :(得分:7)
我已成功将主机的/home/<user-name>
文件夹安装到现有(未运行)容器的/mnt
文件夹中。您可以通过以下方式进行操作:
打开与停止的容器相对应的配置文件,可以在/var/lib/docker/containers/99d...1fb/config.v2.json
中找到(对于较早版本的docker,可能为config.json
)。
找到MountPoints
部分,在我的情况下为空:"MountPoints":{}
。接下来,将内容替换为类似的内容(您可以使用适当的设置从另一个容器复制适当的内容):
"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}
或相同(格式):
"MountPoints": {
"/mnt": {
"Source": "/home/<user-name>",
"Destination": "/mnt",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/home/<user-name>",
"Target": "/mnt"
},
"SkipMountpointCreation": false
}
}
service docker restart
这对我适用于Ubuntu 18.04.1和Docker 18.09.0
答案 5 :(得分:0)
最好的方法是通过docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
SRC_PATH
在容器上
DEST_PATH
在本地主机上
然后docker-compose down
将卷附加到同一DEST_PATH
并通过使用docker-compose up -d
运行Docker容器
通过关注docker-compose.yml
volumes:
- DEST_PATH:SRC_PATH
答案 6 :(得分:0)
在长时间寻找这个问题之后,有关使用Docker Windows容器的说明!
条件:
问题:
解决方案部分描述于此:
docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer
docker exec -it <CONTAINERID> cmd.exe
mkdir DirForMount
docker container stop <CONTAINERID>
docker commit <CONTAINERID> <NEWIMAGENAME>
docker container rm <CONTAINERID>
docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>
此后,我在docker Windows容器上解决了这个问题。
答案 7 :(得分:0)
只需使用Portainer。它会重新创建容器并一键删除旧容器。