Opciones del comando run de Docker run:

Docker runAunque en el artículo de Primeros pasos con Docker  vimos el comando “run”, en este artículo vamos a estudiar sus opciones. En primer lugar vamos a usar el comando “docker run redis” para ejecutar el contenedor que ejecuta un servicio redis, pero una versión anterior, por ejemplo, la 4.0. Para eso hay que especificar la versión separada por dos puntos. Esto se llama una etiqueta o tag: “docker run redis:4.0”.

Si no se especifica ninguna etiqueta, se considerará que la etiqueta predeterminada es la última que depende de los autores de ese software. Para saber información sobre versiones y qué es lo último hay que acudir a  https://hub.docker.com/. Hay que buscar una imagen y se verán todas las etiquetas compatibles en su descripción. Cada versión del software puede tener múltiples etiquetas cortas y largas asociadas. 

inputs o entradas

Supongamos que tengo una aplicación simple que cuando se ejecuta solicita mi nombre y al ingresar mi nombre imprime un mensaje de bienvenida. Si tuviera que dockerizar esta aplicación y ejecutarla como un contenedor de docker, no esperaría el mensaje. Simplemente imprime lo que se supone que imprime la aplicación en la salida estándar. Esto se debe a que, por defecto, el contenedor acoplable no escucha una entrada estándar. Aunque esté conectado a su consola, no puede leer ninguna entrada suya. No tiene una terminal para leer las entradas. Se ejecuta en un modo no interactivo.

Si se desea proporcionar una entrada se debe asignar la entrada estándar del host al contenedor utilizando el parámetro -i. El parámetro -i es para el modo interactivo y cuando se ingresa mi nombre imprime la salida esperada, pero todavía falta algo cuando ejecutamos la aplicación. Nos pidió nuestro nombre, pero cuando se ejecuta falta ese mensaje, aunque parece haber aceptado la entrada. Esto se debe a que el mensaje de solicitud se muestra en la terminal y no nos hemos conectado a la terminal de contenedores. Para esto, hay que usar la opción -t también. Entonces, con la combinación de -i y -t ahora estamos conectados al terminal, así como al modo interactivo en el contenedor: “docker -it run <imagen>”

Asignación de puertos

Otra de las opciones del comando run de Docker es la que permite la asignación de puertos o la publicación de puertos en los contenedores. Volvamos al ejemplo en el que estamos en una aplicación web simple en un contenedor Docker. El host donde está instalado Docker se llama host Docker. Cuando ejecutamos una aplicación web en un contenedor se asigna una dirección IP dentro del host Docker (por ejemplo la 172.17.0.2) y escucha en un puerto determinado.

Se podría utilizar la IP del contenedor pero es una IP interna y sólo es accesible dentro del host del contenedor. Si se abre un navegador desde el host del contenedor se puede acceder, pero si abre un navegador desde el host del ordenador que ejecuta Docker no se podrá. Para acceder hay que ir a la IP del host de Docker y haber mapeado el puerto dentro del contenedor docker a un puerto libre en el host Docker. 

Ejemplo

Supongamos que vamos a crear 3 contenedores de una aplicación web que escucha por el puerto 5000 y dos contenedores mysql que escuchan por el puerto 3306. Cada uno de los 5 contenedores tendrá su IP dentro del host de Docker, pero las tres webs escucharan por el puerto 5000 y las dos bases de datos por el puerto 3306. Para acceder a cada contenedor desde fuera del host Docker hay que mapear los puertos de cada una de las aplicaciones. Para esto se utiliza el parámetro -p de esta manera: “docker run -p <puerto docker>:<puerto aplicacion< <imagen>”. En el ejemplo de las 5 aplicaciones sería:

  • web1: docker run -p 80:5000 webapp
  • web2: docker run -p 8000:5000 webapp
  • web3: docker run -p 8001:5000 webapp
  • mysql1: docker run -p 3306:3306 mysql
  • mysql2: docker run -p 8306:3306 mysql

Con esto, para que el usuario pueda acceder a cualquier aplicación dockerizada, solo tiene que ir a la IP del host de Docker y el puerto mapeado. Por lo tanto, puede ejecutar tantas aplicaciones como quiera y asignarlas a tantos puertos como desee. Y, por supuesto, no puede asignar al mismo puerto en el host Docker más de una vez.

Persistencia de los datos en el contenedor de Docker.

Supongamos que queremos ejecutar un contenedor mysql. Cuando se crean bases de datos y tablas, los archivos de datos se almacenan en location /var/lib/mysql dentro del contenedor docker. El contenedor de Docker tiene su propio sistema de archivos aislado y cualquier cambio en cualquier archivo ocurre dentro del contenedor. Si se vuelcan muchos datos en la base de datos, y se elimina el contenedor mysql también se eliminan todos los datos en su interior. Si se desea conservar los datos, lo mejor es asignar un directorio de fuera del contenedor.

Podemos crear un directorio llamado /opt/datadir y asignarlo a /var/lib/mysql dentro del contenedor docker usando la opción -v y especificando el directorio en el host docker seguido de dos puntos y el directorio dentro del contenedor docker. De esta manera, cuando se ejecute el contenedor de Docker, montará implícitamente el directorio externo en una carpeta dentro del contenedor de Docker. De esta manera, todos los datos ahora se almacenarán en el volumen externo en el directorio /opt/data y, por lo tanto, permanecerán incluso si elimina el contenedor: “docker run -v /opt/datadir:/var/lib/mysql mysql”

El comando “docker ps” está bien para obtener detalles básicos sobre contenedores, como sus nombres y el ID, pero si queremos ver detalles adicionales sobre un contenedor específico, es mejor usar el comando “docker inspect” y proporcionar el nombre del contenedor o el ID. Devuelve todos los detalles de un contenedor en formato JSON, como el estado, los montajes, los datos de configuración, la configuración de red, etc. Recuerde usarlo cuando sea necesario para encontrar detalles en un contenedor.

Finalmente, para ver los registros de un contenedor que se ejecuta en segundo plano se utiliza el comando “docker logs” con el ID. del contenedor o el nombre