web-dev-qa-db-fra.com

Mode interactif Docker et exécution du script

J'ai un script Python dans mon conteneur Docker qui doit être exécuté, mais j'ai également besoin d'avoir un accès interactif au conteneur une fois qu'il a été créé (avec/bin/bash).

Je voudrais pouvoir créer mon conteneur, faire exécuter mon script et être à l'intérieur du conteneur pour voir les changements/résultats qui se sont produits (pas besoin d'exécuter manuellement mon python).

Le problème actuel auquel je suis confronté est que si j'utilise les commandes CMD ou ENTRYPOINT dans le fichier docker, je ne peux pas retourner dans le conteneur une fois qu'il a été créé. J'ai essayé d'utiliser Docker Start et Docker Attach mais j'obtiens l'erreur:

Sudo docker start containerID
Sudo docker attach containerID
"You cannot attach to a stepped container, start it first"

Idéalement, quelque chose de proche:

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

Supposons que mon python contient quelque chose comme (ce n'est pas pertinent ce qu'il fait, dans ce cas, il crée juste un nouveau fichier avec du texte):

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

Lorsque je crée mon conteneur, je veux que mon script s'exécute et je voudrais pouvoir voir le contenu du fichier. Donc quelque chose comme:

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#

Dans l'exemple ci-dessus mon script python aurait été exécuté lors de la création du conteneur pour générer le nouveau fichier newfile.txt. C'est ce dont j'ai besoin.

24
will.fiset

Ma façon de procéder est légèrement différente avec quelques avantages. Il s'agit en fait d'un serveur multisession plutôt que d'un script, mais il pourrait être encore plus utilisable dans certains scénarios:

# 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

Le principal avantage est que vous pouvez attacher plusieurs sessions bash à un seul conteneur. Par exemple, je peux exécuter une session avec bash pour indiquer le journal et dans une autre session exécuter des commandes réelles.

BTW lorsque vous détachez la dernière session 'exec', votre conteneur est toujours en cours d'exécution afin qu'il puisse effectuer des opérations en arrière-plan

29
Roman Nikitchenko

Pourquoi pas ça?

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

Ou si vous voulez qu'il reste sur le conteneur

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

J'espère que cela a été utile.

3
Regan

Vous pouvez exécuter une image docker, exécuter un script et avoir une session interactive avec une seule commande:

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

Le second bash gardera la session du terminal interactif ouverte, quelle que soit la commande CMD dans le Dockerfile avec lequel l'image a été créée, car la commande CMD est remplacée par la commande bash - c Ci-dessus.

Il n'est également pas nécessaire d'ajouter une commande comme local("/bin/bash") à votre Python (ou bash dans le cas d'un script Shell).

En supposant que le script n'a pas encore été transféré de l'hôte Docker à l'image docker par une commande ADD Dockerfile, nous pouvons mapper les volumes et exécuter le script à partir de là: Sudo docker run -it -v <Host-location-of-your-script>:/scripts <image-name> bash -c "/scripts/<your-script-name>; bash"

Exemple: en supposant que le script python dans la question d'origine est déjà sur l'image docker, nous pouvons omettre le -v option Et la commande est aussi simple que suit: Sudo docker run -it image bash -c "python myscript.py; bash"

3
Olli

Je pense que c'est ce que vous voulez dire.

Remarque: Cela utilise Fabric ( parce que je suis trop paresseux et/ou je n'ai pas le temps pour savoir comment câbler correctement stdin/stdout/stderr au terminal, mais vous pouvez passer du temps et utiliser directement subprocess.Popen):

Sortie:

$ 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