Docker Container: Fundamentos, Imágenes, Dockerfile y Docker Compose
Docker revolucionó el desarrollo de software mediante la containerización. Permite crear entornos consistentes desde desarrollo hasta producción, resolviendo el problema del “funciona en mi máquina”.
Fundamentos de Docker
Qué es la containerización
La containerización es una tecnología de virtualización a nivel del sistema operativo que ejecuta aplicaciones con todas sus dependencias en entornos aislados.
Docker versus máquinas virtuales
# Máquina virtual (VM)
# - Sistema operativo completo
# - Hypervisor requerido
# - Alto consumo de recursos
# - Inicio lento
# Contenedor Docker
# - Kernel del sistema operativo compartido
# - No requiere hypervisor
# - Bajo consumo de recursos
# - Inicio rápido
Arquitectura de Docker
# Componentes de Docker
# 1. Docker Daemon (dockerd)
# - Gestiona contenedores, imágenes, redes, volúmenes
# - Se ejecuta en segundo plano
# - Punto final de API para clientes
# 2. Docker Client (docker)
# - Interfaz de línea de comandos
# - Se comunica con Docker Daemon
# - Interacción con el usuario
# 3. Docker Registry
# - Almacén de imágenes (Docker Hub)
# - Registros públicos y privados
# 4. Objetos de Docker
# - Images: plantillas para contenedores
# - Containers: instancias en ejecución
# - Networks: comunicación entre contenedores
# - Volumes: almacenamiento de datos
Instalación y configuración de Docker
Instalación
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker
# CentOS/RHEL
sudo yum install docker
sudo systemctl start docker
sudo systemctl enable docker
# Docker Desktop (Windows/Mac)
# Descargar desde https://www.docker.com/products/docker-desktop
# Agregar usuario al grupo docker
sudo usermod -aG docker $USER
newgrp docker
# Verificar instalación
docker --version
docker info
Comandos básicos
# Versión de Docker e información del sistema
docker version
docker info
docker system df
# Gestionar imágenes
docker images
docker pull ubuntu:latest
docker search nginx
docker rmi nginx:latest
# Gestionar contenedores
docker ps # Contenedores en ejecución
docker ps -a # Todos los contenedores
docker run nginx # Iniciar contenedor
docker stop container_id # Detener contenedor
docker rm container_id # Eliminar contenedor
# Logs e inspección
docker logs container_id
docker inspect container_id
docker exec -it container_id bash
Imágenes de Docker
Qué son las imágenes de Docker
Las imágenes de Docker son plantillas de solo lectura que se usan para crear contenedores. Están compuestas por múltiples capas.
Estructura de una imagen
# Estructura de capas de una imagen Docker
# 1. Capa base (por ejemplo, Ubuntu)
# 2. Capa de dependencias (por ejemplo, Python)
# 3. Capa de aplicación (por ejemplo, aplicación web)
# 4. Capa de configuración (por ejemplo, variables de entorno)
# Ver capas
docker history nginx:latest
# Información de la imagen
docker inspect nginx:latest
Dockerfile
Un Dockerfile es un archivo de texto con instrucciones para crear una imagen de Docker.
# Ejemplo de Dockerfile para aplicación Node.js
# Imagen base
FROM node:16-alpine
# Metadatos
LABEL maintainer="max@example.com"
LABEL version="1.0"
LABEL description="Node.js web application"
# Directorio de trabajo
WORKDIR /app
# Variables de entorno
ENV NODE_ENV=production
ENV PORT=3000
# Copiar archivos
COPY package*.json ./
RUN npm install --production
# Copiar código de la aplicación
COPY . .
# Crear usuario (buena práctica de seguridad)
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
# Exponer puerto
EXPOSE 3000
# Health Check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Comando de inicio
CMD ["node", "server.js"]
Buenas prácticas para Dockerfile
# Buenas prácticas en Dockerfile
# 1. Imagen base minimalista
FROM alpine:latest
# 2. Usar tags específicos (no latest)
FROM node:16.14.2-alpine
# 3. Usar .dockerignore
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
# 4. Optimizar cache de capas
COPY package*.json ./
RUN npm install
COPY . .
# 5. Build multi-etapa
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:16-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
# 6. Prácticas de seguridad
USER nonrootuser
RUN rm -rf /var/cache/apk/*
Crear y gestionar imágenes
# Construir imagen
docker build -t myapp:1.0 .
docker build -t myapp:latest -f Dockerfile.prod .
# Imagen con argumentos de construcción
docker build --build-arg NODE_ENV=production -t myapp:prod .
# Build multi-plataforma
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:multi .
# Etiquetar imágenes
docker tag myapp:1.0 myregistry/myapp:1.0
docker tag myapp:latest myregistry/myapp:latest
# Enviar imágenes
docker login myregistry.com
docker push myregistry/myapp:1.0
docker push myregistry/myapp:latest
# Limpiar imágenes
docker image prune -f
docker image prune -a -f
Contenedores de Docker
Ciclo de vida del contenedor
# Crear e iniciar contenedor
docker run --name mywebserver -d -p 8080:80 nginx
# Contenedor con volúmenes
docker run --name mydb -v /data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0
# Contenedor con red
docker network create mynetwork
docker run --name myapp --network mynetwork -d myapp:latest
# Gestionar contenedor
docker start mywebserver
docker stop mywebserver
docker restart mywebserver
docker pause mywebserver
docker unpause mywebserver
# Inspeccionar contenedor
docker logs mywebserver
docker logs -f mywebserver # Seguir logs
docker stats mywebserver # Uso de recursos
docker exec -it mywebserver bash
Configuración del contenedor
# Límites de recursos
docker run --memory="512m" --cpus="1.0" myapp:latest
# Variables de entorno
docker run -e NODE_ENV=production -e PORT=3000 myapp:latest
# Volúmenes
docker run -v /host/path:/container/path myapp:latest
docker run -v myvolume:/container/path myapp:latest
# Puertos
docker run -p 8080:80 -p 8443:443 myapp:latest
# Redes
docker run --network bridge myapp:latest
docker run --network host myapp:latest
docker run --network none myapp:latest
# Políticas de reinicio
docker run --restart=always myapp:latest
docker run --restart=on-failure:5 myapp:latest
docker run --restart=unless-stopped myapp:latest
Volúmenes de Docker
# Tipos de volúmenes
# 1. Bind Mounts: Sistema de archivos del host
docker run -v /host/data:/container/data myapp:latest
# 2. Named Volumes: Gestionado por Docker
docker volume create mydata
docker run -v mydata:/container/data myapp:latest
# 3. Anonymous Volumes: Creado automáticamente
docker run -v /container/data myapp:latest
# Gestión de volúmenes
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune
# Backup y restore
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar czf /backup/mydata-backup.tar.gz /data
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar xzf /backup/mydata-backup.tar.gz -C /
Redes en Docker
Tipos de redes
# Bridge Network (Estándar)
docker network create mybridge
docker run --network mybridge myapp:latest
# Host Network
docker run --network host myapp:latest
# None Network
docker run --network none myapp:latest
# Overlay Network (Multi-Host)
docker network create --driver overlay myoverlay
Configuración de redes
# Crear una red
docker network create --driver bridge --subnet 192.168.1.0/24 mynetwork
# Ejecutar un contenedor en una red
docker run --network mynetwork --ip 192.168.1.10 myapp:latest
# Conectar y desconectar contenedores
docker network connect mynetwork mycontainer
docker network disconnect mynetwork mycontainer
# Inspeccionar redes
docker network inspect mynetwork
docker network ls
docker network prune
Docker Compose
Fundamentos de Docker Compose
Docker Compose permite definir y gestionar aplicaciones multi-contenedor de forma declarativa.
# docker-compose.yml
version: '3.8'
services:
# Servicio web
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/myapp
depends_on:
- db
- redis
volumes:
- ./logs:/app/logs
restart: unless-stopped
networks:
- app-network
# Servicio de base de datos
db:
image: postgres:13
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
networks:
- app-network
# Redis cache
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- app-network
# Nginx reverse proxy
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- web
restart: unless-stopped
networks:
- app-network
# Volúmenes
volumes:
postgres_data:
redis_data:
# Redes
networks:
app-network:
driver: bridge
Comandos de Docker Compose
# Iniciar servicios
docker-compose up
docker-compose up -d # Modo detached
docker-compose up --build # Con reconstrucción
# Detener servicios
docker-compose down
docker-compose down -v # Con volúmenes
# Ver registros
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=100 web
# Gestionar servicios
docker-compose ps
docker-compose restart web
docker-compose stop web
docker-compose start web
# Escalar servicios
docker-compose up -d --scale web=3
# Construir imágenes
docker-compose build
docker-compose build --no-cache
docker-compose build web
# Composición de configuraciones
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
Configuración específica por entorno
# docker-compose.override.yml (Desarrollo)
version: '3.8'
services:
web:
environment:
- NODE_ENV=development
volumes:
- .:/app
- /app/node_modules
command: npm run dev
db:
ports:
- "5432:5432"
# docker-compose.prod.yml (Producción)
version: '3.8'
services:
web:
environment:
- NODE_ENV=production
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
nginx:
ports:
- "80:80"
- "443:443"
Seguridad en Docker
Mejores prácticas de seguridad
# 1. Imagen base minimalista
FROM alpine:latest
# 2. Usuario sin privilegios
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
USER appuser
# 3. Usar secretos (no en la imagen)
# docker run --secret=mysecret myapp:latest
# 4. Sistema de archivos de solo lectura
docker run --read-only --tmpfs /tmp myapp:latest
# 5. Límites de recursos
docker run --memory=512m --cpus=1.0 myapp:latest
Escaneo de seguridad en Docker
# Escanear imagen con Trivy
trivy image myapp:latest
# Docker Scout (herramienta oficial)
docker scout cves myapp:latest
# Validar Dockerfile con hadolint
hadolint Dockerfile
Monitoreo y registros en Docker
Estrategias de logging
# docker-compose.yml con configuración de logging
version: '3.8'
services:
web:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels:
- "logging=promtail"
# ELK Stack para logging
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
environment:
- discovery.type=single-node
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:7.14.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
kibana:
image: docker.elastic.co/kibana/kibana:7.14.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
Monitoreo con Prometheus
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus_data:
grafana_data:
Docker y Kubernetes
Fundamentos de Kubernetes
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Migración de Docker a Kubernetes
# Usar kompose para convertir
kompose convert -f docker-compose.yml
# Aplicar manifiestos de Kubernetes
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# Gestionar el deployment
kubectl get deployments
kubectl get pods
kubectl logs -f deployment/myapp-deployment
kubectl scale deployment myapp-deployment --replicas=5
Mejores prácticas en Docker
Optimización de rendimiento
# Multi-stage build para imágenes más pequeñas
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build
FROM node:16-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
Implementación en Producción
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: myregistry/myapp:${VERSION}
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Solución de Problemas
Problemas Comunes
# 1. El contenedor no inicia
docker logs container_id
docker inspect container_id
# 2. Espacio en disco lleno
docker system df
docker system prune -a -f
docker volume prune -f
# 3. Problemas de red
docker network inspect network_name
docker exec -it container_id ping other_container
# 4. Problemas de permisos
sudo chown -R $USER:$USER /var/run/docker.sock
# 5. Problemas al descargar imágenes
docker system prune -f
docker pull --no-cache image_name
Técnicas de Depuración
# Inspeccionar contenedor
docker exec -it container_id /bin/sh
docker exec -it container_id /bin/bash
# Copiar archivos
docker cp container_id:/path/file.txt .
docker cp file.txt container_id:/path/
# Analizar capas de imagen
docker history image_name
dive image_name
# Análisis de rendimiento
docker stats
docker top container_id
Conceptos Relevantes para la Certificación
Comandos Docker Esenciales
| Comando | Descripción | Uso |
|---|---|---|
docker build | Crear una imagen | Desde Dockerfile |
docker run | Iniciar un contenedor | Ejecutar aplicación |
docker-compose up | Iniciar multi-contenedor | Entorno de desarrollo |
docker push | Subir imagen | Carga a Registry |
docker pull | Descargar imagen | Descarga desde Registry |
Tareas Típicas de Examen
- Crear Dockerfiles para diferentes aplicaciones
- Configurar Docker Compose para aplicaciones multi-contenedor
- Implementar prácticas de seguridad
- Optimizar imágenes Docker para producción
- Migrar aplicaciones a Kubernetes
Resumen
Docker es fundamental para la ingeniería de software moderna:
- Containerización: Entornos consistentes en cualquier lugar
- Imágenes: Plantillas reutilizables para aplicaciones
- Dockerfile: Procesos de compilación automatizados
- Docker Compose: Definir aplicaciones multi-contenedor
- Kubernetes: Orquestación para grandes despliegues
Una buena gestión de Docker requiere comprensión de conceptos de contenedores, prácticas de seguridad y técnicas de orquestación.
Lecturas Recomendadas
Docker es fácil de aprender e implementar para despliegues simples, pero la plataforma ofrece mucho más para mejorar la productividad y seguridad. Invierte tiempo en literatura especializada para aprovechar todo el potencial de los contenedores. Los libros recomendados te guiarán desde los fundamentos hasta soluciones empresariales avanzadas, ayudándote a diseñar y operar arquitecturas Docker profesionales.
Docker: Das Praxisbuch für Entwickler und DevOps-Teams. Grundlagen, Einstieg, Konzepte. Für Windows, macOS und Linux. Ausgabe 2026
44,99 €
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.
Das Komplette Docker Handbuch: Containerisierte Anwendungen Erstellen, Verteilen, Ausführen
39,99 €
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.



