- 背景:我用它来运行我的 docker 容器
docker run -it ubuntu
。 - 我想做的事:我想在该容器内持久地安装来自 repos 的任何软件(让我们举例
gjiten
子)。 - 问题:
exit
加入容器后,安装的软件就消失了。 - 问题:如何
gjiten
在我的容器内持久安装软件(例如)?
杂项
- 据我所知,卷不起作用,因为我不知道
apt
在哪里安装包。(apt
但如果允许指定目标目录,这将是最好的解决方案。) - 我知道我可以在 docker 卷中使用 appimages,但是我无法使用
apt
,而且更新软件也变得很痛苦。 - 我知道我可以在 docker 卷上创建一个 chroot,但这真的很痛苦。
编辑:答案:
已退出的 Docker 容器仍然存在和变化从容器内部没有丢失。我为此创建了一个答案。
答案1
您需要创建一个 Dockerfile 并从现有镜像编写您自己的容器脚本。语法如下。
FROM UBUNTU:LATEST
RUN <some command like apt install>
您需要阅读手册才能完全理解它,因为它的内容比这更多。最好的学习方法是查看 dockerhub 和 github 上的任何项目。这样您就可以看到“成品”以及容器的制作方式。
HTH 一点点,s1mmel
这是一个实例。这是我之前构建的唯一 Repo 中的 Dockerfile。一个 Minecraft papermc 服务器。这不会带你走完所有路,但对于初学者来说,我认为这已经足够好了。
答案2
我认为自己对docker环境的认识并不正确,所以才产生了这个问题。
重要的
退出容器的信息不是丢失!已安装的程序即使退出后仍会保留 *。因此,这个问题基本上已经过时了。
下面我尝试阐明docker在这方面是如何工作的。
*这与 Kulfy 的评论“当你退出实例或终止 docker 服务时,除非在使用镜像时提交更改,否则更改和文件将会丢失”相反。
Docker 的工作原理
docker run ubuntu
从图像创建一个容器ubuntu
。- 只要主进程运行,容器就会运行。
- 由于 ubuntu 镜像中的主进程将立即完成,容器将立即退出(因此调用会在 shell 中立即返回)。
- 退出容器就像是系统关闭一样。容器并没有丢失。数据/系统更改仍然有效。
- 您可以使用
docker ps -a
它将显示甚至退出的容器来验证这一点。
- 您可以使用
问题相关
docker run -it ubuntu
从图像创建一个容器ubuntu
并在 shell 中启动交互模式。- 您现在可以在该容器中执行任何操作。(例如运行
touch aaa
或安装gjiten
) - 如果您
exit
在容器内键入内容,您将退出该容器内的终端 (TTY)。由于该终端是该容器的主要进程,因此现在退出,容器也将退出(= 关闭容器内的操作系统)。 - 您的数据没有丢失现在。系统刚刚关闭。
- 如果您
docker ps -a
现在运行,您仍然可以在那里看到您的容器。所有更改仍然有效;它只是目前没有运行。 docker container start -i [containerID]
您现在可以使用(-i
进行交互 )重新启动容器(如“重新启动系统”) 。- 您现在应该在容器内。
- 键入
ls
以查看您的文件aaa
是否还在那里。 - 您可以从另一个终端运行
docker ps
,它将显示当前正在运行的容器。
顺便说一句:请注意,您需要创建一个容器-it
才能-i
使用docker container start -i [containerID]
答案3
一个解决方案
如果可以访问主机,解决方案之一可能是进行commit
更改。不过,这将创建一个全新的映像。
- 启动容器
- 改变容器内部的东西
- 找出容器 ID
root@9a20cddf27c0
例如容器内的右侧部分
- 在主机上运行
docker commit [container ID] [new image name]
道具:来自评论的@Kulfy。
答案4
我认为你需要理解容器镜像. 两者之间有明显的区别容器和容器镜像。
每个容器都从静态映像运行。映像本身是一个压缩包,其中包含运行给定软件所需的一切(二进制文件、直接依赖项、第三方依赖项、配置文件、用户、文件权限,所有这些)。
一旦容器运行,它创建的一切都是短暂的,并且用户数据会持久保存到容器外部的卷中。
如果您需要永久安装特定的库或包,则需要修改映像。实际上,这意味着创建自己的映像Dockerfile
并继承FROM
要修改的基础映像。创建映像后,您可以基于它运行容器。
目前官方文档已经非常清楚:https://docs.docker.com/get-started/part2/