Интерактивный режим 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. Это то, что мне нужно.
Ответы
Ответ 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"