Saltar al contenido principal

Ejecutar un contenedor (docker run y opciones comunes)

En esta sección, vamos a ver cómo arrancar nuestros primeros contenedores, las opciones más comunes para hacerlo. Además de cómo ver los detalles de un contenedor en ejecución, ejecutar un proceso en segundo plano, mapear puertos y entender como un contenedor se comporta como un proceso.

Dentro vídeo: https://youtu.be/ImLoqbY9DNA

Iniciar un contenedor

Arrancar un contenedor

Para arrancar un contenedor, utilizamos el comando docker run. Este comando, nos permite arrancar un contenedor a partir de una imagen. Su sintaxis básica es la siguiente:

docker run <imagen>

Por ejemplo, si queremos arrancar un contenedor nginx (un conocido servidor web), podríamos hacerlo con el siguiente comando:

docker run nginx

Aunque no hayamos descargado una imagen, Docker se encargará de buscar la imagen en Docker Hub, descargarla y arrancar el contenedor de forma automática.

Podemos consultar los contenedores que tenemos en ejecución con el comando docker ps. Por ejemplo, si queremos ver los contenedores que tenemos en ejecución, podríamos hacerlo con el siguiente comando:

docker ps

Además, podemos ver todos los contenedores, tanto los que están en ejecución como los que están parados, con el comando docker ps -a.

Opciones comunes de docker run

Junto al comando docker run, podemos utilizar una serie de opciones para personalizar el comportamiento del contenedor. Algunas de las opciones más comunes son:

  • -d: Arranca el contenedor en segundo plano.
  • -p: Mapea un puerto del contenedor al puerto del host.
  • -v: Mapea un volumen del host al contenedor.
  • --name: Asigna un nombre al contenedor.
  • --rm: Elimina el contenedor al pararlo.
  • -e: Define una variable de entorno.
  • --env-file: Define un archivo de variables de entorno.

Vamos a ver varios ejemplos, para entender cómo funcionan estas opciones:

ID y detalles del contenedor

Con los contenedores que hemos ejecutado previamente, haciendo un docker ps, podemos ver varios valores interesantes. Entre ellos, los más destacados son el ID y el nombre del contenedor, pues nos permitirán referenciarlos en otros comandos, como el logs, attach, stop, commit, etc.

Esta es la salida de un comando docker ps:

❯ docker ps                                                                                        
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9267a9edf3d nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp vigorous_noether

En este caso, el ID del contenedor es e9267a9edf3d y el nombre del contenedor es vigorous_noethe. Además, podemos ver la imagen que utiliza, el comando que ejecuta, cuando se creó, el estado, los puertos que tiene mapeados, etc.

Proceso del contenedor y ejecución

Por defecto, cuando ejecutamos un contenedor en docker, la salida del terminal que vemos, es la salida del contenedor. Es decir, el log del proceso que se está ejecutando dentro. Si estamos depurando puede ser útil verlo pero no siempre es así.

Si queremos arrancar un contenedor en segundo plano, podemos utilizar la opción -d. Esto hará que se ejecute el contenedor sin mostrar la salida en el terminal.

docker run -d nginx

Si hemos lanzado un contenedor en segundo plano, podemos ver la salida del contenedor con el comando docker logs. Por ejemplo, si queremos ver la salida del contenedor anterior, podríamos hacerlo con el siguiente comando:

docker logs <id_contenedor>

También podríamos seguir la salida en tiempo real con el comando docker logs -f.

También podríamos acoplarnos al contenedor y ver la salida en tiempo real con el comando docker attach. Por ejemplo, si queremos ver la salida del contenedor anterior en tiempo real, podríamos hacerlo con el siguiente comando:

docker attach <id_contenedor>

Además del ID también podríamos utilizar el nombre del contenedor para referenciarlo.

Por último, si hemos ejecutado un contenedor sin la opción -d, podemos hacer "Control + c" para parar el contenedor y volver al terminal o, si no queremos pararlo, podemos hacer "Control + p + q" para desacoplarnos del contenedor sin pararlo.

Política de reinicio

Por defecto, cuando un contenedor falla o termina su proceso, Docker no lo reinicia por defecto. Si queremos que un contenedor se reinicie automáticamente, podemos utilizar la opción --restart. Esta opción nos permite definir una política de reinicio. Algunas de las políticas más comunes son:

  • no: No reinicia el contenedor.
  • always: Reinicia el contenedor siempre.
  • unless-stopped: Reinicia el contenedor siempre que no lo paremos.
  • on-failure: Reinicia el contenedor solo si falla.
  • on-failure:<n>: Reinicia el contenedor solo si falla n veces.

Por ejemplo, si queremos que un contenedor se reinicie siempre que falle o se reinicie el servidor anfitrión, podríamos hacerlo con el siguiente comando:

docker run --restart always nginx

Mapeo de puertos

En este ejemplo, lo que estamos ejecutando es un servidor web. Como ya remarcamos en la introducción, un contenedor se ejecuta en un entorno aislado pero, si que tenemos varios mecanismos para comunicarnos con el contenedor. Uno de ellos es el mapeo de puertos.

Podemos utilizar el contenedor de nginx como ejemplo, si hacemos una petición web o accedemos desde el navegador a localhost:80 (localhost o la IP de tu máquina si lo estás haciendo en un servidor externo), no podremos acceder a él.

El parámetro -p, mencionado anteriormente, nos permite mapear un puerto del host a un puerto del contenedor. En este caso, si queremos acceder al servidor web que hemos arrancado, necesitamos mapear el puerto 80 del contenedor un puerto del host. En este caso he optado por el 8080, ya que en windows y mac el 80 a veces esta en uso. Para ello, podemos utilizar el siguiente comando:

docker run -d -p 8080:80 nginx

Ahora si, si accedemos a localhost:8080, podremos ver el servidor web de nginx respondiendo perfectamente. Esto es porque el puerto 8080 de nuestro host está mapeado al puerto 80 del contenedor y docker se encargará de redirigir las peticiones al contenedor. Esto funciona con cualquier puerto o cualquier aplicación, no solo con servidores web.

Por ejemplo, mapear varios puertos:

docker run -d -p 8080:80 -p 8081:81 nginx

También podríamos mapear un rango de puertos, por ejemplo del 8080 al 8085 incluidos:

docker run -d -p 8080-8085:80 nginx

Con esto, habríamos terminado lo más básico de la ejecución de contenedores. En la siguiente sección, veremos cómo parar, reiniciar y eliminar contenedores. Los parámetros de volúmenes y variables de entorno los veremos en secciones posteriores dedicadas completamente a ellos.


Volver al índice

X

Graph View