Docker es una herramienta Open Source que nos permite realizar una virtualización liviana, con la que poder empaquetar entornos y aplicaciones que posteriormente podremos desplegar en cualquier máquina que disponga de la tecnología Docker instalado en su sistema. Para ello, Docker extiende LXC (Linux Containers), que es un sistema de virtualización que permite crear múltiples sistemas totalmente aislados entre sí, sobre la misma máquina o sistema anfitrión.
La principal diferencia entre una máquina virtual y un contenedor de Docker, reside en que la máquina virtual necesita contener todo el sistema operativo, mientras que un contenedor Docker aprovecha el sistema operativo sobre el cual se ejecuta. El contenedor comparte el Kernel del sistema operativo anfitrión, e incluso parte de sus bibliotecas.
Qué es Docker
Docker es una plataforma de software que permite a los desarrolladores crear, distribuir y ejecutar aplicaciones de manera rápida y eficiente en entornos aislados llamados contenedores. Estos contenedores encapsulan todo lo necesario para que una aplicación funcione, incluyendo el código, las bibliotecas, las herramientas y las configuraciones, lo que facilita la portabilidad y la implementación en diferentes entornos de desarrollo y producción.
La principal ventaja de Docker está en su tecnología de contenedores, que ofrece una alternativa ligera y eficiente a las máquinas virtuales tradicionales. Mientras que las máquinas virtuales virtualizan todo el hardware de un servidor y ejecutan múltiples sistemas operativos independientes, los contenedores Docker comparten el mismo núcleo del sistema operativo y solo virtualizan los recursos a nivel de sistema de archivos y procesos. Esto los hace más rápidos, eficientes y portátiles que las máquinas virtuales.
Docker utiliza un formato de contenedor estándar llamado Docker Image, que incluye todo lo necesario para ejecutar una aplicación de manera independiente. Las imágenes Docker se crean a partir de archivos de configuración llamados Dockerfile, que especifican los pasos necesarios para construir la imagen, incluyendo la instalación de dependencias, la configuración del entorno y la ejecución de comandos específicos.
Una vez que se ha creado una imagen Docker, se puede distribuir y compartir a través de un repositorio centralizado llamado Docker Hub, que actúa como un almacén de imágenes Docker públicas y privadas. Los desarrolladores pueden descargar y ejecutar imágenes Docker desde Docker Hub en cualquier entorno compatible con Docker, lo que facilita la implementación rápida y escalable de aplicaciones en la nube.
Además de la distribución de aplicaciones, Docker también facilita la gestión y el orden de contenedores en entornos de producción a través de herramientas como Docker Compose y Docker Swarm. Estas herramientas permiten a los desarrolladores definir y gestionar la infraestructura de contenedores, lo que facilita la escalabilidad, la disponibilidad y la tolerancia a fallos de las aplicaciones distribuidas.
Desde el punto de vista del consumo de procesador y de la memoria RAM, los contenedores hacen un uso mucho más eficiente del sistema anfitrión, con lo que únicamente usarán la memoria y la capacidad de cómputo que estrictamente necesiten. Eso es debido a que el contenedor del sistema comparte el Kernel, y parte de las bibliotecas como hemos mencionado anteriormente.
Ventajas y desventajas
Dentro de este software nos podemos encontrar pros y contras de uso, que vamos a repasar de forma resumida:
Ventajas:
- Portabilidad: Los contenedores creados con Docker son independientes del sistema operativo y el hardware, lo que permite ejecutar aplicaciones de manera consistente en cualquier entorno, ya sea local, en la nube o en cualquiera de las diferentes plataformas.
- Aislamiento: Docker permite que cada aplicación funcione en su propio contenedor evitando conflictos entre proyectos que utilicen diferentes versiones de bibliotecas o configuraciones, algo que puede resultar muy útil.
- Eficiencia: Al compartir el kernel del sistema operativo del host, los contenedores son mucho más ligeros que las máquinas virtuales, lo que reduce el uso de recursos.
- Rapidez: Los contenedores se inician en segundos, lo que acelera significativamente el proceso en comparación con las máquinas virtuales, que suelen tardar minutos en arrancar.
Desventajas:
- Curva de aprendizaje: Para quienes no están familiarizados con herramientas de virtualización o despliegue esta herramienta puede suponer un problema, sobre todo en sus inicios, por lo que tendremos que tener paciencia.
- Aislamiento relativo: Pese a que también lo añadimos a sus ventajas, el aislamiento supone un problema, y es que, si todos comparten el kernel del sistema operativo del host, significa que un fallo o vulnerabilidad en este mismo podría afectar a todos los contenedores a la vez.
- Persistencia de datos: Si no se configuran correctamente los volúmenes o sistemas de almacenamiento externos, los datos pueden perderse al detener o eliminar un contenedor, por lo que deberemos tener precaución con esto.
- Complejidad en sistemas grandes: Si el sistema es complejo, es posible que se requieran herramientas adicionales como Kubernetes para poder gestionar todo de forma correcta.
Estas serían las ventajas y desventajas principales, aunque existen más, dependiendo del uso particular de cada usuario.
Imágenes y Contenedores
Los términos que hay que manejar con Docker son principalmente 2, las imágenes y contenedores. Las imágenes se podrían ver como un componente estático, pues no son más que un sistema operativo base, con un conjunto de aplicaciones empaquetadas. Un contenedor es la instanciación o ejecución de una imagen, pudiendo ejecutar varios contenedores a partir de una misma imagen.
Instalación de Docker
Nos dirigiremos a la página principal Docker y descargaremos la versión correspondiente para nuestro sistema operativo. En mi caso descargaré la versión de MacOS. Tan solo tendremos que arrastrar el icono de Docker a nuestra carpeta de Aplicaciones.
Cuando iniciemos por primera vez Docker, tendremos que poner nuestra clave de inicio al sistema por cuestiones de seguridad.
Una vez cumplimentados los pasos de instalación y abriremos una ventana terminal. En esta ejecutaremos el comando Docker y nos aparecerá la lista de opciones.
Pasos para crear virtualización ligera
Una vez tengamos instalado correctamente Docker vamos a empezar a trastear con él, para ello vamos a Docker Hub, que es un repositorio de imágenes pre-configuradas listas para usar (en otras palabras, un GitHub de imágenes). DockerHub dispone de las imágenes oficiales de postgresql, redis, mysql, ubuntu, rabbitmq, sonarqube, mongodb, además de una multitud de imágenes que los usuarios van creando y subiendo al repositorio.
En este ejemplo vamos a usar la imagen oficial de sonarqube, para crear un contenedor con Sonar instalado. En el repositorio de sonarqube encontraremos información relativa a la imagen y de cómo se usa, más o menos lo que vamos a describir a continuación.
El primer paso sería descargarnos la imagen:
docker pull sonarqube
Podemos listar las imágenes que tenemos en nuestro equipo con el siguiente comando:
docker images
Una vez tenemos la imagen, ya estamos en disposición de instanciar un contenedor a partir de ella. Este comando lo que realiza es levantar un contenedor con los siguientes parámetros:
docker run -d --name sonarqube -p 9000:9000 sonarqube
- -d: Levanta el contenedor en segundo plano
- –name: Nombre asociado al contenedor
- -p: Mapeamos el puerto 9000 de nuestro equipo con el 9000 del contenedor
Podemos comprobar los contenedores que están levantados:
docker ps
Para acceder al sonar instalado en el contenedor nos bastaría con abrir un al navegador con la URL https://localhost:9000.
docker inspect
Ahora ya podemos acceder a nuestro Sonar, tal y como podéis ver a continuación:
¿Y si necesitamos tener otro Sonar? Pues nada, instanciamos de nuevo la imagen para crear otro contenedor.
Sólo necesitamos cambiar el nombre y el mapeo de puertos, volvemos a comprobar los contenedores activos … y ahí tenemos nuestros dos contenedores:
docker run -d --name sonarqube2 -p 7000:9000 sonarqube
docker ps
Podemos acceder al nuevo sonar:
Podemos parar un contenedor con el comando «docker stop sonarqube», tal y como podéis ver a continuación:
Vemos como sólo quedaría activo sonarqube2, podemos listar los contenedores independientemente de su estado con:
docker ps -a
Para borrar un contenedor deberíamos ejecutar el siguiente comando:
docker rm sonarqube
docker rm sonarqube2
Y debes prestar mucha atención. Básicamente porque los contenedores son efímeros por diseño. Si eliminas un contenedor con docker rm sin haber configurado un volumen, ten en cuenta que todos los datos y cambios que contenía se perderán para siempre. Así que si queires evitarlo, resulta clave llegar a usar volúmenes para la persistencia de datos, como explicamos en la sección ‘Gestionar redes y volúmenes’.
Una de las opciones que tendríamos si queremos que los cambios que realicemos al contenedor sean permanentes, sería la de generar una imagen a partir del contenedor, para ello haríamos lo siguiente:
docker commit -m "" -a "" :
Ahora bien, ten en cuenta que exponer puertos directamente con -p 9000:9000 puede abrir una brecha de seguridad si el contenedor se ejecuta en un servidor público. Por esto mismo, para entornos seguros es importante limitar el acceso a IPs específicas. Al igual que resulta clave usar un firewall para proteger el puerto expuesto. Y, en general, todo pasa por nunca exponer puertos de servicios sensibles (como bases de datos) directamente a Internet.
Dockerfile
En este último apartado vamos a ver cómo crear una nueva imagen a través de un fichero llamado Dockerfile. Un fichero Dockerfile es simplemente un fichero de texto que nos permite definir las instrucciones a seguir para construir una imagen, en otras palabras, es como una receta para crear nuestras imágenes, que servirán de forma posterior para correr nuestros contenedores.
En este ejemplo vamos a crear una imagen con un SO Ubuntu y le vamos a instalar el servidor web Apache, para ello contamos con un Dockerfile:
FROM ubuntu
MAINTAINER Redes Zone
ENV http_proxy https://user:pass@proxy/
ENV https_proxy https://user:pass@proxy/
RUN apt-get update
RUN apt-get install apache2 -y
RUN echo "Apache with Docker
" > /var/www/html/index.html
EXPOSE 80
ENTRYPOINT apache2ctl -D FOREGROUND
Vamos a describir los comandos del Dockerfile:
- FROM : Indica la imagen que tomamos como base, en este caso la imagen oficial de Ubuntu
- MAINTAINER: Especifica el autor de la imagen.
- ENV: Definimos unas variables de entorno en la imagen base.
- http_proxy https://user:pass@proxy/ — Definimos la variable http_proxy
- https_proxy https://user:pass@proxy/ — Definimos la variable https_proxy
- RUN: Ejecuta una sentencia sobre la imagen base
- apt-get update : actualiza los repositorios de Ubuntu
- apt-get install apache2 -y : Instala el apache
- echo “
Apache with Docker
” > /var/www/html/index.html : crea un fichero index.html
- EXPOSE: Exponemos el puerto 80 del contenedor para que pueda ser mapeado por la máquina anfitrión.
- ENTRYPOINT: Indicamos que se ejecute apache2ctl -D FOREGROUND cada vez que arranquemos el contenedor.
Una vez tengamos definido el fichero Dockerfile, vamos a construir la imagen:
docker build –t redeszone/apache
Le estamos indicando a docker que construya una imagen con el nombre redeszone/apache a partir del DockerFile que se encuentra en la misma ruta donde ejecutamos el comando.
Listamos las imágenes disponibles:
Ya estamos en disposición de arrancar un contenedor a partir de la imagen que hemos creado:
docker run --name apache1 -d -p 90:80 redeszone/apache
Arrancamos un contenedor, que llamaremos apache1, mapeando el puerto 80 del contenedor con el 90 de nuestra máquina, a partir de la imagen redeszone/apache.
Comandos Docker para construir, ejecutar y gestionar contenedores
Si estás empezando con Docker o ya llevas tiempo usándolo, seguro que más de una vez te has sentido algo perdido con tanto comando. A mí también me pasó. Por eso he preparado esta guía donde te explico, con un lenguaje claro y desde la experiencia, los 18 comandos más útiles para sacarle todo el partido a Docker. Docker es una herramienta que uso cada día, tanto para montar entornos de desarrollo como para desplegar servicios. Al principio, cuesta entender cómo se organiza todo: contenedores, imágenes, volúmenes, redes… Pero con unos cuantos comandos bien aprendidos, todo se vuelve más sencillo y rápido.
En esta lista te muestro los comandos esenciales que realmente uso, no solo los que salen en los manuales. Te explico para qué sirve cada uno, cómo lo uso y te doy algunos consejos prácticos.
Comandos básicos que necesitas dominar
Si estás arrancando con Docker, estos son los primeros comandos que yo aprendí y que sigo usando a diario.
- «docker –version» y «docker info«: El primero te dice qué versión de Docker tienes instalada. El segundo te da un resumen completo del estado de tu sistema Docker: cuántos contenedores tienes, cuántas imágenes, en qué sistema estás trabajando, etc. Yo lo uso mucho cuando algo no arranca y necesito saber si todo está en orden.
- «docker pull
«: Sirve para descargar imágenes desde Docker Hub. Por ejemplo, si quiero la imagen oficial de Ubuntu, hago: «docker pull ubuntu». Si no pones una etiqueta, por defecto se baja la versión «latest». - «docker run
«: Este comando lanza un contenedor a partir de una imagen. Por ejemplo: «docker run -it ubuntu». Esto me abre un terminal dentro de Ubuntu. Es uno de los comandos que más uso para hacer pruebas rápidas. - docker ps y docker ps -a: «docker ps» te muestra los contenedores en ejecución. Si añades -a, verás también los que están parados. Muy útil cuando tienes varios contenedores y no recuerdas cuál es cuál.
- «docker stop
» y «docker start «: Para parar y volver a arrancar contenedores. A veces no quiero borrarlos, solo pausarlos temporalmente. Estos comandos me permiten hacerlo sin perder nada.
Cómo trabajar con imágenes y contenedores
Aquí entramos en los comandos que uso para construir mis propias imágenes y gestionar contenedores más allá de lo básico.
- «docker build -t
» : Construyo mis propias imágenes con este comando. En mi directorio tengo un Dockerfile y al ejecutar «docker build -t miapp» se genera una nueva imagen lista para usar. - «docker images«: Muestra una lista de todas las imágenes que tengo en mi sistema. Lo consulto para saber si ya tengo descargada una imagen antes de volver a bajarla.
- «docker rmi
«: Sirve para eliminar imágenes que ya no necesitas. Yo lo uso cuando empiezo a quedarme sin espacio en el disco. - «docker exec -it
«: Este me encanta. Me permite ejecutar comandos dentro de un contenedor ya en marcha. Por ejemplo: «docker exec -it miapp bash». Así puedo entrar a revisar logs o cambiar cosas sin tener que reiniciar nada. - «docker logs
«: Muestra los logs de un contenedor. Ideal para saber si tu app ha petado o si está arrancando correctamente. - «docker rm
«: Elimina contenedores que ya no usas. Ojo: solo funciona con contenedores parados, si no, primero hay que hacer «docker stop». - «docker restart
«: Para reiniciar un contenedor en caliente. Lo uso mucho en desarrollo, cuando cambio algo en la configuración.
Gestionar redes y volúmenes como un profesional
Una vez que tienes más de un contenedor, toca conectar y compartir datos entre ellos. Aquí entran las redes y los volúmenes.
- «docker network ls» y «docker network create«: «docker network ls» muestra las redes disponibles. Y con «docker network create nombre» creo redes personalizadas. Esto lo uso, por ejemplo, cuando tengo una base de datos y una API y quiero que solo hablen entre ellas.
- «docker volume ls» y «docker volume create«: Los volúmenes son clave para mantener datos, aunque borres el contenedor, «docker volume create» me permite crear uno, y luego puedo usarlo así: «docker run -v midatos:/datos alpine». De esa forma, aunque el contenedor se elimine, los datos siguen ahí.
Para la persistencia de datos, lo cierto es que una práctica recomendada es utilizar el flag –mount por su sintaxis más explícita y versátil. No obstante, hay que dejar claro que -v sigue siendo igual de funcional si lo prefieres. Ejemplo a tener en cuenta:
- Sintaxis más clásica (-v): docker run -v mi_volumen:/app/datos mysql
- Sintaxis más recomendada actualmente (–mount): docker run –mount source=mi_volumen,target=/app/datos mysql
La sintaxis –mount permite especificar opciones adicionales como el tipo de montaje (volume, bind) y es el estándar en entornos de Docker Swarm.’
Para tenerlo todo limpio y en orden
A veces acumulamos cosas y el sistema se llena. Aquí algunos comandos extra que me han salvado.
- «docker container prune«: Borra todos los contenedores parados. Muy útil si llevas tiempo probando cosas y todo está desordenado.
- «docker image prune«: Hace lo mismo, pero con las imágenes que ya no se usan. Libera bastante espacio si lo usas regularmente.
Automatiza con Docker Compose
Cuando tu proyecto tiene varios contenedores, lo mejor es usar Docker Compose. Aquí van los comandos que no pueden faltar.
- «docker-compose up«: Lanza todos los servicios definidos en el archivo «docker-compose.yml». Yo suelo usarlo con -d (modo demonio) para que todo corra en segundo plano:
«docker-compose up -d». - «docker-compose down«: Para parar y limpiar todo lo que se ha creado con up: contenedores, redes, etc. Ideal para reiniciar desde cero.
Consejos que me han funcionado
Más allá de los comandos, te dejo algunos consejos que aplico para no volverme loco con Docker:
- Etiqueta siempre tus imágenes con -t. Así sabrás qué versión estás usando.
- No trabajes siempre como root. Docker puede ejecutarse con usuarios específicos.
- Haz limpieza regularmente. Un simple docker system prune (con cuidado) te puede ahorrar muchos GB de espacio en disco.
- Usa Compose para proyectos complejos. Evita que tengas que recordar comandos kilométricos.
- Guarda tus Dockerfiles en control de versiones. Así puedes volver atrás si rompes algo.
Estos comandos me han permitido pasar de ser un principiante que copiaba ejemplos sin entenderlos a poder montar entornos completos con confianza. Docker no es difícil, solo hay que perderle el miedo y practicar. Empieza por los básicos, y poco a poco te irás sintiendo más cómodo. Y lo más importante: no te obsesiones con memorizar. Ten esta guía a mano y ve consultándola cuando lo necesites. A mí me ha funcionado y espero que a ti también te sirva.
