Docker - Comandos Básicos de Docker

Tutorial #2

Introducción

En este tutorial nos vamos a familiarizar con los comandos básicos de docker, concentrándonos exclusivamente en las capacidades que tiene docker para descargar imágenes, instanciar contenedores, detener y eliminar contenedores, entre otras características básicas.

Recordemos que basados en el tutorial anterior estamos utilizando una distribución Ubuntu GNU/Linux por lo que todos los comandos estarán precedidos del comando sudo. Si está trabajando en otro tipo de distribución GNU/Linux, o está trabajando como usuario root, es probable que no requiera utilizar el comando sudo.

En la primera parte del tutorial listaremos y explicaremos los comandos básicos de docker y al final se realizará un pequeño demo de práctica.

Comando pull

El comando pull permite descargar una imagen del registry que tenga configurado. Si es una instalación por defecto estaremos utilizando como registry hub.docker.com. A partir de la imagen descargada podemos instanciar diferentes contenedores o crear nuevas imágenes utilizando la misma como base.

Recordemos que un registry es un servicio que opera como repositorio de imágenes docker que comparten usuarios.

Para descargar una imagen, utilice el comando docker pull seguido del nombre de la imagen de interés.

$ sudo docker pull nombre-de-la-imagen

Comando run

El comando run permite iniciar un contenedor a partir de una imagen descargada. Si la imagen no se ha descargado previamente del registry, docker procede a descargarla antes de instanciar el contenedor (es decir, ejecuta un pull).

$ sudo docker run nombre-de-la-imagen

Comando ps

El comando ps lista todos los contenedores en ejecución.

$ sudo docker ps

El comando ps tiene diferentes opciones que podemos agregar con el operador guion. Por ejemplo, podemos utilizar el comando docker ps -a, lista todos los contenedores incluyendo aquellos que ya terminaron su ejecución, ya que por defecto docker ps sólo lista los contenedores en ejecución.

$ sudo docker ps -a

Comando stop

El comando stop permite detener un contenedor. Para esto requerimos el nombre asignado al contenedor. Cuando ejecutamos el comando run, docker asigna un ID y un nombre a nuestro contenedor, estos campos podemos visualizarlos al ejecutar el comando ps.

$ sudo docker ps
Para detener el contenedor ejecutamos el comando: 

$ sudo docker stop nombre-del-contenedor

Comando rm

Para remover un contendor utilizamos el comando rm, se requiera especificar el nombre del contenedor. Recordemos que con el comando ps se puede visualizar el nombre asignado.

$ docker rm nombre-del-contenedor

Verifique con el comando ps que el contenedor ya no esta disponible.

$ sudo docker ps -a

Comando images

Listar imagenes

$ sudo docker images

Comando rmi

Para remover una imagen descargada, primer liste las imágenes con el comando imagen y luego utilice el comando rmi para remove imagen de preferencia.

$ sudo docker images
$ sudo docker rmi nombre-de-la-imagen

Ejecución de comandos dentro de un contenedor

Para ejecutar un comando dentro de un contenedor, especifique luego del nombre del contenedor el comando de interés.

$ sudo docker run imagen comando

Ejemplo: Se descarga la imagen oficial de ubuntu, sé instancia un contenedor de ubuntu y se ejecuta el comando date, que retorna la fecha del sistema.

$ sudo docker run ubuntu date

Comando exec

El comando exec se utiliza para ejecutar programas o aplicaciones en contenedores que ya se están ejecutando.

$ sudo docker exec nombre-del-contenedor-en-ejecución comando-o-aplicación

Ejemplo: Ejecutemos el comando ps para listar todos los contenedores en ejecución, asumamos que tenemos un contenedor llamado inspiring_maxwell y queremos ejecutar el cat /etc/release para conocer la versión del sistema operativo del contenedor.

$ sudo docker ps -a
$ sudo docker exec inspiring_maxwell cat /etc/*release*

Comando run (Attach & detach)

Mientras trabajamos con un contenedor docker, a menudo necesitamos ejecutarlo en un modo interactivo. Aquí es donde adjuntamos los flujos estándar de entrada, salida o error de nuestra terminal al contenedor.

En otras ocasiones se requiere ejecutar un contenedor en segundo plano. Sin embargo, es posible que deseemos conectarnos a él más tarde para verificar su salida o errores o desconectar la sesión.

Ejecutar un contenedor en modo Attached, significa que no podemos volver a nuestro indicador de shell hasta que finalice el proceso en ejecución en el contenedor. Cuando el proceso finalice o sea terminado por nosotros, el contenedor detendrá su ejecución.

$ sudo docker run imagen

Para ejecutar un contenedor en modo Detached, podemos ejecutar simplemente el comando run con la opción -d, esto nos permitira seguir trabajando en el shell del sistema mientras el contenedor termina su ejecución.

$ sudo docker run -d imagen

Si deseamos realizar un attach a un contenedor que está ejecutándose en modo detached basta con ejecutar el comando run attach y especificar los primeros 4 dígitos del ID del contenedor, este ID lo podemos consultar con el comando ps.

$ sudo docker run attach primeros_4_digitos_id

Comando run (Modo interactivo)

El modo interactivo nos permite interactuar directamente con los procesos en ejecución dentro de un contenedor. Para esto utilizamos las opciones -it, la opción -i adjunta el flujo de entrada estándar (stdin) en el contenedor y la opción -t asigna una pseudo-terminal al proceso. Esto nos permite interactuar con el contenedor desde nuestra terminal.

$ sudo docker run-it imagen comando o aplicación

Ejemplo: Abrir un shell bash en un contenedor ubuntu

$ sudo docker run -it ubuntu /bin/bash

Demo

Para esta demo, descargaremos una imagen oficial de hub.docker.com. Seleccionaremos una imagen oficial, las imágenes oficiales sobre ofrecidas y mantenidas por los socios de docker (Fabricantes como Canonical o Red Hat, entre muchos otros).

Para el ejercicio yo seleccioné la imagen oficial de Python. Para descargarla ejecutemos el comando:

$ sudo docker pull python

Para instanciarla, ejecutemos el comando:

$ sudo docker run python

Liste los contenedores en ejecución con el comando:

$ sudo docker ps

Como pudo observar no hay ningún contenedor en ejecución, el contenedor finalizo su tarea por eso no está listado como un resultado del comando ps. Ejecute ps -a

$ sudo docker ps -a

Como puede verificar el estado del contenedor es exited, se ejecutó el comando python3 y se asignó un ID y un nombre aleatorio al contenedor. En mi caso, cranky_curran.

Vamos a instanciar un nuevo contenedor a partir de la misma imagen. En este caso vamos a abrir una terminal bash en este contenedor utilizando el modo interactivo.

$ sudo docker run -it python bash

Como podemos observar el shell cambio, en mi caso puedo observar un shell que inicia con el promt en root@e5b2c4984a4c:/#. Ejecute el comando:

# cat /etc/*release*

La salida del comando nos permite validar que este contenedor oficial de Python está soportado en Debian GNU/Linux 11 (bullseye).

PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Para cerrar el modo interactivo del contenedor, ejecute el comando exit. Si desea, puede ejecutar el comando python para validar el entorno de ejecución de este.

Ejecute el comando ps. Puede validar que el estado del contenedor es exited.

Ahora vamos a crear una nueva instancia de este contenedor, pero vamos a realizar un par de ajustes al comando run. Primero lo vamos a correr en modo detached (vamos a enviar la ejecución a background). Luego vamos a ejecutar el comando sleep con el parámetro 30. Sleep es un comando que se utiliza para temporizar un intervalo determinado.

$ sudo docker run -d python sleep 30

Luego procedemos a ejecutar el comando ps. Vamos a ver que la salida nos muestra que este contenedor está en ejecución, que está ejecutando el comando sleep por 30 segundos y adicionalmente, nos mostrara hace cuanto tiempo está en ejecución.

$ sudo docker ps

Ejecute el comando ps repetidamente, al pasar los 30 segundos podrá observar que el contenedor ya no está en ejecución.

Ahora vamos a ejecutar nuevamente el contenedor con el comando sleep por 500 segundos. Como puede ver es un intervalo de ejecución muy largo. Esto lo vamos a utilizar para probar el comando stop y detener la ejecución del contenedor. Ejecute los siguientes comandos y valide el resultado del comando stop.

$ sudo docker ps
$ sudo docker run -d python sleep 500
$ sudo docker ps
$ sudo docker stop nombre-del-contendor (en mi caso: sweet_mendeleev)
$ sudo docker ps
$ sudo docker ps -a

Si se fija con detalle los contenedores ejecutados previamente tienen status exited con código 0, mientras que algunos de los contenedores ejecutados recientemente tienen código 127 y 137. Consulte el significado de estos códigos.

Ahora vamos a borrar o remover todos los contenedores creados previamente. Para esto, utilice el comando ps para listar los contenedores y utilice el comando remove las veces que sea necesario para eliminar los diferentes contenedores creados previamente.

Ejemplo: Basado en los nombres autogenerados en mi máquina, valide los nombres de sus contenedores con el resultado de la ejecución del comando ps.

Primero vamos a borrar dos contenedores usando sus nombres:

$ sudo docker ps -a 
$ sudo docker rm inspiring_lumiere 
$ sudo docker rm sweet_mendeleev
$ sudo docker ps -a

Ahora, vamos a borrar tres contenedores usando sus IDs y utilizando solo una linea de comando:

$ sudo docker ps -a 
$ sudo docker rm  e0 56 8a
$ sudo docker ps -a

Como puede observar solo usamos los dos primeros caracteres del ID del contenedor, en este caso e0 corresponde al ID e03f68e72c1a y docker internamente identifica a qué valor hacemos referencia. En una sola línea especificamos tres IDs abreviados.

Procedemos a listar las imágenes descargadas y disponibles localmente. Para esto ejecuté el comando images:

$ sudo docker images

Para eliminar una imagen descargada, utilice el comando rmi. En este caso vamos a eliminar la imagen docker/whalesay que utilizamos en el tutorial anterior.

$ sudo docker rmi docker/whalesay

Nota: Recuerde que la imagen no puede estar en uso si desea borrarla. Es necesario eliminar previamente los contenedores que utilizan dicha imagen.

Finalmente, vamos a realizar un ajuste más al comando run y vamos a probar el comando exec.

Al comando run le vamos a agregar la opción --name para asignarle un nombre a nuestro contenedor, y no utilizar un nombre aleatorio asignado por docker.

$ sudo docker run --name mi-contenedor -d python sleep 120
$ sudo docker ps -a

Con el comando ps puede listar el contenedor, validar su nombre y su ejecución por dos minutos.

Ahora vamos a ejecutar un comando sobre el contenedor en ejecución, para esto vamos a utilizar el comando exec. Si el contenedor no está en ejecución, no podremos ejecutar nada con exec.

$ sudo docker exec mi-contenedor cat /etc/*release*

En este ejercicio ejecutamos el comando cat /etc/*release* dentro del contenedor de nombre mi-contenedor.

Did you find this article valuable?

Support Jesse Padilla by becoming a sponsor. Any amount is appreciated!