Desplegar contenedores es solo la mitad del trabajo; la otra mitad es saber qué está ocurriendo dentro de ellos. En esta lección aprenderemos a registrar y monitorizar contenedores: cómo consultar logs con docker logs, qué logging drivers existen (json-file, syslog, journald), cómo ver métricas en tiempo real con docker stats, cómo definir healthchecks para comprobar la salud de un servicio y, a alto nivel, cómo montar una solución de monitorización con cAdvisor, Prometheus y Grafana, además de centralizar los logs. La observabilidad es imprescindible para diagnosticar problemas y mantener aplicaciones fiables en producción.

Consultar Logs con docker logs

Por defecto, Docker captura todo lo que un contenedor escribe en la salida estándar (stdout) y la salida de error (stderr).

# Ver los logs de un contenedor
docker logs mi_contenedor

# Seguir los logs en tiempo real
docker logs -f mi_contenedor

# Mostrar solo las últimas 50 líneas con marcas de tiempo
docker logs --tail 50 --timestamps mi_contenedor
  • -f (--follow): muestra los nuevos logs según se generan, como tail -f.
  • --tail 50: limita la salida a las últimas 50 líneas, útil en contenedores con mucho historial.
  • --timestamps: añade la fecha y hora de cada entrada.

Buena práctica: tu aplicación debe escribir en stdout/stderr y no en ficheros internos del contenedor, para que Docker pueda gestionar los logs de forma estándar.

Logging Drivers

Docker permite redirigir los logs a distintos destinos mediante logging drivers. El driver determina dónde y cómo se almacenan.

Driver Destino Caso de uso
json-file Ficheros JSON en el host (por defecto) Uso general; permite docker logs
local Formato optimizado en el host Mejor rendimiento y rotación que json-file
syslog Servidor syslog Centralización en infraestructura existente
journald systemd journal Integración con sistemas basados en systemd
fluentd Fluentd / agregadores Pipelines de logs avanzados
none Descarta los logs Contenedores donde no interesan los logs

Configurar el driver al ejecutar un contenedor

docker run -d --name app \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  nginx
  • --log-driver json-file: usa el driver por defecto de forma explícita.
  • --log-opt max-size=10m: cada fichero de log no superará los 10 MB.
  • --log-opt max-file=3: mantiene como máximo 3 ficheros rotados, evitando que los logs llenen el disco.

Nota: con drivers como syslog o journald, el comando docker logs puede no estar disponible, ya que los logs se gestionan fuera de Docker.

Configurar journald

docker run -d --name app --log-driver journald nginx
journalctl CONTAINER_NAME=app
  • journalctl CONTAINER_NAME=app: consulta los logs del contenedor a través del journal de systemd.

Métricas en Tiempo Real con docker stats

docker stats
  • Muestra en tiempo real el uso de CPU, memoria, red y E/S de disco de todos los contenedores en ejecución.
# Métricas de un contenedor concreto, sin refresco continuo
docker stats --no-stream mi_contenedor
  • --no-stream: toma una única instantánea en lugar de actualizarse continuamente, útil para scripts.
Columna Significado
CPU % Porcentaje de CPU utilizado
MEM USAGE / LIMIT Memoria usada frente al límite asignado
MEM % Porcentaje de memoria respecto al límite
NET I/O Datos enviados/recibidos por la red
BLOCK I/O Lectura/escritura en disco
PIDS Número de procesos del contenedor

Healthchecks

Un healthcheck le indica a Docker cómo comprobar si la aplicación dentro del contenedor está realmente funcionando, no solo si el proceso está vivo.

FROM nginx:alpine
HEALTHCHECK --interval=30s --timeout=3s --retries=3 --start-period=10s \
  CMD curl -f http://localhost/ || exit 1
  • --interval=30s: ejecuta la comprobación cada 30 segundos.
  • --timeout=3s: si la comprobación tarda más de 3 segundos, se considera fallida.
  • --retries=3: tras 3 fallos consecutivos, el contenedor se marca como unhealthy.
  • --start-period=10s: periodo de gracia inicial mientras la aplicación arranca; los fallos durante este tiempo no cuentan.
  • CMD curl -f http://localhost/ || exit 1: la comprobación en sí; -f hace que curl devuelva error ante respuestas HTTP de fallo.

También se puede definir al ejecutar el contenedor:

docker run -d --name web \
  --health-cmd "curl -f http://localhost/ || exit 1" \
  --health-interval 30s \
  nginx

Para ver el estado de salud:

docker ps
docker inspect --format '{{.State.Health.Status}}' web
  • docker ps: la columna STATUS mostrará (healthy) o (unhealthy).
  • docker inspect --format '{{.State.Health.Status}}': extrae directamente el estado de salud.

Introducción a la Monitorización: cAdvisor, Prometheus y Grafana

Para entornos reales, los comandos puntuales no bastan: necesitas métricas históricas, alertas y paneles. Una combinación muy extendida es cAdvisor + Prometheus + Grafana.

  • cAdvisor (Container Advisor): recoge métricas de uso de recursos de cada contenedor y las expone en un formato que Prometheus puede leer.
  • Prometheus: base de datos de series temporales que recopila (scrapes) métricas periódicamente y permite consultarlas y definir alertas.
  • Grafana: herramienta de visualización que crea paneles (dashboards) a partir de los datos de Prometheus.
version: "3.8"
services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
  • cadvisor: monta directorios del host en solo lectura (:ro) para leer las métricas de los contenedores.
  • prometheus: expone el puerto 9090 y carga su configuración desde prometheus.yml.
  • grafana: expone el puerto 3000 para acceder a los paneles desde el navegador.

Fichero de configuración de Prometheus que le indica de dónde recoger métricas:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "cadvisor"
    static_configs:
      - targets: ["cadvisor:8080"]
  • scrape_interval: 15s: Prometheus recoge métricas cada 15 segundos.
  • targets: ["cadvisor:8080"]: el destino del que recopila datos; usa el nombre de servicio gracias al DNS interno de Docker.

Con esta base, en Grafana puedes importar paneles ya preparados para visualizar CPU, memoria y red por contenedor.

Centralización de Logs

En entornos con muchos contenedores y hosts, revisar logs uno a uno es inviable. La solución es centralizarlos en una plataforma común:

  • Pila EFK/ELK: Elasticsearch (almacenamiento e indexación), Fluentd o Logstash (recolección y procesado) y Kibana (visualización).
  • Loki + Grafana: Loki almacena logs de forma eficiente y Grafana los visualiza junto a las métricas.
  • Servicios gestionados en la nube: como AWS CloudWatch Logs, Google Cloud Logging o Azure Monitor.
# Ejemplo: enviar logs a Fluentd mediante el logging driver
docker run -d --name app \
  --log-driver fluentd \
  --log-opt fluentd-address=localhost:24224 \
  --log-opt tag=app.web \
  nginx
  • --log-driver fluentd: redirige los logs al recolector Fluentd.
  • --log-opt fluentd-address: dirección del servidor Fluentd (datos de ejemplo).
  • --log-opt tag=app.web: etiqueta los logs para poder filtrarlos y enrutarlos.

Errores Comunes y Consejos

  • Escribir logs en ficheros internos del contenedor: rompe la gestión estándar de Docker. Escribe siempre en stdout/stderr.
  • No limitar el tamaño de los logs: con json-file sin max-size/max-file, los logs pueden llenar el disco del host. Configura siempre la rotación.
  • Confundir proceso vivo con servicio sano: un proceso puede seguir ejecutándose pero no responder. Define healthchecks reales que prueben la funcionalidad.
  • Olvidar el --start-period en healthchecks: aplicaciones que tardan en arrancar pueden marcarse como unhealthy injustamente sin un periodo de gracia.
  • Monitorizar solo de forma reactiva: configura alertas en Prometheus para enterarte de los problemas antes que tus usuarios.
  • Consejo: combina métricas (Prometheus/Grafana) y logs centralizados; ambos se complementan al diagnosticar incidencias.

Ejercicios

Ejercicio 1: Logs con rotación

Lanza un contenedor Nginx con el driver json-file configurado para un máximo de 5 MB por fichero y 2 ficheros. Genera tráfico y consulta los logs en tiempo real.

Ejercicio 2: Healthcheck

Crea un Dockerfile basado en Nginx con un HEALTHCHECK que compruebe la página principal. Construye la imagen, ejecútala y verifica con docker ps que aparece como healthy.

Ejercicio 3: Métricas en tiempo real

Ejecuta dos o tres contenedores y usa docker stats para identificar cuál consume más memoria. Después toma una instantánea con --no-stream de uno de ellos.

Soluciones

Solución 1

docker run -d --name web \
  --log-driver json-file \
  --log-opt max-size=5m \
  --log-opt max-file=2 \
  -p 8080:80 \
  nginx

curl http://localhost:8080      # Genera alguna entrada de log
docker logs -f web              # Consulta en tiempo real (Ctrl+C para salir)

Solución 2

FROM nginx:alpine
RUN apk add --no-cache curl
HEALTHCHECK --interval=15s --timeout=3s --retries=3 --start-period=5s \
  CMD curl -f http://localhost/ || exit 1
docker build -t web_sana:1.0 .
docker run -d --name sana -p 8081:80 web_sana:1.0
sleep 20
docker ps   # La columna STATUS debe mostrar (healthy)

Solución 3

docker run -d --name c1 nginx
docker run -d --name c2 redis
docker run -d --name c3 postgres -e POSTGRES_PASSWORD=ejemplo

docker stats                          # Observa el uso de memoria de cada uno
docker stats --no-stream c3           # Instantánea única del contenedor c3

Normalmente PostgreSQL consumirá más memoria que Nginx o Redis en reposo, lo que se aprecia en la columna MEM USAGE.

Conclusión

En esta lección hemos cubierto la observabilidad de contenedores: la consulta de logs con docker logs, los distintos logging drivers y su rotación, las métricas en tiempo real con docker stats, la definición de healthchecks y una introducción a la monitorización con cAdvisor, Prometheus y Grafana, junto con las estrategias de centralización de logs. Estas herramientas te permiten detectar y diagnosticar problemas antes de que afecten a tus usuarios.

Con esta lección concluimos el Módulo 5 sobre conceptos avanzados de Docker. En el Módulo 6: Docker en Producción, llevaremos todo lo aprendido al mundo real, empezando por CI/CD con Docker, donde integraremos la construcción, prueba y despliegue de imágenes en pipelines automatizados.

© Copyright 2026. Todos los derechos reservados