Docker Exec - Comment exécuter une commande dans une image ou un conteneur Docker

Je vais vous révéler un secret DevOps ici: la chose que tous les gens de DevOpsy aiment faire est de construire un système super sophistiqué et complexe, puis de trouver un moyen de le gérer comme un shell ordinaire. Ou connectez-vous avec SSH et traitez-le comme un shell normal.

Docker n'est pas différent! Vous exécutez un ordinateur dans un autre ordinateur. Peut-être que cet ordinateur est une instance EC2 ou un ordinateur portable. Vous pouvez même devenir vraiment fou et exécuter une VM qui exécute ensuite Docker.

La plupart du temps, lorsque j'utilise Docker, je l'utilise pour empaqueter et distribuer une application. Parfois, je l'utilise pour quelque chose de plus cool comme un projet informatique distribué. Mais souvent, je lance un Dockerfile dans un dépôt GitHub afin de ne pas avoir à installer des CLI dont je sais qu'elles finiront par entrer en conflit sur mon ordinateur portable.

Pour faire court, vous pouvez dire à Docker d'exécuter la commande bash, qui vous place dans un shell:

docker run -it name-of-image bash # docker run -it continuumio/miniconda3:latest bash # docker run -it node:latest bash

Mais continuez à lire pour en savoir plus. ;-)

Essaye le

Google Docker de votre langage de programmation préféré. Pour moi, c'est Python, et en particulier j'aime conda. Exécutez ensuite quelques commandes pour vous assurer que vous êtes bien dans ce shell.

# From Host echo $(pwd) # Drop into docker shell docker run -it continuumio/miniconda3:latest bash # Now you are in the docker shell! echo $(pwd) echo $USER

Cool hein? C'est parfait pour déboguer un conteneur qui doit absolument fonctionner correctement. C'est aussi très bien pour mon cas d'utilisation le plus courant «Je ne veux pas installer ceci sur mon ordinateur».

Déboguer une build Docker avec Docker Run

Traiter votre image Docker comme un shell normal vous sera utile lorsque vous essayez de déboguer des builds Docker.

Supposons que vous ayez un Dockerfile pour une image que vous essayez de créer. Normalement, ce qui se passe, c'est que lors de l'exécution docker build -t my-image .(-t est pour tag) Docker exécute chacune de vos étapes RUN et s'arrête lorsqu'il arrive à une commande qui ne se termine pas correctement.

Dans un shell UNIX, le code de sortie 0 signifie que tout va bien avec une commande. Donc, pour illustrer ce point, j'ai fait en sorte que notre Dockerfile ait une commande RUN qui se termine par 1.

FROM continuumio/miniconda3:latest RUN apt-get update -y; \ apt-get upgrade -y; \ apt-get install -y \ vim-tiny vim-athena build-essential RUN conda update conda \ && conda clean --all --yes RUN exit 1
docker build -t my-image .

Cela vous donnera une sortie qui ressemble à:

(base) ➜ my-image docker build -t my-image . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM continuumio/miniconda3:latest ---> 406f2b43ea59 Step 2/4 : RUN apt-get update -y; apt-get upgrade -y; apt-get install -y vim-tiny vim-athena build-essential ---> Using cache ---> 726af29a48a0 Step 3/4 : RUN conda update conda && conda clean --all --yes ---> Using cache ---> 19478bb3ce67 Step 4/4 : RUN exit 1 ---> Running in 7c98aab6b52c The command '/bin/sh -c exit 1' returned a non-zero code: 1

Vous pouvez confirmer que votre image Docker n'a pas été créée en exécutant docker imageset en recherchant my-image. Il ne sera pas là parce qu'il n'a pas été construit avec succès.

Maintenant, ce que nous pouvons faire est de commenter cette commande dérangeante Dockerfile RUN.

FROM continuumio/miniconda3:latest RUN apt-get update -y; \ apt-get upgrade -y; \ apt-get install -y \ vim-tiny vim-athena build-essential RUN conda update conda \ && conda clean --all --yes #RUN exit 1

Ensuite, ce que vous verrez est:

Sending build context to Docker daemon 2.048kB Step 1/3 : FROM continuumio/miniconda3:latest ---> 406f2b43ea59 Step 2/3 : RUN apt-get update -y; apt-get upgrade -y; apt-get install -y vim-tiny vim-athena build-essential ---> Using cache ---> 726af29a48a0 Step 3/3 : RUN conda update conda && conda clean --all --yes ---> Using cache ---> 19478bb3ce67 Successfully built 19478bb3ce67 Successfully tagged my-image:latest 

Vous pouvez maintenant déposer dans votre image Docker et commencer à exécuter des commandes de manière interactive!

docker run -it my-image bash # you can also run # docker run -it my-image:latest bash

De là, un par un, vous pouvez commencer à déboguer vos commandes RUN pour voir ce qui n'a pas fonctionné. Si vous n'êtes pas sûr qu'une commande s'est terminée correctement ou non, exécutez $?:

# First run docker run -it my-image bash to get to the shell # Print the string hello echo "hello" # hello echo $? # 0 # Run a non existant command hello $(hello) # bash: hello: command not found echo $? # 127

Vous pouvez continuer à exécuter ces étapes, commenter votre Dockerfile, passer dans un shell et déterminer les commandes problématiques, jusqu'à ce que vos images Docker se construisent parfaitement.

Emballer

J'espère que je vous ai montré que l'utilisation d'une image Docker n'est pas différente du terminal de votre ordinateur. L'utilisation d'images Docker est un excellent moyen de distribuer des applications.

Essayez de prendre votre application CLI préférée ou le prochain projet GitHub, et au lieu de créer un script d'installation, empaquetez-le avec Docker. ;-)