Python Docker交互模式和执行脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25101596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:43:52  来源:igfitidea点击:

Docker interactive mode and executing script

pythoncontainersdocker

提问by will.fiset

I have a Python script in my docker container that needs to be executed, but I also need to have interactive access to the container once it has been created ( with /bin/bash ).

我的 docker 容器中有一个 Python 脚本需要执行,但我还需要在创建容器后对容器进行交互式访问(使用 /bin/bash )。

I would like to be able to create my container, have my script executed and be inside the container to see the changes/results that have occurred (no need to manually execute my python script).

我希望能够创建我的容器,执行我的脚本并在容器内查看已发生的更改/结果(无需手动执行我的 python 脚本)。

The current issue I am facing is that if I use the CMD or ENTRYPOINT commands in the docker file I am unable to get back into the container once it has been created. I tried using docker start and docker attach but I'm getting the error:

我目前面临的问题是,如果我在 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"

Ideally, something close to this:

理想情况下,接近于此:

sudo docker run -i -t image /bin/bash python myscript.py


Assume my python script contains something like (It's irrelevant what it does, in this case it just creates a new file with text):

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

open('newfile.txt','w').write('Created new file with text\n')

When I create my container I want my script to execute and I would like to be able to see the content of the file. So something like:

当我创建我的容器时,我希望我的脚本能够执行,并且我希望能够看到文件的内容。所以像:

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#

In the example above my python script would have executed upon creation of the container to generate the new file newfile.txt. This is what I need.

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

回答by James Mills

I think this is what you mean.

我想这就是你的意思。

Note:THis uses Fabric(because I'm too lazy and/or don't have the time to work out how to wire up stdin/stdout/stderr to the terminal properly but you could spend the time and use straight subprocess.Popen):

注意:这使用Fabric因为我太懒惰和/或没有时间研究如何将 stdin/stdout/stderr 正确连接到终端,但您可以花时间直接使用subprocess.Popen):

Output:

输出:

$ 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:

Dockerfile:

# Test Docker Image

FROM python:2

ADD myscript.py /usr/bin/myscript

RUN pip install fabric

CMD ["/usr/bin/myscript"]

myscript.py:

我的脚本.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!")

回答by Regan

Why not this?

为什么不是这个?

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

Or if you want it to stay on the container

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

docker run --name="scriptPy" -i -t image /bin/bash python myscript.py
docker start scriptPy
docker attach scriptPy

Hope it was helpful.

希望它有帮助。

回答by Roman Nikitchenko

My way of doing it is slightly different with some advantages. It is actually multi-session server rather than script but could be even more usable in some scenarios:

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

# 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

Main advantage is you can attach several bash sessions to single container. For example I can exec one session with bash for telling log and in another session do actual commands.

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

BTW when you detach last 'exec' session your container is still running so it can perform operations in background

顺便说一句,当您分离最后一个“执行”会话时,您的容器仍在运行,因此它可以在后台执行操作

回答by Olli

You can run a docker image, perform a script and have an interactive session with a single command:

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

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

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

The second bashwill keep the interactive terminal session open, irrespective of the CMD command in the Dockerfile the image has been created with, since the CMD command is overwritten by the bash - ccommand above.

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

There is also no need to appending a command like local("/bin/bash")to your Python script (or bashin case of a shell script).

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

Assuming that the script has not yet been transferred from the Docker host to the docker image by an ADDDockerfile command, we can map the volumes and run the script from there: sudo docker run -it -v <host-location-of-your-script>:/scripts <image-name> bash -c "/scripts/<your-script-name>; bash"

假设脚本尚未通过ADDDockerfile 命令从 Docker 主机传输到docker 镜像,我们可以映射卷并从那里运行脚本: sudo docker run -it -v <host-location-of-your-script>:/scripts <image-name> bash -c "/scripts/<your-script-name>; bash"

Example: assuming that the python script in the original question is already on the docker image, we can omit the -v optionand the command is as simple as follows: sudo docker run -it image bash -c "python myscript.py; bash"

示例:假设原题中的python脚本已经在docker镜像上,我们可以省略-v option,命令简单如下: sudo docker run -it image bash -c "python myscript.py; bash"