Docker para Principiantes: Guía Completa de Contenedores 2026

Docker para Principiantes: Guía Completa de Contenedores 2026

Aprende Docker desde cero. Entiende contenedores, imágenes, Dockerfile y Docker Compose con ejemplos prácticos.

17 de marzo de 20267 min de lectura

¿Por Qué Necesitas Docker?

"En mi máquina funciona perfectamente." Si has dicho esto alguna vez, Docker es para ti.

Docker resuelve uno de los problemas más clásicos del desarrollo de software: la inconsistencia entre entornos. Empaqueta tu aplicación junto con todas sus dependencias —librerías, variables de entorno, versión del runtime— en una unidad llamada contenedor, que funciona de forma idéntica en cualquier máquina donde se ejecute.

En 2026, Docker es una habilidad fundamental para cualquier desarrollador backend o de infraestructura. Las empresas esperan que sus ingenieros sepan contenedorizarse aplicaciones, y el ecosistema cloud (AWS, GCP, Azure) está construido alrededor de esta tecnología.

Contenedores vs Máquinas Virtuales

Es la comparación clásica, y entenderla es clave:

AspectoContenedores (Docker)Máquinas Virtuales
Tiempo de inicioMilisegundosMinutos
TamañoMegabytesGigabytes
Sistema OperativoComparte kernel del hostOS completo propio
AislamientoA nivel de procesoA nivel de hardware
OverheadMínimoSignificativo
PortabilidadExcelenteBuena

Los contenedores son como departamentos en un edificio: comparten la infraestructura (el kernel del OS) pero cada uno tiene su propio espacio. Las VMs son como casas independientes: cada una tiene sus propios cimientos, paredes y techo.

Instalación

# macOS: Descarga Docker Desktop desde
# https://www.docker.com/products/docker-desktop

# Linux (Ubuntu/Debian)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker

# Verificar instalación
docker --version
# Docker version 27.x.x

docker compose version
# Docker Compose version v2.x.x

# Prueba rápida
docker run hello-world

Conceptos Fundamentales

Imagen vs Contenedor

  • Imagen: Una plantilla inmutable con todo lo necesario para ejecutar la app (código, dependencias, configuración). Es la "receta".
  • Contenedor: Una instancia en ejecución de una imagen. Es el "plato cocinado".

Puedes crear múltiples contenedores a partir de la misma imagen. Son independientes entre sí.

# Operaciones con imágenes
docker pull node:22-alpine          # Descargar imagen de Docker Hub
docker images                        # Listar imágenes locales
docker rmi node:22-alpine           # Eliminar imagen

# Operaciones con contenedores
docker run node:22-alpine           # Crear y ejecutar contenedor
docker run -d -p 3000:3000 my-app   # En background con port mapping
docker ps                            # Ver contenedores activos
docker ps -a                         # Ver todos (incluidos parados)
docker stop <id o nombre>           # Parar contenedor
docker rm <id o nombre>             # Eliminar contenedor
docker logs -f <id>                 # Ver logs en tiempo real
docker exec -it <id> sh             # Entrar al contenedor

Tu Primer Dockerfile

El Dockerfile es el script que define cómo construir la imagen de tu aplicación.

Node.js / Express

# Imagen base: Node.js 22 en Alpine Linux (imagen mínima)
FROM node:22-alpine

# Directorio de trabajo dentro del contenedor
WORKDIR /app

# Copiar archivos de dependencias PRIMERO (optimiza la caché)
COPY package*.json ./

# Instalar solo dependencias de producción
RUN npm ci --only=production

# Copiar el resto del código
COPY . .

# Declarar el puerto que usa la app
EXPOSE 3000

# Healthcheck para verificar que la app está sana
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

# Comando por defecto al iniciar el contenedor
CMD ["node", "src/server.js"]

Python / FastAPI

FROM python:3.13-slim

# Variables de entorno para Python
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

# Instalar dependencias del sistema (si las hay)
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Construir y Ejecutar

# Construir la imagen (desde el directorio con el Dockerfile)
docker build -t mi-app:1.0 .

# Ejecutar el contenedor
docker run -d \
  --name mi-app-dev \
  -p 3000:3000 \
  -e NODE_ENV=development \
  -e DATABASE_URL=postgresql://user:pass@localhost/db \
  mi-app:1.0

# Ver que está funcionando
docker ps
docker logs mi-app-dev

.dockerignore: Lo que No Debe Entrar

# .dockerignore
node_modules
.npm
.git
.gitignore
*.md
.env
.env.*
dist
build
coverage
.nyc_output
__pycache__
*.pyc
*.pyo
.pytest_cache
.mypy_cache
.ruff_cache
*.log

Sin este archivo, node_modules (que puede pesar cientos de MB) se copiaría al contexto de build, haciéndolo lentísimo.

Docker Compose: Orquestando Múltiples Servicios

Las apps reales tienen múltiples servicios: API, base de datos, caché, cola de mensajes. Docker Compose permite definir y levantar todo esto con un solo comando.

# docker-compose.yml

services:
  # API Backend (FastAPI)
  api:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: toolbox-api
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/toolbox
      - REDIS_URL=redis://redis:6379/0
      - SECRET_KEY=${SECRET_KEY}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./backend:/app  # Hot reload en desarrollo
    restart: unless-stopped

  # Frontend (Next.js)
  frontend:
    build:
      context: ./frontend
      target: development  # Multi-stage build
    container_name: toolbox-frontend
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://localhost:8000
    volumes:
      - ./frontend:/app
      - /app/node_modules  # Preservar node_modules del contenedor
    depends_on:
      - api

  # PostgreSQL
  db:
    image: postgres:17-alpine
    container_name: toolbox-db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: toolbox
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d toolbox"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis (caché y sesiones)
  redis:
    image: redis:7-alpine
    container_name: toolbox-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes

  # pgAdmin (interfaz para la base de datos, solo desarrollo)
  pgadmin:
    image: dpage/pgadmin4:latest
    container_name: toolbox-pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@toolbox.dev
      PGADMIN_DEFAULT_PASSWORD: admin
    ports:
      - "5050:80"
    profiles:
      - dev  # Solo se inicia con --profile dev

volumes:
  postgres_data:
  redis_data:

Comandos de Docker Compose

# Levantar todos los servicios
docker compose up -d

# Levantar con reconstrucción de imágenes
docker compose up -d --build

# Solo el perfil de desarrollo
docker compose --profile dev up -d

# Ver estado de los servicios
docker compose ps

# Logs de un servicio específico
docker compose logs -f api

# Ejecutar comando en un contenedor activo
docker compose exec api bash
docker compose exec db psql -U postgres toolbox

# Parar servicios
docker compose down

# Parar y eliminar volúmenes (¡borra datos!)
docker compose down -v

# Reiniciar un servicio específico
docker compose restart api

Buenas Prácticas para Producción

Multi-Stage Build para Optimizar el Tamaño

# Etapa 1: Instalar dependencias y compilar
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Etapa 2: Imagen final solo con lo necesario
FROM node:22-alpine AS production
WORKDIR /app

# Crear usuario sin privilegios (seguridad)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Solo copiar los artefactos del build
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json .

USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]

Resultado: imagen de ~80MB en lugar de ~800MB.

Variables de Entorno con Archivos .env

# .env.production (no commitear a git)
POSTGRES_PASSWORD=super_secret_password_123
SECRET_KEY=jwt_secret_very_long_random_string
REDIS_PASSWORD=redis_password

# En docker-compose.yml
services:
  api:
    env_file:
      - .env.production

Comandos Esenciales de Docker (Cheatsheet)

# Gestión de imágenes
docker pull <imagen>           # Descargar
docker build -t <nombre> .     # Construir desde Dockerfile
docker tag <img> <nuevo-nombre> # Añadir tag
docker push <imagen>           # Subir a registry

# Gestión de contenedores
docker run -d -p <host>:<cont> --name <n> <img>  # Ejecutar
docker stop <id/nombre>        # Parar
docker start <id/nombre>       # Iniciar
docker restart <id/nombre>     # Reiniciar
docker rm <id/nombre>          # Eliminar
docker exec -it <id> sh        # Shell interactivo

# Diagnóstico
docker logs -f <id>            # Logs en tiempo real
docker stats                   # Uso de recursos
docker inspect <id>            # Información detallada
docker top <id>                # Procesos dentro del contenedor

# Limpieza
docker system prune -a         # Limpiar todo lo no utilizado
docker volume prune            # Limpiar volúmenes
docker image prune             # Limpiar imágenes sin usar

Conclusión

Docker ha pasado de ser una tecnología de nicho a ser un estándar de la industria. Dominar los conceptos de esta guía te permite:

  1. Reproducir entornos exactos: Tu app funciona igual en desarrollo, testing y producción
  2. Incorporarte a cualquier proyecto: Casi todo proyecto moderno usa Docker
  3. Trabajar con microservicios: Docker Compose y Kubernetes usan los mismos conceptos
  4. Desplegar en cualquier cloud: AWS ECS, GCP Cloud Run, Azure Container Apps, todos hablan Docker

El siguiente paso después de esta guía: aprender los fundamentos de Kubernetes para orquestación a gran escala, y explorar servicios gestionados como AWS ECS Fargate que simplifican el despliegue de contenedores en producción.

Publicaciones relacionadas