¿Qué es Docker y por qué deberían aprenderlo los desarrolladores?
Un desglose práctico de Docker para desarrolladores: contenedores vs máquinas virtuales, comandos principales, Dockerfiles y cómo empezar a usarlo en proyectos reales.
Docker aparece constantemente en ofertas de trabajo y guías de configuración, y si nunca has trabajado con contenedores puede parecer un obstáculo que tienes que superar antes de poder escribir código real. No es tan complicado una vez que pasas la jerga.
Qué es realmente un contenedor
Un contenedor empaqueta tu aplicación con todo lo que necesita para ejecutarse: el código, el runtime, las librerías del sistema y archivos de configuración. No es una máquina virtual. Una VM virtualiza un sistema operativo completo, kernel incluido, lo que significa que arrancarla puede tomar un minuto y consumir varios gigabytes de RAM. Un contenedor comparte el kernel de la máquina host y solo aísla el proceso, así que inicia en menos de un segundo y típicamente usa decenas de megabytes en lugar de gigabytes.
Esa diferencia es por qué Docker se apoderó tan rápido del desarrollo local y los pipelines de CI. Puedes iniciar una base de datos Postgres, una caché Redis y tu servidor de aplicaciones en una laptop sin instalar ninguno de ellos directamente en tu OS.
Las piezas principales que necesitas conocer
Hay cuatro términos que cubren la mayoría de lo que harás día a día:
- Image: una plantilla de solo lectura creada a partir de un Dockerfile. Piénsalo como una captura de un sistema de archivos más metadatos sobre cómo ejecutarlo.
- Container: una instancia ejecutándose de una imagen. Puedes iniciar, detener y eliminar contenedores sin tocar la imagen de la que vinieron.
- Dockerfile: un archivo de texto con instrucciones para construir una imagen, línea por línea.
- Registry: donde se almacenan y descargan las imágenes, más comúnmente Docker Hub.
Un Dockerfile mínimo para una aplicación Node.js se ve así:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Constrúyelo con docker build -t my-app . y ejecútalo con docker run -p 3000:3000 my-app. El flag -p mapea un puerto en tu máquina a un puerto dentro del contenedor, que es cómo realmente accedes a la aplicación desde tu navegador.
Comandos que usarás constantemente
Unos pocos comandos cubren la mayoría del trabajo diario:
docker ps— lista los contenedores en ejecucióndocker ps -a— lista todos los contenedores, incluyendo los detenidosdocker images— lista las imágenes en tu máquinadocker logs <container>— verifica la salida de un contenedor en ejecución o caídodocker exec -it <container> sh— abre un shell dentro de un contenedor en ejecucióndocker rm/docker rmi— limpia contenedores e imágenes que ya no necesitas
Ese último par importa más de lo que la gente espera. Docker dejará felizmente que el espacio de disco desaparezca en imágenes antiguas y contenedores detenidos. Ejecutar docker system prune ocasionalmente recupera una cantidad sorprendente de espacio.
Por qué docker-compose cambia el flujo de trabajo
La mayoría de proyectos reales necesitan más de un contenedor: un servidor de aplicaciones, una base de datos, tal vez una caché. Escribir comandos docker run para cada uno se vuelve tedioso rápido. docker-compose.yml te permite definir la pila completa en un archivo:
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpassword
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Ejecuta docker compose up y ambos servicios inician juntos, conectados en red para que web pueda alcanzar db por nombre de servicio. Esta es la configuración que verás en el README de casi todo repositorio de código abierto, y entenderla significa que puedes clonar un proyecto y tenerlo ejecutándose en minutos en lugar de instalar manualmente Postgres, Redis y todo lo demás que la aplicación necesite.
Dónde la gente se atasca al principio
Los volúmenes confunden a casi todos al principio. Sin un volumen, cualquier cosa escrita dentro de un contenedor desaparece cuando el contenedor se elimina, lo que es un problema para bases de datos. La sección volumes en el archivo compose anterior mapea un volumen nombrado a una ruta dentro del contenedor para que los datos sobrevivan los reinicios.
Otro error común es copiar node_modules o .git en la imagen porque no hay un archivo .dockerignore. Añade uno como lo harías con .gitignore:
node_modules
.git
.env
Eso mantiene las compilaciones más rápidas e imágenes más pequeñas, lo que importa una vez que estés empujando imágenes a un registry o desplegando a Kubernetes.
Dónde ir después de lo básico
Una vez que construir y ejecutar contenedores se sienta normal, las siguientes habilidades útiles son compilaciones multietapa para imágenes de producción más pequeñas, entender modos de red de Docker, y leer una salida de docker inspect cuando algo no se conecta bien. Nada es difícil, solo es desconocido la primera vez.
Para más sobre containerizar aplicaciones reales y conectarlas a pipelines de despliegue en la nube, consulta los segmentos de DevOps y Cloud en Korra Studio.
Escrito con asistencia de IA, revisado y publicado por Michal Pilch (CISSP), Korra Studio.
Esta es una nota de la base de conocimiento de Korra Studio — la plataforma combina cada tema con mentoría 1 a 1.
Empezar gratisarrow_forward