Docker交互模式并执行脚本
我的Docker容器中有一个需要执行的Python脚本,但是我也需要在容器创build后(使用/ bin / bash)交互访问容器。
我想能够创build我的容器,执行我的脚本,并在容器内查看发生的变化/结果(无需手动执行我的Python脚本)。
我面临的当前问题是,如果我在docker文件中使用CMD或ENTRYPOINT命令,一旦创build了容器,我就无法返回容器。 我尝试使用docker启动和docker附加,但我得到的错误:
sudo docker start containerID sudo docker attach containerID "You cannot attach to a stepped container, start it first"
理想情况下,接近这个:
sudo docker run -i -t image /bin/bash python myscript.py
假设我的python脚本包含类似的东西(它与它无关,在这种情况下它只是创build一个带有文本的新文件):
open('newfile.txt','w').write('Created new file with text\n')
当我创build我的容器,我希望我的脚本执行,我希望能够看到文件的内容。 所以像这样:
root@66bddaa892ed# sudo docker run -i -t image /bin/bash bash4.1# ls newfile.txt bash4.1# cat newfile.txt Created new file with text bash4.1# exit root@66bddaa892ed#
在上面的例子中,我的python脚本会在创build容器时执行,以生成新文件newfile.txt。 这是我需要的。
我的做法略有不同,有一些优点。 它实际上是多会话服务器而不是脚本,但在某些情况下可能更加可用:
# Just create interactive container. No start but named for future reference. # Use your own image. docker create -it --name new-container <image> # Now start it. docker start new-container # Now attach bash session. docker exec -it new-container bash
主要优点是你可以附加几个bash会话到单个容器。 例如,我可以使用bash执行一个会话来告诉日志,而在另一个会话中执行实际的命令。
顺便说一句,当你分离最后的'exec'会话你的容器仍在运行,所以它可以在后台执行操作
我想这是你的意思。
注意:这是使用Fabric ( 因为我太懒惰和/或没有时间弄清楚如何将stdin / stdout / stderr正确连接到terminal,但你可以花费时间并使用直接subprocess.Popen
) :
输出:
$ docker run -i -t test Entering bash... [localhost] local: /bin/bash root@66bddaa892ed:/usr/src/python# cat hello.txt Hello World!root@66bddaa892ed:/usr/src/python# exit Goodbye!
Dockerfile:
# Test Docker Image FROM python:2 ADD myscript.py /usr/bin/myscript RUN pip install fabric CMD ["/usr/bin/myscript"]
myscript.py:
#!/usr/bin/env python from __future__ import print_function from fabric.api import local with open("hello.txt", "w") as f: f.write("Hello World!") print("Entering bash...") local("/bin/bash") print("Goodbye!")
为什么不呢?
docker run --name="scriptPy" -i -t image /bin/bash python myscript.py docker cp scriptPy:/path/to/newfile.txt /path/to/host vim /path/to/host
或者如果你想要它留在容器上
docker run --name="scriptPy" -i -t image /bin/bash python myscript.py docker start scriptPy docker attach scriptPy
希望这是有帮助的。
您可以运行一个docker镜像,执行一个脚本并通过一个命令进行交互式会话:
sudo docker run -it <image-name> bash -c "<your-script-full-path>; bash"
由于CMD命令被上面的bash - c
命令覆盖,第二个bash
将保持交互式terminal会话处于打开状态,而不pipeDockerfile中的CMD命令是否已经被创build。
也不需要在你的Python脚本中添加像local("/bin/bash")
这样的命令(或者在shell脚本中为bash
)。
假设脚本尚未通过ADD
Dockerfile命令从Docker主机传输到Docker镜像,我们可以映射这些卷并从那里运行脚本: sudo docker run -it -v <host-location-of-your-script>:/scripts <image-name> bash -c "/scripts/<your-script-name>; bash"
例如:假设原始问题中的python脚本已经在docker镜像上,我们可以省略-v option
,命令如下所示: sudo docker run -it image bash -c "python myscript.py; bash"