背景:
我需要开发一个Dockerfile。
但是在此之前,我想选择一个基础图像,并基于该基础图像启动一个容器。
在容器启动之后,我想尝试安装一些软件包并修改我的服务的一些配置。如果可以手动完成一切,最后我可以将所有这些步骤移动到:打包安装和配置设置(通过手动尝试证明有效)到我的Dockerfile。
问题:
有时候,在我尝试了许多正确的步骤之后,然后进行错误的配置。更糟的是,我停止容器并再次启动容器,以证明启动脚本正常。
但是不幸的是,由于容器中配置了错误的应用程序,容器已经无法启动。
事实上,我想在容器中尝试其他配置,然后也许一切都会好起来,但是我再也没有机会再次进入容器。我不想重置新容器,因为我已经在旧容器中做了很多手动操作(由于我处于开发阶段,所以没有将正确的步骤移至Dockerfile,我想在证明一切都正确之后再做)好)
接下来是显示我的情况的最小示例:
Dockerfile:
FROM alpine
ADD ./docker-entrypoint.sh .
RUN chmod 777 ./docker-entrypoint.sh
ENTRYPOINT ["./docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/sh
touch /tmp/app.log
tail -f /tmp/app.log
我将在上面做什么
docker build --no-cache -t try .
docker run -idt --name me try
docker exec -it me /bin/sh
将docker-entrypoint.sh
更改为下一个:
#!/bin/sh
exit 0
touch /tmp/app.log
tail -f /tmp/app.log
然后:
docker stop me
docker start me # the container will not start
现在,我知道exit 0
可能是错误的命令或错误的配置,我想尝试其他方法,但是没有机会。
再次,要注意:
我不想重置容器,因为我已经在旧容器中手动完成了很多操作,而不仅仅是exit 0
。
而且, supervisord
也不是我在开发生命周期中所需要的,我只是想使事情变得简单。类似于更改entrypoint for an already existed container
(似乎仅适用于docker run
)
有什么建议可以简化我的开发阶段吗?
答案 0 :(得分:1)
有趣。基本上,您现在有了一个运行脚本的容器,该脚本可立即退出。但是,您要保存它。
尝试以下操作:
将您的容器作为另一个图像提交。
docker commit me me / snap:v001
使用图像运行bash。
docker run -it --name me2 me / snap:v001 bash
修复您的入口点代码。
答案 1 :(得分:1)
只需编写您的Dockerfile。编辑,运行docker build
,然后重复。
关于Dockerfile并没有什么特别神奇的。如果您采用这种方法,但决定在文本文件中进行详细注释:我想开始FROM
一些基本图像,然后开始RUN
一些命令,COPY
中一些文件,以及{{ 1}}其他命令:这是一个Dockerfile。它的优点是始终从干净的环境开始,并且始终可复制。
例如,假设您正在尝试手动编译某些软件包,但是配置选项并不正确。
RUN
现在您可以运行FROM ubuntu:18.04
RUN apt-get update && apt-get install build-essential
WORKDIR /package
COPY some-package.tar.gz ./
RUN tar xzf some-package.tar.gz
WORKDIR /package/some-package
RUN ./config --wrong-option
RUN make
RUN make install
CMD ["some-command"]
,它将通过此命令序列运行。也许到达docker build .
时它将失败(因为该脚本实际上被命名为RUN ./config
)。您可以编辑Dockerfile并重新运行./configure
,然后Docker将重新启动之前失败的位置。同样,当您发现docker build
错误时,可以对其进行更改,而--wrong-option
将从更改的行重新开始。
如果您需要在中断的阶段进行进一步的调试(也许docker build
完成了配置步骤,但是构建失败),--wrong-option
输出将包括每个层的图像ID,您可以{ {1}},以在出现问题的步骤之前在部分图像上获得外壳。
有一些优化措施,例如将docker build
行结合在一起和多阶段构建非常有用,但是您可以将它们保存为最后。
docker run --rm -it 0123456789ab sh
并不是您与Docker交互的主要方式。您将碰到的正是您遇到的问题:没有持久的记录来记录您所做的事情,它并不是特别可复制,并且如果容器被删除,您将失去所有工作。