尽管Docker的Interactive tutorial和faq我在容器退出时丢失了数据。
我按照此处的说明安装了Docker:http://docs.docker.io/en/latest/installation/ubuntulinux 在ubuntu 13.04上没有任何问题。
但退出时会丢失所有数据。
iman@test:~$ sudo docker version
Client version: 0.6.4
Go version (client): go1.1.2
Git commit (client): 2f74b1c
Server version: 0.6.4
Git commit (server): 2f74b1c
Go version (server): go1.1.2
Last stable version: 0.6.4
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
iputils-ping
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 56.1 kB of archives.
After this operation, 143 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 56.1 kB in 0s (195 kB/s)
Selecting previously unselected package iputils-ping.
(Reading database ... 7545 files and directories currently installed.)
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ...
Setting up iputils-ping (3:20101006-1ubuntu1) ...
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory
我还使用具有相同结果的交互式会话对其进行了测试。我忘了什么吗?
正如@ mohammed-noureldin和其他人所说,实际上这是不 容器退出。每次它只是创建一个新容器。
答案 0 :(得分:362)
您需要commit对容器所做的更改然后运行它。试试这个:
sudo docker pull ubuntu
sudo docker run ubuntu apt-get install -y ping
然后使用以下命令获取容器ID:
sudo docker ps -l
提交对容器的更改:
sudo docker commit <container_id> iman/ping
然后运行容器:
sudo docker run iman/ping ping www.google.com
这应该有用。
答案 1 :(得分:331)
当您使用docker run
启动容器时,它实际上会根据您指定的图像创建一个新容器。
除了此处的其他有用答案外,请注意您可以在退出后重新启动现有容器并且您的更改仍然存在。
docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin
答案 2 :(得分:106)
有以下方法可以保存容器数据:
Docker卷
Docker提交
a)从ubuntu映像创建容器并运行bash终端。
$ docker run -i -t ubuntu:14.04 /bin/bash
b)终端内部安装curl
# apt-get update
# apt-get install curl
c)退出集装箱码头
# exit
d)执行以下命令记下您的容器ID:
$ docker ps -a
e)将容器保存为新图像
$ docker commit <container_id> new_image_name:tag_name(optional)
f)确认您可以在安装了curl的情况下看到新图像。
$ docker images
$ docker run -it new_image_name:tag_name bash
# which curl
/usr/bin/curl
答案 3 :(得分:55)
除Unferth's answer外,建议您创建Dockerfile。
在空目录中,使用以下内容创建名为“Dockerfile”的文件。
FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]
使用Dockerfile 创建图像。让我们使用标签,这样我们就不需要记住十六进制图像编号了。
$ docker build -t iman/ping .
然后在容器中运行图像。
$ docker run iman/ping stackoverflow.com
答案 4 :(得分:9)
如果要在容器中保留数据,可能需要查看docker卷。访问https://docs.docker.com/engine/tutorials/dockervolumes/。 docker文档是一个非常好的起点
答案 5 :(得分:5)
我对您的问题有一个简单得多的答案,请运行以下两个命令
sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a
上面的ps -a命令返回所有容器的列表。引用引用图像名称的容器名称-'ubuntu'。 docker auto为容器生成名称,例如-'lightlyxuyzx'
,这就是如果您不使用--name选项的话。
-t和-d选项很重要,创建的容器已分离,可以使用-t选项重新附加,如下所示。
使用--name选项,您可以在我的情况下将容器命名为“ mycontainername”。
sudo docker exec -ti mycontainername bash
,以上命令可帮助您使用bash shell登录到容器。从这一点开始,您在容器中所做的任何更改都会被docker自动保存。
例如-apt-get install curl
在容器内
您可以毫无问题地退出容器,docker自动保存更改。
在接下来的用法中,您要做的就是,每次要使用此容器时都运行这两个命令。
以下命令将启动已停止的容器:
sudo docker start mycontainername
sudo docker exec -ti mycontainername bash
下面提供端口和共享空间的另一个示例:
docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash
就我而言: 7efe2989e877-是先前容器运行的imageid 我使用
获得的docker ps -a
答案 6 :(得分:2)
我的建议是使用docker compose来管理docker。管理项目的所有docker容器是一种简单的方法,您可以映射版本并链接不同的容器以协同工作。
文档很容易理解,比docker的文档更好。
最佳
答案 7 :(得分:0)
类似的问题(单靠Dockerfile无法修复它)将我带到了这个页面。
第0阶段: 对于所有人,希望Dockerfile可以修复它:直到--dns和--dns-search将出现在Dockerfile支持中 - 没有办法将基于Intranet的资源集成到。
第1阶段:
在使用Dockerfile构建映像之后(顺便说一句,这是一个严重的故障,Dockerfile必须位于当前文件夹中),通过运行docker run脚本来部署基于Intranet的映像。例:
docker run -d \
--dns=${DNSLOCAL} \
--dns=${DNSGLOBAL} \
--dns-search=intranet \
-t pack/bsp \
--name packbsp-cont \
bash -c " \
wget -r --no-parent http://intranet/intranet-content.tar.gz \
tar -xvf intranet-content.tar.gz \
sudo -u ${USERNAME} bash --norc"
第2阶段: 在守护程序模式下应用docker run脚本,提供本地dns记录,以便能够下载和部署本地内容。
重点:运行脚本应以/usr/bin/sudo -u ${USERNAME} bash --norc
之类的结尾,以便即使在安装脚本完成后也能保持容器运行。
没有,无法以交互模式运行容器以实现完全自动化,因为它将保留在内部应该命令提示符中,直到 CTRL-p CTRL-q 为止按下。
否,如果在安装脚本结束时不执行交互式bash,则容器将在完成脚本执行后立即终止,从而丢失所有安装结果。
第3阶段:
容器仍在后台运行,但尚不清楚容器是否已经结束安装程序。使用以下块来确定执行过程完成:
while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" -
do
echo "."
sleep 5
done
脚本将在完成安装后继续进行。这是调用的正确时刻:提交,提供当前容器ID和目标图像名称(可能与构建/运行过程相同但附加了使用本地安装目的标记。例如:docker commit containerID pack/bsp:toolchained
。
请参阅此链接,了解如何获得正确的containerID
阶段4:容器已使用本地安装进行更新,并且已将其提交到新分配的映像(添加了目的标记的映像)。现在停止集装箱运行是安全的。例如:docker stop packbsp-cont
stage5:在本地安装的容器需要运行的任何时刻,使用之前保存的映像启动它。
例如:docker run -d -t pack/bsp:toolchained
答案 8 :(得分:0)
来自用户kgs的精彩答案How to continue a docker which is exited
docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)
docker exec -it <container-id> /bin/bash
第二行至关重要。所以exec用于代替run,而不是在图像上而是在containerid上。并且在容器启动后执行此操作。
答案 9 :(得分:0)
没有任何答案解决此设计选择的要点。我认为docker可以通过这种方式来防止这2个错误:
答案 10 :(得分:0)
上面提出的问题确实有很好的答案。可能不需要其他答案,但是我仍然想以最简单的方式对这个话题发表个人看法。
关于容器和图像的一些观点可以帮助我们得出结论:
结论:
我们可以看到,Docker容器独立于Docker映像。
只要该容器的唯一ID [使用docker ps --all
获取ID] ,就可以重新启动该容器。
在容器运行时,可以在容器内进行任何操作,例如创建新目录,创建文件,安装工具等。容器停止后,它将保留所有更改。停止和重新启动容器就像重新启动计算机系统一样。
已经创建的容器始终可用于重新启动,但是当我们发出docker run
命令时,将根据映像创建一个新容器,因此它就像一个新的计算机系统。我们现在可以理解,在旧容器内进行的更改在此新容器中不可用。
最后的提示:
我想现在很明显为什么数据似乎丢失了,但始终在那里..但是在另一个[旧]容器中。因此,请充分注意docker start
和docker run
命令的区别,不要混淆它们。