Docker交互模式和执行脚本

wil*_*set 26 python containers docker

我的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"
Run Code Online (Sandbox Code Playgroud)

理想情况下,接近这个:

sudo docker run -i -t image /bin/bash python myscript.py
Run Code Online (Sandbox Code Playgroud)

假设我的python脚本包含类似的东西(它与它的作用无关,在这种情况下它只是创建一个带文本的新文件):

open('newfile.txt','w').write('Created new file with text\n')
Run Code Online (Sandbox Code Playgroud)

当我创建我的容器时,我希望我的脚本能够执行,我希望能够看到该文件的内容.所以类似于:

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#
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我的python脚本将在创建容器时执行,以生成新文件newfile.txt.这就是我需要的.

Rom*_*nko 33

我的做法与一些优点略有不同.它实际上是多会话服务器而不是脚本,但在某些情况下可能更有用:

# 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
Run Code Online (Sandbox Code Playgroud)

主要优点是您可以将多个bash会话附加到单个容器.例如,我可以用bash执行一个会话来告诉日志,而在另一个会话中执行实际命令.

BTW当您分离最后一次'exec'会话时,您的容器仍在运行,因此它可以在后台执行操作

  • 这就是我要找的。 (2认同)

Oll*_*lli 8

您可以运行 docker 镜像、执行脚本并使用单个命令进行交互式会话:

sudo docker run -it <image-name> bash -c "<your-script-full-path>; bash"

第二个bash将保持交互式终端会话打开,而不管创建映像的 Dockerfile 中的 CMD 命令如何,因为 CMD 命令被bash - c上面的命令覆盖。

也无需local("/bin/bash")在 Python 脚本(或bash在 shell 脚本的情况下)附加命令。

假设脚本尚未通过ADDDockerfile 命令从 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"


Reg*_*gan 6

为什么不是这个?

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
Run Code Online (Sandbox Code Playgroud)

或者如果你想让它留在容器上

docker run --name="scriptPy" -i -t image /bin/bash python myscript.py
docker start scriptPy
docker attach scriptPy
Run Code Online (Sandbox Code Playgroud)

希望有帮助。


Jam*_*lls 3

我想这就是你的意思。

注意:这使用Fabric因为我太懒了和/或没有时间弄清楚如何将 stdin/stdout/stderr 正确连接到终端,但你可以花时间直接使用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!
Run Code Online (Sandbox Code Playgroud)

Dockerfile:

# Test Docker Image

FROM python:2

ADD myscript.py /usr/bin/myscript

RUN pip install fabric

CMD ["/usr/bin/myscript"]
Run Code Online (Sandbox Code Playgroud)

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!")
Run Code Online (Sandbox Code Playgroud)