Ejecutar comandos dentro de un contenedor docker es más fácil de lo que piensa.
Un contenedor docker es un entorno aislado que normalmente contiene una sola aplicación con todas las dependencias requeridas.
Muchas veces necesitamos ejecutar algunos comandos dentro de un contenedor docker.
Hay varias formas en las que podemos ejecutar un comando dentro de un contenedor y obtener el resultado requerido.
Veamos cómo podemos hacerlo.
Uso de Shell interactivo
Podemos acceder directamente al shell de un contenedor y ejecutar nuestros comandos como con una terminal Linux normal.
Para obtener un shell interactivo de un contenedor detenido (no en estado de ejecución), puede usar:
$ docker run -it ubuntu bash [email protected]:/#
Como puede ver, aterrizamos directamente dentro de un nuevo contenedor de Ubuntu donde podemos ejecutar nuestros comandos.
Si ya se está ejecutando un contenedor, puede usar el comando exec como se muestra a continuación.
Primero, averigüemos el ID del contenedor.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2d969adde7a nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 127.0.0.1:80->80/tcp nginx 0960560bc24b mariadb "docker-entrypoint.s…" 2 hours ago Up 2 hours 127.0.0.1:3306->3306/tcp mariadb
Y, luego ingrese al ID del contenedor c2d969adde7a
$ docker exec -it c2d969adde7a bash [email protected]:/#
En el resultado anterior, puede observar que iniciamos una sesión bash del contenedor nginx que estaba en estado de ejecución.
Aquí podemos ejecutar cualquier comando compatible y obtener el resultado.
Nota: es posible que su contenedor no tenga bash y, de ser así, puede usar sh.
Ex:
docker exec -it c2d969adde7a sh
Salida directa
A menudo, solo necesitamos la salida de uno o dos comandos y no requerimos una sesión interactiva completa para nuestra tarea.
Puede ejecutar el comando requerido dentro de un contenedor y obtener su salida directamente sin abrir una nueva sesión de shell usando el comando exec sin el indicador -it.
Su sintaxis sería:
$ docker exec <container-id or name> <command>
Aquí hay un ejemplo:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2d969adde7a nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 127.0.0.1:80->80/tcp nginx 0960560bc24b mariadb "docker-entrypoint.s…" 2 hours ago Up 2 hours 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 $
Ejecutamos ps -ef | comando grep mysql dentro del contenedor MariaDB en ejecución y obtuve el resultado directamente.
Camino Dockerfile
Esta no es la forma exacta en que puede ejecutar comandos dentro de un contenedor docker, aunque puede ser útil en situaciones de desarrollo o para la depuración de la implementación inicial, etc.
Podemos usar el comando EJECUTAR dentro de un Dockerfile.
Aquí está nuestro Dockerfile de muestra:
FROM nginx:latest RUN nginx -V
Simplemente extrae la última imagen de nginx del registro y luego ejecuta el comando nginx -V para mostrar la versión de Nginx cuando crea la imagen.
$ docker build -t nginx-test .Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx:latest ---> 7ce4f91ef623 Step 2/2 : RUN nginx -V ---> Running in 43918bbbeaa5 nginx version: nginx/1.19.9 built by gcc 8.3.0 (Debian 8.3.0-6) built with OpenSSL 1.1.1d 10 Sep 2019 TLS SNI support enabled configure arguments: --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 --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_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-needed -pie' Removing intermediate container 43918bbbeaa5 ---> d682277f2e50 Successfully built d682277f2e50 Successfully tagged nginx-test:latest $
Observe la salida del comando EJECUTAR en el fragmento anterior.
El fragmento anterior solo se mostrará en la primera compilación y las compilaciones consecutivas no repetirán la salida del comando EJECUTAR.
Como solución alternativa, puede probar –no-cache flag:
$ docker build -t nginx-test . --no-cache
El último método no es la mejor manera, pero a veces puede ser útil para la depuración, etc.
Resumen
Ejecutar un comando dentro de un contenedor docker es simple y hay algunos métodos disponibles para hacerlo.
Es una tarea habitual de un administrador de Docker, por lo que es útil conocer estos comandos.
A continuación, aprenda algunos de los comandos populares de Docker.