web-dev-qa-db-ja.com

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"

理想的には、これに近いもの:

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#

上記の例では、新しいファイルnewfile.txtを生成するために、コンテナの作成時にmy pythonスクリプトが実行されます。これが必要です。

24
will.fiset

私のやり方は若干異なり、いくつかの利点があります。実際にはスクリプトではなくマルチセッションサーバーですが、一部のシナリオではさらに使いやすくなります。

# 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で1つのセッションを実行し、別のセッションで実際のコマンドを実行できます。

ところで、最後の「exec」セッションをデタッチすると、コンテナはまだ実行されているため、バックグラウンドで操作を実行できます

29

どうしてですか?

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

お役に立てば幸いです。

3
Regan

単一のコマンドで、Dockerイメージを実行し、スクリプトを実行し、インタラクティブセッションを実行できます。

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

2番目のbashは、上記の_bash - c_コマンドによって上書きされるため、イメージが作成されたDockerfileのCMDコマンドに関係なく、インタラクティブターミナルセッションを開いたままにします。

local("/bin/bash")のようなコマンドをPythonスクリプト(またはシェルスクリプトの場合は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"_

3
Olli

これがあなたの言うことだと思います。

注:これは 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!

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!")
2
James Mills