尽管Docker的交互式教程和常见问题,我丢失了我的数据时,容器退出。

我已经安装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 

我还用互动会话测试了它,得到了同样的结果。我是不是忘了什么?

编辑:对docker新用户很重要

正如@ mohammad -noureldin和其他人所说,实际上这不是一个容器退出。每次它都会创建一个新容器。


当前回答

上面的问题都有很好的答案。也许不需要另一个答案,但我仍然想用最简单的语言就这个话题发表我的个人观点。

下面是一些关于容器和图像的观点,有助于我们得出结论:

A docker image can be: created-from-a-given-container deleted used-to-create-any-number-of-containers A docker container can be: created-from-an-image started stopped restarted deleted used-to-create-any-number-of-images A docker run command does this: Downloads an image or uses a cached image Creates a new container out of it Starts the container When a Dockerfile is used to create an image: It is already well known that the image will eventually be used to run a docker container. After issuing docker build command, docker behind-the-scenes creates a running container with a base-file-system and follows steps inside the Dockerfile to configure that container as per the developers need. After the container is configured with specs of the Dockerfile, it will be committed as an image. The image gets ready to rock & roll!

结论:

正如我们所看到的,docker容器独立于docker镜像。

一个容器可以重新启动,前提是该容器的唯一ID[使用docker ps——all获取ID]。

任何操作,如创建新目录,创建文件,安装工具等,都可以在容器运行时在容器中完成。一旦容器停止,它将持久化所有更改。容器停止和重新启动就像重新启动计算机系统一样。

一个已经创建的容器总是可以重新启动,但是当我们发出docker run命令时,一个新的容器就会从一个映像中创建出来,因此它就像一个新的计算机系统。正如我们现在所理解的那样,在旧容器中所做的更改在这个新容器中不可用。

最后一点:

我想现在很明显为什么数据似乎丢失了,但它总是在那里。但在一个不同的(旧的)容器里。因此,请注意docker start和docker run命令的区别,不要混淆它们。

其他回答

如果您希望将数据持久化在容器中,您可能需要查看docker卷。访问https://docs.docker.com/engine/tutorials/dockervolumes/。docker文档是一个很好的开始

您需要向容器提交所做的更改,然后运行它。试试这个:

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

这应该有用。

类似的问题(仅靠Dockerfile无法解决)将我带到了这个页面。

0阶段: 对于所有人来说,希望Dockerfile可以修复它:直到——dns和——dns-search将出现在Dockerfile支持中-没有办法将基于intranet的资源集成到。

stage 1: after building image using Dockerfile (by the way it's a serious glitch Dockerfile must be in the current folder), having an image to deploy what's intranet based, by running docker run script. example: 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运行脚本在守护进程模式提供本地DNS记录有能力下载和部署本地的东西。

重点:运行脚本应该以类似/usr/bin/sudo -u ${USERNAME} bash——norc结尾,以便在安装脚本结束后仍然保持容器运行。

不,不可能在完全自动化的交互模式下运行容器,因为它将保持在内部shall命令提示符中,直到按下CTRL-p CTRL-q。

不,如果交互bash不会在安装脚本的末尾执行,容器将在脚本执行完成后立即终止,丢失所有安装结果。

stage 3: container is still running in background but it's unclear whether container has ended installation procedure or not yet. using following block to determine execution procedure finishes: while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done the script will proceed further only after completed installation. and this is the right moment to call: commit, providing current container id as well as destination image name (it may be the same as on the build/run procedure but appended with the local installation purposes tag. example: docker commit containerID pack/bsp:toolchained. see this link on how to get proper containerID

阶段4:容器已经使用本地安装更新,并且已经提交到新分配的映像中(添加了目的标记的映像)。现在可以安全地停止容器运行了。例如:docker stop packbsp-cont

Stage5:任何带有本地安装的容器需要运行的时候,使用之前保存的映像启动它。 示例:docker run -d -t pack/bsp:toolchained

一个聪明的答案在这里如何继续从用户kgs退出的docker

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,而且不是在映像上而是在容器id上。而且是在容器启动之后。

对于你的问题,我有一个更简单的答案,运行以下两个命令

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

上面的ps -a命令返回所有容器的列表。取引用映像名称的容器名称- 'ubuntu'。Docker会自动为容器生成名称,例如- 'lightlyxuyzx',前提是你没有使用——name选项。

-t和-d选项很重要,创建的容器被分离,并可以使用-t选项重新连接,如下所示。

使用——name选项,你可以将容器命名为mycontainername。

sudo docker exec -ti mycontainername bash

上面的命令可以帮助您使用bash shell登录到容器。从此时起,你在容器中所做的任何更改都会被docker自动保存。 例如- apt-get在容器内安装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