Ejecutar comandos dentro de un contenedor Docker es más fácil de lo que crees.
Un contenedor docker es un entorno aislado que normalmente contiene una única aplicación con todas las dependencias necesarias. Muchas veces necesitamos ejecutar algunos comandos dentro de un contenedor docker. Hay varias maneras en las que podemos ejecutar un comando dentro de un contenedor y obtener la salida requerida.
Veamos cómo podemos hacerlo.
Uso del shell interactivo
Podemos acceder directamente al shell de un contenedor y ejecutar nuestros comandos como con un terminal Linux normal. Para obtener un intérprete de comandos interactivo de un contenedor detenido (no en estado de ejecución), puede utilizar:
$ docker run -it ubuntu bash
root@c520631f652d:/#
Como puedes ver, aterrizamos directamente dentro de un nuevo Ubuntu
donde podemos ejecutar nuestros comandos. Si ya hay un contenedor en ejecución, puede utilizar exec
como se indica 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, a continuación, obtener dentro de contenedor ID c2d969adde7a
$ docker exec -it c2d969adde7a bash
root@c2d969adde7a:/#
En la salida anterior, se puede observar que hemos iniciado un bash
sesión de nginx
que estaba en estado de ejecución. Aquí podemos ejecutar cualquier comando soportado y obtener la salida.
Nota - puede que tu contenedor no tenga bash y si es así, puedes usar sh.
Ex:
docker exec -it c2d969adde7a sh
Salida directa
A menudo sólo necesitamos la salida de uno o dos comandos y no necesitamos una sesión interactiva completa para nuestra tarea. Puedes ejecutar el comando requerido dentro de un contenedor y obtener su salida directamente sin abrir una nueva sesión de shell usando exec
comando sin -it
bandera. Su sintaxis sería:
$ docker exec <container-id or name> <command>
He aquí 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 | grep mysql
dentro del MariaDB y obtener la salida directamente.
Manera Dockerfile
Esta no es la forma exacta en que se pueden ejecutar comandos dentro de un archivo contenedor docker aunque puede ser útil en situaciones de desarrollo o para la depuración del despliegue inicial, etc. Podemos utilizar RUN
dentro de un archivo Dockerfile. Aquí está nuestro Dockerfile de ejemplo:
FROM nginx:latest
RUN nginx -V
Simplemente extrae la última nginx
desde el registro y ejecuta el programa nginx -V
para mostrar la versión de Nginx al compilar 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 de RUN
en el fragmento anterior. El fragmento anterior sólo se mostrará en la primera compilación y las compilaciones consecutivas no repetirán el comando RUN
del comando. Como solución alternativa, puede intentar --no-cache
bandera:
$ docker build -t nginx-test . --no-cache
El último método no es el mejor, pero a veces puede ser útil para la depuración, etc.
Resumen
Ejecutar comando dentro de un docker contenedor es sencillo y existen varios métodos para hacerlo. Es una tarea habitual de un administrador de Docker, por lo que conocer estos comandos resulta útil.
A continuación, conozca algunos de los Comandos Docker.