2017-07-29 4 views
0

Il semble y avoir une différence entre la façon dont Docker exécute des commandes dans un Dockerfile et les commandes exécutées manuellement après le démarrage d'un conteneur. Cela semble être dû au type de shells que vous pouvez démarrer, un shell non interactif (je suppose) avec un Dockerfile et un shell interactif lors de l'exécution de quelque chose comme docker run -it <some-img-id>.Comment exécuter DCDer cmds Exactement comme dans un Dockerfile

Comment puis-je déboguer des commandes en cours d'exécution dans un conteneur Docker afin qu'il s'exécute exactement comme les commandes sont exécutées à partir d'un fichier Docker? Est-ce que simplement ajouter /bin/bash --noprofile au run suffit? Ou y a-t-il autre chose de différent au sujet de l'environnement quand il est démarré à partir d'un Dockerfile?

+0

Il n'y a pas de réponse générique à ceci - nous aurions besoin de voir la commande ** spécifique ** que vous demandez. A [mcve] montrer aux autres comment voir la différence par eux-mêmes serait également utile. –

+0

... des commandes comme 'COPY' sont implémentées complètement à l'intérieur de Docker - elles n'appellent pas du tout un shell. Et 'RUN' et kin ont différents modes - si vous passez une liste d'arguments littérale en tant que tableau, encore une fois, pas de shell n'importe où. –

Répondre

1

Ce que vous rencontrez est le comportement à cause du shell. La plupart des utilisations sont utilisées pour utiliser shell bash. Donc, en général, nous tenterions d'exécuter les commandes en dessous de la mode

Pour le nouveau conteneur

docker run -it <imageid> bash 

Pour conteneur existant

docker exec -it <containerid> bash 

Mais quand nous spécifions une commande à l'aide RUN directive à l'intérieur un Dockerfile

RUN echo Testing 

Ensuite, il est équivalent à /bin/sh -c 'echo Testing'. Donc, vous pouvez vous attendre à certaines différences car les deux coquilles sont différentes.

Dans Docker 1,12 ou plus, vous avez une directive Dockerfile nommé SHELL ce qui vous permet de remplacer la valeur par défaut SHELL

SHELL ["/bin/bash", "-c"] 
RUN echo Testing 

Cela rendrait la commande RUN exécutée comme bash -c 'echo Testing'. Vous pouvez en apprendre plus sur la directive SHELLhere

1

Réponse courte 1:

Si Dockerfile ne pas utiliser USER et SHELL commandes, alors ceci:

docker --entrypoint "/bin/sh -c" -u root <image> cmd 

Réponse courte 2:

Si vous n'êtes pas écrasez ou compressez l'image après la construction, Docker crée des couches d'images pour chacune des commandes Dockerfile. Vous pouvez les voir dans la sortie de docker build à la fin de chaque étape avec --->:

Step 2/8 : WORKDIR /usr/src/app 
    ---> 5a5964bed25d # <== THIS IS IMAGE ID OF STEP 2 
Removing intermediate container b2bc9558e499 
Step 3/8 : RUN something 
    ---> f6e90f0a06e2 # <== THIS IS IMAGE ID OF STEP 3 
Removing intermediate container b2bc9558e499 

Rechercher l'ID d'image juste avant l'étape RUN vous souhaitez déboguer (par exemple, vous voulez à l'étape de mise au point 3 sur ci-dessus , prenez l'étape 2 image id). Ensuite, il suffit d'exécuter la commande dans cette image:

docker run -it 5a5964bed25d cmd 

Réponse longue 1:

Lorsque vous exécutez docker run [image] cmd Docker en fait commence la cmd de cette façon:

  • Exécute le point d'entrée par défaut de l'image avec le cmd comme argument. Entrypoint est stocké dans l'image lors de la construction par la commande ENTRYPOINT dans Dockerfile. C'est à dire si cmd est my-app et entrypoint est /bin/sh -c, il exécute /bin/sh -c my-app.
  • Démarre avec l'ID utilisateur par défaut de l'image, qui est définie par la dernière commande USER dans Dockerfile
  • Démarre avec les variables d'environnement de toutes ENV commandes de Dockerfile de l'image commulative

Lorsque docker build exécute la Dockerfile RUN, il fait exactement la même chose, seulement avec les valeurs présentes à ce moment là (ligne) du Dockerfile. Donc, pour être exact, vous devez prendre la valeur de la commande ENVs et last USER avant votre ligne RUN, et les utiliser dans la commande docker run.

La plupart des images courantes ont /bin/sh -c ou /bin/bash -c comme point d'entrée et la plus probable est que la construction fonctionne avec l'utilisateur root.Par conséquent docker --entrypoint "/bin/bash -c" -u root <image> cmd devrait être suffisant