Este tutorial está diseñado para guiar a quienes desean aprender más acerca de Docker. Es ideal para un nivel medio.
Docker es una plataforma de contenedores líder que simplifica la construcción, despliegue y ejecución de aplicaciones en entornos aislados y portables. Esta guía de nivel intermedio profundiza en la creación de imágenes optimizadas con Dockerfile (incluyendo Multi-stage builds y caching), el manejo de la persistencia de datos con Volúmenes, la configuración de redes para la comunicación entre contenedores, la orquestación de aplicaciones multi-servicio con Docker Compose, la gestión de imágenes en Registros (como Docker Hub), y una introducción a conceptos de orquestación a mayor escala y seguridad básica de contenedores. Permite llevar las aplicaciones contenedorizadas a entornos de producción y gestionar infraestructuras de desarrollo más complejas.
El 'Hola, mundo' en Docker consiste en ejecutar un contenedor simple basado en una imagen mínima que imprime un mensaje.
docker run hello-world
Resultado:
Hello from Docker!
This message shows that your installation appears to be working correctly.
Familiarizarse con estos comandos es esencial para interactuar eficientemente con Docker:
docker version && docker info
docker ps
docker ps -a
docker images
docker run -d --name mi-web -p 80:80 mi_imagen_web
docker run -d -v mi_volumen_datos:/app/data mi_imagen_app
docker run -d --network mi_red_interna mi_imagen_servicio
docker build -t mi_usuario/mi_app:1.0 .
# Contenido de Dockerfile:
FROM node:lts as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY .
RUN npm run build
FROM node:lts-slim
WORKDIR /app
COPY --from=builder /app/dist .
CMD ["node", "server.js"]
docker stop id_o_nombre
docker restart id_o_nombre
docker rm id_o_nombre
docker rmi nombre_imagen_o_id
docker inspect id_o_nombre
docker logs id_o_nombre
docker exec -it id_o_nombre bash
docker push mi_usuario/mi_app:1.0
docker volume create nombre_volumen
docker volume ls
docker volume prune
docker network create mi_red_privada --driver bridge
docker network ls
docker compose up -d --build
docker compose stop
docker compose down
Comprender estos conceptos fundamentales te ayudará a dominar Docker de forma más organizada y eficiente:
Dockerfile (Instrucciones, Capas, Cache):
El archivo de texto que contiene las instrucciones para construir una imagen Docker. Cada instrucción (`FROM`, `RUN`, `COPY`, `CMD`, `ENTRYPOINT`, `EXPOSE`, `WORKDIR`, `ENV`, `ARG`, `USER`, etc.) crea una nueva capa en la imagen. Docker utiliza un sistema de cache basado en el contenido de las capas para acelerar las construcciones futuras.
Imágenes y Contenedores:
La diferencia fundamental: una Imagen es una plantilla inmutable que empaqueta la aplicación y su entorno (código, librerías, dependencias, archivos de configuración). Un Contenedor es una instancia ejecutable, aislada y efímera de una Imagen. Los contenedores son ligeros y se ejecutan sobre el kernel del sistema operativo del host.
Volúmenes:
El mecanismo preferido para la persistencia de datos en Docker. Los volúmenes (gestionados por Docker) y los montajes 'bind' (directorios del host mapeados a contenedores) permiten almacenar datos importantes (bases de datos, archivos de log, configuraciones) fuera del sistema de archivos efímero del contenedor, asegurando que los datos persistan incluso si el contenedor se elimina.
Redes:
Cómo los contenedores se comunican entre sí y con el exterior. Docker ofrece diferentes drivers de red (bridge por defecto, host, overlay para Swarm/Kubernetes, macvlan). Las redes definidas por el usuario en modo bridge son comunes para aislar servicios y permitir la comunicación por nombre de servicio en Docker Compose.
Docker Compose:
Una herramienta para definir y gestionar aplicaciones compuestas por múltiples contenedores (servicios). Utiliza un archivo YAML (`docker-compose.yml`) para configurar la construcción de imágenes, redes, volúmenes, puertos y dependencias entre servicios, simplificando el despliegue y la gestión de entornos complejos (desarrollo, testing, staging simple).
Registros (Docker Hub y Privados):
Servicios para almacenar, compartir y gestionar imágenes Docker. Docker Hub es el registro público por defecto. Las empresas a menudo utilizan registros privados para sus imágenes internas. Aprender a etiquetar (`tag`) imágenes y a subirlas (`push`) y descargarlas (`pull`) es esencial para la colaboración y el despliegue.
Multi-stage Builds en Dockerfile:
Una técnica avanzada en Dockerfile que utiliza múltiples instrucciones `FROM`. Permite separar el entorno de construcción (con herramientas de compilación, SDKs) del entorno de runtime final (con solo las dependencias necesarias), resultando en imágenes finales mucho más pequeñas y seguras.
Orquestación de Contenedores (Introducción a Swarm y Kubernetes):
La necesidad de gestionar, escalar, desplegar y automatizar la operación de aplicaciones en contenedores a gran escala, a menudo en múltiples máquinas. Docker Swarm es la solución de orquestación nativa de Docker (más simple). Kubernetes es la plataforma líder de orquestación de facto en la industria (más compleja y potente). Comprender por qué se necesitan estas herramientas.
Seguridad Básica de Contenedores:
Consideraciones importantes para reducir la superficie de ataque de los contenedores. Incluye usar imágenes base mínimas y oficiales, no ejecutar procesos como root dentro del contenedor, gestionar permisos de archivo correctamente, no exponer puertos innecesarios, y considerar herramientas de escaneo de vulnerabilidades para las imágenes.
Optimización de Dockerfile y Tamaño de Imagen:
Técnicas para construir imágenes más eficientes y con menor tamaño, lo que acelera los tiempos de construcción, descarga y despliegue. Incluye ordenar las instrucciones para aprovechar el cache, minimizar el número de capas (ej: encadenar comandos RUN), usar `.dockerignore`, multi-stage builds, y elegir imágenes base optimizadas (ej: Alpine, Slim).
Algunos ejemplos de aplicaciones prácticas donde se utiliza Docker:
Contenerizar aplicaciones con múltiples servicios dependientes (ej: frontend, backend, base de datos, cache):
Utilizar Docker Compose para definir, configurar y orquestar todos los servicios que componen una aplicación, simplificando la configuración del entorno de desarrollo local o despliegues sencillos.
Gestionar la persistencia de datos para bases de datos o almacenar archivos subidos por usuarios en contenedores:
Implementar volúmenes gestionados por Docker o montajes 'bind' para asegurar que los datos importantes (bases de datos, archivos de configuración, uploads) persistan más allá del ciclo de vida de los contenedores efímeros.
Configurar redes personalizadas para aislar servicios o habilitar comunicación interna controlada:
Crear redes bridge definidas por el usuario para que solo los contenedores conectados a esa red puedan comunicarse entre sí, mejorando la seguridad y la organización.
Construir imágenes optimizadas para producción con tamaño reducido y menor superficie de ataque:
Aplicar técnicas de Dockerfile como multi-stage builds, `.dockerignore`, y optimizar las instrucciones RUN para reducir el tamaño final de la imagen y eliminar dependencias de desarrollo innecesarias.
Desplegar aplicaciones multi-contenedor en un único host o clúster pequeño con Docker Compose o Swarm:
Utilizar Docker Compose o inicializar un Swarm de Docker para gestionar el despliegue básico, escalado y orquestación de aplicaciones en un entorno simple.
Crear entornos de desarrollo locales que repliquen fielmente el entorno de producción:
Usar Docker y Docker Compose para definir y levantar un entorno de desarrollo que incluya todas las dependencias (versiones de lenguaje, bases de datos, servicios externos) de forma idéntica a como estarán en producción.
Compartir imágenes de aplicaciones o servicios entre equipos o con plataformas de CI/CD:
Construir imágenes, etiquetarlas con tags significativos y subirlas a un registro (Docker Hub o privado) para facilitar la colaboración y la automatización del despliegue.
Automatizar la construcción y prueba de imágenes en pipelines de CI/CD:
Integrar comandos `docker build` y `docker push` en flujos de trabajo de integración continua/despliegue continuo para automatizar la creación y el despliegue de nuevas versiones de la aplicación.
Aquí tienes algunas recomendaciones para facilitar tus inicios en Docker:
Optimiza tus Dockerfiles:
Un buen Dockerfile es clave. Ordena tus instrucciones para aprovechar el cache de capas. Usa `.dockerignore`. Considera multi-stage builds para imágenes finales pequeñas. Minimiza el número de comandos `RUN` (encadenándolos con `&&`).
Entiende a Fondo los Volúmenes para la Persistencia de Datos:
Los datos dentro de un contenedor se pierden al eliminarlo. Aprende a usar volúmenes (`docker volume create`, `-v <nombre>:/ruta`) para la base de datos, logs, archivos de configuración o cualquier dato que necesite persistir. No uses bind mounts para persistencia de datos en producción a menos que sepas lo que haces.
Domina Docker Compose para Aplicaciones Multi-servicio:
Si trabajas con backend + base de datos, frontend + API, etc., Docker Compose (`docker-compose.yml`) es indispensable. Te permite definir y orquestar todos tus servicios en un solo archivo. Aprende su sintaxis YAML.
Limpia Regularmente Recursos no Usados:
Imágenes, contenedores y volúmenes viejos pueden consumir mucho espacio en disco. Usa `docker system prune` (con cuidado), `docker image prune -a`, `docker container prune`, `docker volume prune`.
Considera la Seguridad Básica:
No ejecutes contenedores como root. Crea un usuario dentro del Dockerfile con la instrucción `USER`. Usa imágenes base mínimas. No expongas puertos innecesarios. Sé consciente de cómo manejar secretos.
Aprende a Inspeccionar Contenedores e Imágenes y a Ver Logs:
`docker inspect <id>` y `docker logs <id>` son tus herramientas clave para entender qué está pasando con tus contenedores, ver su configuración y depurar errores. `docker exec -it <id> <comando>` te permite ejecutar comandos dentro de un contenedor en ejecución.
Familiarízate con los Registros (Docker Hub, Registros Privados):
Aprende a etiquetar tus imágenes (`docker tag`) y a subirlas (`docker push`) a un registro. Esto es necesario para compartir imágenes con otros o para desplegarlas en servidores remotos.
Entiende la Diferencia entre CMD y ENTRYPOINT en Dockerfile:
Aunque ambos especifican comandos a ejecutar, tienen roles diferentes. CMD define el comando por defecto (que puede ser sobrescrito al ejecutar el contenedor). ENTRYPOINT define el comando principal del contenedor, al que se le pasan los argumentos definidos en CMD (o pasados al ejecutar `docker run`).
Si te interesa Docker, también podrías explorar estas herramientas:
Amplía tus conocimientos con estos enlaces y materiales: