Docker: La Revolución que Empaquetó tu Código
- Mauricio ECR
- DevOps
- 29 Apr, 2025
En el dinámico mundo del desarrollo y la infraestructura de tecnologías de la información, la necesidad de empaquetar, distribuir y ejecutar aplicaciones de forma consistente ha llevado a la popularización de tecnologías como Docker. Docker no inventó el concepto de contenedores, ya existían tecnologías como LXC (Linux Containers), pero sí los popularizó al proporcionar una forma sencilla y eficiente de trabajar con ellos. Lanzado en 2013, Docker se ha convertido rápidamente en una herramienta fundamental para desarrolladores, administradores de sistemas y profesionales de DevOps.
La promesa de Docker es resolver el clásico problema de “funciona en mi máquina, pero no en producción”. Al encapsular una aplicación y todas sus dependencias en una unidad aislada llamada contenedor, garantiza que la aplicación se ejecute de la misma manera en cualquier entorno, ya sea desarrollo, pruebas o producción.
Conceptos Fundamentales de Docker
Para entender cómo funciona Docker, es crucial familiarizarse con algunos conceptos básicos:
-
Contenedor: Un contenedor es, fundamentalmente, un proceso que se ejecuta en un entorno aislado. Es una instancia en ejecución de una imagen. Un contenedor incluye la aplicación y sus dependencias, tanto de librerías del lenguaje de programación como de librerías de sistema operativo necesarias para la aplicación. Es importante diferenciarlo de una máquina virtual; no es un sistema operativo completo. Los contenedores se ejecutan con un propósito o comando principal y finalizan cuando este comando termina, aunque pueden ejecutar una tarea y finalizar, o un servicio que se mantenga en ejecución. Se pueden ejecutar, parar, reiniciar y eliminar. La eliminación de un contenedor no afecta la imagen de la que proviene.
-
Imagen: Una imagen es un archivo binario o una plantilla que contiene todos los elementos necesarios para ejecutar un contenedor. Esto incluye la aplicación, librerías de lenguaje, librerías de sistema operativo necesarias y la configuración de arranque. Las imágenes son inmutables una vez creadas; cualquier cambio requiere la creación de una nueva imagen. Están compuestas por capas, donde cada capa representa un cambio en el sistema de archivos. Esto permite reutilizar funcionalidades y optimizar el almacenamiento y la construcción, ya que Docker solo descarga las capas que no tiene en local.
-
Dockerfile: Un Dockerfile es un archivo de texto que contiene las instrucciones secuenciales necesarias para construir una imagen. Permite definir pasos como instalar dependencias (
RUN), copiar archivos (COPY), establecer el directorio de trabajo (WORKDIR), y definir el comando por defecto (CMD) o el comando principal (ENTRYPOINT) que se ejecutará al iniciar un contenedor. Cada instrucción crea una capa en la imagen.# Usamos una imagen base ligera de Python (basada en Alpine Linux) FROM python:3.9-alpine # Establecemos el directorio de trabajo dentro del contenedor WORKDIR /app # Copiamos el archivo app.py del host al directorio /app en el contenedor COPY app.py /app/ # Definimos el comando que se ejecutará cuando se inicie el contenedor # En este caso, ejecutar el script python CMD ["python", "app.py"] -
Docker Hub: Es un repositorio de imágenes de contenedor. Funciona de manera similar a GitHub, pero para imágenes. Permite buscar (
docker search), descargar (docker pull) y subir (docker push) imágenes creadas por la comunidad o propias. Existen otros repositorios que soportan el estándar de Docker, como GitHub Container Registry, GitLab Container Registry, etc., gracias al estándar OCI (Open Container Initiative).
Contenedores vs. Máquinas Virtuales
Una distinción clave para comprender Docker es su diferencia con las máquinas virtuales (VMs). Las VMs emulan hardware completo y ejecutan un sistema operativo completo y una capa de virtualización separada, lo que las hace independientes pero consume más recursos y es menos eficiente. Los contenedores, en cambio, comparten el mismo kernel del sistema operativo subyacente. Se ejecutan en un entorno aislado pero comparten los recursos del sistema. Esto los hace más ligeros, rápidos y eficientes en el uso de recursos que las VMs.
Instalación y Entornos
Docker ofrece dos componentes principales para su instalación:
- Docker Engine: El motor que permite crear y ejecutar contenedores. Es gratuito, sin restricciones y se instala principalmente en sistemas Linux. Se utiliza a través de la línea de comandos (CLI) y es ideal para servidores de desarrollo o producción por su rendimiento nativo.
- Docker Desktop: Una aplicación de escritorio para Windows y Mac (y opcionalmente Linux) que incluye Docker Engine más herramientas adicionales como interfaz gráfica, soporte para Kubernetes, plugins, etc. En Windows y Mac, utiliza una máquina virtual para ejecutar los contenedores. Es gratuito para uso personal y pequeñas empresas.
La instalación en Linux a menudo se simplifica con un script oficial.
#instale algunos paquetes de requisitos previos que permitan a apt usar paquetes a través de HTTPS
$ sudo apt install curl apt-transport-https ca-certificates software-properties-common
#descargue la clave GPG de Docker
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
#agregue el repositorio Docker APT a su sistema. El comando crea un docker.listarchivo de repositorio en el /etc/apt/sources.list.ddirectorio.
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ sudo apt install docker-ce -y
$ sudo docker --version
o
sudo docker run hello-world
Construcción de Imágenes con Dockerfile
La construcción de imágenes se realiza utilizando el comando
docker build
nota: El Dockerfile debe estar en el directorio desde donde se ejecuta el comando.
tambien se puede definir un Dockerfile y un contexto (el directorio de referencia). La sintaxis básica es
docker build -t <nombre_imagen> <directorio_contexto>
donde -t asigna un nombre y etiqueta.
Las instrucciones del Dockerfile se ejecutan secuencialmente, de arriba a abajo, y Docker intenta reutilizar capas para optimizar el proceso. Instrucciones clave incluyen:
FROM: Especifica la imagen base.RUN: Ejecuta comandos para instalar software, configurar, etc.COPY: Copia archivos/directorios del contexto de construcción a la imagen.WORKDIR: Define el directorio de trabajo por defecto.CMD: Define el comando por defecto al iniciar el contenedor. Puede ser sobreescrito al ejecutardocker run.ENTRYPOINT: Define el comando principal al iniciar el contenedor. Los comandos pasados adocker runse adjuntan como argumentos aENTRYPOINT.
La diferencia entre CMD y ENTRYPOINT radica en cómo manejan los argumentos pasados al docker run. CMD se sobreescribe, mientras que ENTRYPOINT usa esos argumentos como parámetros.
Para hacer las imágenes más flexibles, se pueden usar:
- Argumentos de Construcción (
ARG): Definidos conARGen el Dockerfile y pasados con--build-argdurante eldocker build. Permiten variabilizar el proceso de construcción. - Variables de Entorno: Se pasan al contenedor en tiempo de ejecución con
-eo--envendocker run. Permiten configurar la aplicación sin modificar la imagen, adaptándola a diferentes entornos.
Ejecución y Gestión de Contenedores
Los contenedores se arrancan con el comando
docker run <imagen>
Este comando crea y arranca un nuevo contenedor.
Comandos y opciones comunes para la gestión de contenedores:
docker ps: Lista los contenedores en ejecución. Añadir-amuestra todos (en ejecución y detenidos).- Opciones de
docker run:-d: Ejecuta el contenedor en segundo plano (“detached”).-p <host_port>:<container_port>: Mapea puertos para permitir la comunicación.-v <host_path_o_volume>:<container_path>: Monta volúmenes o directorios/archivos para persistencia o compartir datos.--name <nombre>: Asigna un nombre al contenedor.--rm: Elimina el contenedor al pararlo.-e <variable>=<valor>: Pasa variables de entorno.--restart <policy>: Define una política de reinicio si el contenedor falla o se detiene (ej:always,unless-stopped,on-failure).
docker logs <id_o_nombre>: Muestra la salida del proceso principal.-fsigue la salida en tiempo real.docker attach <id_o_nombre>: Se acopla al proceso principal del contenedor. Control + p + q para desacoplar sin parar.docker exec <id_o_nombre> <comando>: Ejecuta un comando dentro de un contenedor en ejecución.-itpara un terminal interactivo.docker stop <id_o_nombre>: Detiene un contenedor.docker start <id_o_nombre>: Inicia un contenedor existente pero detenido.docker restart <id_o_nombre>: Detiene y vuelve a iniciar un contenedor.docker rm <id_o_nombre>: Elimina un contenedor detenido.-ffuerza la eliminación.docker container prune: Elimina todos los contenedores detenidos.
Persistencia de Datos con Volúmenes
Los contenedores están diseñados para ser efímeros. Para que los datos persistan, se utilizan volúmenes. Los volúmenes son directorios o archivos que se encuentran fuera del sistema de archivos del contenedor y se montan dentro de él.
La gestión de volúmenes incluye:
- Crear:
docker volume create <nombre> - Listar:
docker volume ls - Inspeccionar:
docker volume inspect <nombre> - Montar: Usando
-vo--mountendocker run. - Eliminar:
docker volume rm <nombre>
También es posible copiar archivos entre el host y el contenedor con
docker cp
Redes en Docker
Docker permite gestionar la comunicación entre contenedores y con el exterior mediante redes. Se controlan con el comando
docker network
Tipos de redes comunes incluyen:
bridge: La red por defecto para comunicación en el mismo host.host: Los contenedores comparten la red del host (menos aislamiento).overlay: Para comunicación entre contenedores en diferentes hosts (cargas distribuidas).none: Sin red.
Comandos de red:
- Crear:
docker network create [--driver <tipo>] <nombre> - Listar:
docker network ls - Inspeccionar:
docker network inspect <nombre> - Conectar/Desconectar:
ydocker network connect <red> <contenedor>docker network disconnect <red> <contenedor> - Eliminar:
docker network rm <nombre>
Gestión de Imágenes Avanzada y Repositorios
Además de construir imágenes con Dockerfile, se puede crear una imagen a partir del estado actual de un contenedor en ejecución usando
docker commit <id_contenedor> <nombre_imagen>
aunque esto no es la práctica más común. La buena práctica favorece las imágenes estáticas definidas por Dockerfiles.
Otras operaciones con imágenes:
- Exportar/Importar:
ydocker save -o <fichero>.tar <imagen>docker load -i <fichero>.tar - Etiquetar:
para renombrar o añadir etiquetas. Las etiquetas identifican el origen y la versión.docker tag <imagen_actual>:<etiqueta> <nuevo_nombre>:<nueva_etiqueta> - Buscar:
en Docker Hub.docker search <término> - Descargar:
docker pull <nombre_imagen> - Subir:
Requiere etiquetar la imagen correctamente (ej: usuario/nombre_imagen). Se puede especificar un repositorio remoto.docker push <nombre_imagen> - Eliminar:
docker rmi <id_o_nombre> - Limpiar:
elimina imágenes no asociadas a contenedores.docker image prune
Conclusión
Docker, a través de sus conceptos fundamentales de imágenes, contenedores, Dockerfiles y repositorios, ha estandarizado y simplificado enormemente el ciclo de vida de las aplicaciones. Su capacidad para empaquetar aplicaciones y sus dependencias en unidades portátiles y aisladas, y la eficiencia que ofrece al compartir el kernel del sistema operativo, lo convierten en una herramienta indispensable en la infraestructura de TI moderna. Ya sea para desarrollo, pruebas, microservicios, CI/CD o despliegues en la nube, los contenedores proporcionan una forma consistente y escalable de gestionar aplicaciones, permitiendo a los equipos trabajar de manera más eficiente y agnóstica del entorno. Entender y dominar estos conceptos básicos es el primer paso para aprovechar todo el potencial que Docker ofrece en la actualidad.