Exécuter des commandes à l’intérieur d’un conteneur Docker est plus facile que vous ne le pensez.

Un conteneur Docker est un environnement isolé qui contient généralement une seule application avec toutes les dépendances nécessaires. Nous avons souvent besoin d’exécuter des commandes à l’intérieur d’un conteneur Docker. Il existe plusieurs façons d’exécuter une commande à l’intérieur d’un conteneur et d’obtenir la sortie souhaitée.

Voyons comment nous pouvons le faire.

Utilisation du shell interactif

Nous pouvons accéder directement au shell d’un conteneur et exécuter nos commandes comme avec un terminal Linux normal. Pour obtenir un shell interactif d’un conteneur arrêté (qui n’est pas en cours d’exécution), vous pouvez utiliser :

$ docker run -it ubuntu bash
root@c520631f652d:/#

Comme vous pouvez le voir, nous atterrissons directement dans un nouveau conteneur Ubuntu où nous pouvons exécuter nos commandes. Si un conteneur est déjà en cours d’exécution, vous pouvez utiliser la commande exec comme ci-dessous.

Tout d’abord, trouvons l’ID du conteneur.

$ docker ps
ID DU CONTENEUR IMAGE COMMANDE CRÉÉ STATUT PORTS NOMS
c2d969adde7a nginx "/docker-entrypoint...." il y a 2 heures En haut 2 heures 127.0.0.1:80->80/tcp nginx
0960560bc24b mariadb "docker-entrypoint.s..." il y a 2 heures En haut 2 heures 127.0.0.1:3306->3306/tcp mariadb

Et, ensuite, entrez dans le conteneur ID c2d969adde7a

$ docker exec -it c2d969adde7a bash 
root@c2d969adde7a:/#

Dans la sortie ci-dessus, vous pouvez observer que nous avons démarré une session bash du conteneur nginx qui était en cours d’exécution. Ici, nous pouvons exécuter n’importe quelle commande prise en charge et obtenir la sortie.

Note – votre conteneur peut ne pas avoir bash et si c’est le cas, vous pouvez utiliser sh.

Ex :

docker exec -it c2d969adde7a sh

Sortie directe

Souvent, nous avons juste besoin de la sortie d’une ou deux commandes et nous n’avons pas besoin d’une session interactive complète pour notre tâche. Vous pouvez exécuter la commande requise à l’intérieur d’un conteneur et obtenir sa sortie directement sans ouvrir une nouvelle session shell en utilisant la commande exec sans le drapeau -it. La syntaxe est la suivante

$ docker exec <id ou nom du conteneur> <commande>

Voici un exemple :

$ docker ps
CONTENEUR ID IMAGE COMMANDE CRÉÉ STATUT PORTS NOMS
c2d969adde7a nginx "/docker-entrypoint...." il y a 2 heures En haut 2 heures 127.0.0.1:80->80/tcp nginx
0960560bc24b mariadb "docker-entrypoint.s..." Il y a 2 heures En haut 2 heures 127.0.0.1:3306->3306/tcp mariadb

$ docker exec 0960560bc24b ps -ef | grep mysql
mysql 1 0 0 13:35 ?        00:00:02 mysqld
$

Nous avons exécuté la commande ps -ef | grep mysql à l’intérieur du conteneur MariaDB en cours d’exécution et nous avons obtenu la sortie directement.

La méthode Dockerfile

Ce n’est pas la façon exacte d’exécuter des commandes à l’intérieur d’un conteneur Docker, bien que cela puisse être utile dans des situations de développement ou pour le débogage d’un déploiement initial, etc. Nous pouvons utiliser la commande RUN à l’intérieur d’un Dockerfile. Voici notre exemple de fichier Docker :

FROM nginx:latest
RUN nginx -V

Il extrait simplement la dernière image nginx du registre et exécute ensuite la commande nginx -V pour afficher la version de Nginx lorsque vous construisez l’image.

$ docker build -t nginx-test .
Envoi du contexte de construction au démon Docker 2.048kB
Étape 1/2 : FROM nginx:latest
 --->
 7ce4f91ef623
Etape 2/2 : Exécuter nginx -V
 --->
 Exécuté dans 43918bbbeaa5
version de nginx : nginx/1.19.9
construit par gcc 8.3.0 (Debian 8.3.0-6)
construit avec OpenSSL 1.1.1d 10 Sep 2019
Prise en charge SNI TLS activée
arguments de configuration : --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --avec-http_gzip_static_module - avec-http_mp4_module - avec-http_random_index_module - avec-http_realip_module - avec-http_secure_link_module - avec-http_slice_module - avec-http_ssl_module - avec-http_stub_status_module - avec-http_sub_module - avec-http_gzip_static_module - avec-http_gzip_static_module - avec-http_gzip_static_modulehttp_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.9/debian/debuild-base/nginx-1.19.9=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-need -pie'
Suppression du conteneur intermédiaire 43918bbbeaa5
 --->
 d682277f2e50
Construit avec succès d682277f2e50
Marqué avec succès nginx-test:latest
$

Observez la sortie de la commande RUN dans l’extrait ci-dessus. L’extrait ci-dessus ne s’affiche que lors de la première compilation et les compilations suivantes ne répètent pas la sortie de la commande RUN. Comme solution de contournement, vous pouvez essayer le drapeau --no-cache:

$ docker build -t nginx-test . --no-cache

La dernière méthode n’est pas la meilleure mais peut parfois être utile pour le débogage, etc.

Résumé

Exécuter une commande à l’intérieur d’un conteneur Docker est simple et il y a quelques méthodes disponibles pour le faire. C’est une tâche régulière de l’administrateur Docker, il est donc utile de connaître ces commandes.

More on Docker