Подтвердить что ты не робот

Интерактивный режим Docker и выполнение script

У меня есть Python script в моем контейнере докера, который нужно выполнить, но мне также нужно иметь интерактивный доступ к контейнеру после его создания (с помощью /bin/ bash).

Я хотел бы иметь возможность создать свой контейнер, выполнить мой script и находиться внутри контейнера, чтобы увидеть изменения/результаты, которые произошли (нет необходимости вручную выполнять мой python script).

Текущая проблема, с которой я сталкиваюсь, заключается в том, что если я использую команды 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 script содержит что-то вроде (не имеет значения, что он делает, в этом случае он просто создает новый файл с текстом):

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

Когда я создаю свой контейнер, я хочу, чтобы мой script выполнялся, и я хотел бы видеть содержимое файла. Так что-то вроде:

[email protected]# 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
[email protected]#

В приведенном выше примере мой python script выполнил бы при создании контейнера для создания нового файла newfile.txt. Это то, что мне нужно.

4b9b3361

Ответ 1

Мой способ сделать это немного отличается от некоторых преимуществ. Это скорее многосегментный сервер, чем script, но может быть еще более удобным в некоторых сценариях:

# 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 для сообщения журнала, а в другом сеансе - действительные команды.

BTW, когда вы отсоединяете последний сеанс "exec", ваш контейнер все еще запущен, чтобы он мог выполнять операции в фоновом режиме

Ответ 2

Я думаю, это то, что вы имеете в виду.

Примечание: Это использует Fabric (потому что я слишком ленив и/или не имею время, чтобы выяснить, как правильно подключить stdin/stdout/stderr к терминалу, но вы можете потратить время и использовать прямой subprocess.Popen):

Вывод:

$ docker run -i -t test
Entering bash...
[localhost] local: /bin/bash
[email protected]:/usr/src/python# cat hello.txt
Hello [email protected]:/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!")

Ответ 3

Почему не это?

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

Надеюсь, что это было полезно.

Ответ 4

Вы можете запустить изображение докеров, выполнить script и иметь интерактивный сеанс с помощью одной команды:

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

Второй bash будет держать сеанс интерактивного терминала открытым, независимо от команды CMD в файле Docker, с которой было создано изображение, поскольку команда CMD перезаписывается командой bash - c выше.

Также нет необходимости добавлять команду local("/bin/bash") к вашему Python script (или bash в случае оболочки script).

Предполагая, что script еще не перенесен с хоста Docker на изображение докера с помощью команды ADD Dockerfile, мы можем отобразить тома и запустить script: sudo docker run -it -v <host-location-of-your-script>:/scripts <image-name> bash -c "/scripts/<your-script-name>; bash"

Пример: если предположить, что python script в исходном вопросе уже находится на изображении докера, мы можем опустить -v option, и команда будет такой простой: sudo docker run -it image bash -c "python myscript.py; bash"