我在docker容器中有一个Python脚本需要执行,但我还需要在创建容器后(使用/bin/bash)对容器进行交互式访问。
我希望能够创建我的容器,执行我的脚本,并在容器内看到发生的更改/结果(不需要手动执行我的Python脚本)。
我目前面临的问题是,如果我在docker文件中使用CMD或ENTRYPOINT命令,一旦创建了容器,我就无法返回容器。我尝试使用docker start和docker attach,但出现错误:
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脚本包含类似这样的内容(它做什么无关紧要,在这种情况下,它只是创建一个带有文本的新文件):
open('newfile.txt','w').write('Created new file with text\n')
当我创建我的容器时,我希望我的脚本能够执行,并且我希望能够看到文件的内容。比如说
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脚本将在创建容器时执行,以生成新文件newfile.txt。这就是我需要的
6条答案
按热度按时间fd3cxomn1#
我的做法略有不同,有一些优点。它实际上是多会话服务器而不是脚本,但在某些情况下可能更有用:
主要优点是你可以将多个bash会话附加到单个容器。例如,我可以用bash执行一个会话来告诉日志,而在另一个会话中执行实际的命令。
顺便说一句,当你分离最后一个'exec'会话时,你的容器仍然在运行,所以它可以在后台执行操作
aydmsdu92#
你可以运行一个docker镜像,执行一个脚本,并使用一个命令进行交互式会话:
sudo docker run -it <image-name> bash -c "<your-script-full-path>; bash"
第二个
bash
将保持交互式终端会话打开,而不管创建镜像的Dockerfile中的CMD命令如何,因为CMD命令被上面的bash - c
命令覆盖。也不需要在Python脚本中附加像
local("/bin/bash")
这样的命令(或者在shell脚本中附加bash
)。假设脚本尚未通过
ADD
Dockerfile命令从Docker主机传输到Docker镜像,我们可以Map卷并从那里运行脚本: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"
iqih9akk3#
为什么不是这个?
或者你想让它留在集装箱上
希望对你有帮助。
j2cgzkjk4#
我想这就是你的意思。
**注意:*THis使用Fabric( 因为我太懒和/或没有时间去解决如何正确地将stdin/stdout/stderr连接到终端,但你可以花时间直接使用
subprocess.Popen
*):输出:
Dockerfile:
myscript.py:
dldeef675#
有时,您的Python脚本可能会调用文件夹中的不同文件,如其他Python脚本,CSV文件,JSON文件等。
我认为最好的方法是与您的容器共享目录,这样可以更容易地创建一个可以访问所有所需文件的环境
创建一个文本脚本
添加此脚本作为其内容
增加执行权限
然后,您可以调用以下命令将脚本调用到项目文件夹:
这个调用将创建一个新的python容器来共享你的文件夹。这使得文件夹中的所有文件都可以作为CSV或二进制文件访问。
使用此策略,您可以在容器中快速测试项目,并与容器交互以调试它。
这种方法的一个问题是关于再现性。也就是说,您可以使用运行应用程序所需的shell脚本来安装某些内容。但是,这种变化只是发生在你的容器内。因此,任何试图运行您的代码的人都必须弄清楚您在运行它时做了什么,并做同样的事情。
因此,如果您可以在不安装任何特殊内容的情况下运行项目,那么这种方法可能非常适合您。但是,如果你必须在容器中安装或更改一些东西才能运行你的项目,那么你可能需要创建一个Dockerfile来保存这些命令。这将使从加载容器、进行所需更改到加载文件的所有步骤都易于复制。
dz6r00yl6#
有时候不能简单地执行
$ docker run -it <image>
,因为它可能会运行入口点。在这种情况下,您可以执行以下操作(例如对于image python:3.9-slim):我使用
docker ps
只是为了显示它正在运行以及相应的容器ID。但也可以使用从docker run -itd ...
返回的完整容器ID(* b6 b54 c 042 af 2085 b 0 e619 c5159 fd 776875 af 44351 d22096 b 0 c574 ac 1a 7798318 *)