Gestión de logs de Docker en la práctica: del driver a la recolección centralizada

El móvil vibró. Alerta de disco en el servidor de producción, umbral al 85%.
Me levanté, abrí el portátil y entré por SSH. df -h: en la partición raíz solo quedaba un 12% libre. Tras revisar todo, el culpable estaba en /var/lib/docker/containers: un contenedor Nginx que llevaba dos semanas en marcha y cuyo archivo de log ya pesaba 12 GB.
Docker no limita el tamaño de los logs por defecto, y mucha gente no lo sabe. Ese contenedor generaba decenas de miles de líneas de acceso al día; el driver json-file las registraba todas fielmente, y en dos semanas el disco quedó lleno.
Borré ese archivo de log y añadí rotación a todos los contenedores. La cosa se alargó hasta las cuatro de la madrugada.
Después dediqué una semana a ordenar la gestión de logs de Docker: elección de driver, parámetros de rotación y recolección centralizada en entornos con muchos contenedores. Este artículo resume lo que aprendí en ese incidente.
1. Panorama de los drivers de logs de Docker
Primero, un concepto básico: los logs del contenedor no se escriben al azar; un «driver de logs» decide adónde van y cómo se almacenan.
Docker soporta varios drivers, cada uno con su escenario. Por defecto usa json-file: guarda stdout y stderr en un archivo local en JSON, en /var/lib/docker/containers/<ID-contenedor>/<ID-contenedor>-json.log.
json-file es simple: sin configuración extra, formato uniforme y lectura directa con docker logs. El problema: sin límite de tamaño por defecto. Un contenedor que corre mucho tiempo acumula logs hasta reventar el disco.
Esta tabla resume seis drivers habituales:
| Driver | Escenario | Soporte estructurado | Servicio externo | Impacto en rendimiento |
|---|---|---|---|---|
| json-file | Desarrollo, despliegue en un solo host | Sí (JSON automático) | No | Bajo |
| syslog | Infra syslog empresarial existente | No (requiere parseo) | Sí (rsyslog) | Bajo |
| journald | Entorno systemd | Parcial | No | Bajo |
| fluentd | Observabilidad cloud-native, recolección centralizada | Sí (tag personalizado) | Sí (servicio Fluentd) | Medio |
| gelf | Usuarios de Graylog | Sí | Sí (Graylog) | Medio |
| none | Desactivar logs, contenedores temporales | No | No | Ninguno |
json-file y syslog son los más comunes. json-file para depuración local y despliegues ligeros; syslog cuando ya tienes rsyslog o syslog-ng y quieres enviar logs a un sistema central.
journald delega en systemd journal. En servidores gestionados con systemd (casi cualquier Linux moderno), puedes consultar con journalctl.
fluentd y gelf apuntan a recolección centralizada. fluentd puede enviar a Elasticsearch, Kafka, almacenamiento en la nube, etc.; gelf es el formato de Graylog. Requieren un servicio de recolección aparte, útil en clústeres con muchos contenedores.
none desactiva los logs por completo. Para tareas batch o contenedores efímeros donde el log no importa, ahorra recursos.
¿Cómo elegir?
Despliegue en un solo host o desarrollo: json-file con rotación (siguiente sección). Empresa con syslog: syslog, reutilizando la infra. Clúster con logs centralizados: fluentd o Loki (más abajo). Contenedor temporal sin logs útiles: none.
2. Rotación de logs en la práctica
Volvamos al problema inicial: un log de 12 GB. ¿Cómo evitarlo? Parámetros de rotación.
json-file admite tres parámetros clave:
- max-size: tamaño máximo de un archivo. Al superarlo, Docker crea uno nuevo y renombra los anteriores. Ej.:
max-size=10m→ 10 MB por archivo. - max-file: cuántos archivos históricos conservar. Al superar el límite, se borra el más antiguo. Ej.:
max-file=3→ hasta 3 históricos + el actual. - compress: comprimir archivos rotados. Por defecto false; true ahorra disco con un poco más de CPU.
La combinación controla el espacio en disco. Con max-size=10m, max-file=3, el máximo ronda 30 MB (menos si comprimes).
Configuración: global vs por contenedor
Puedes definir la rotación en tres niveles:
1. Configuración global (daemon.json)
Para todos los contenedores, de una vez. En /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
Reinicia el daemon: sudo systemctl restart docker. Los contenedores nuevos heredan la config.
Nota: solo afecta a contenedores creados después. Los existentes hay que tratarlos aparte o recrearlos.
2. Por contenedor (docker run)
Para parámetros específicos:
docker run -d \
--name nginx \
--log-driver json-file \
--log-opt max-size=50m \
--log-opt max-file=5 \
--log-opt compress=true \
nginx:alpine
En aplicaciones de mucho tráfico puedes ampliar, p. ej. max-size=50m, max-file=10.
3. Docker Compose
Lo más habitual en producción:
version: "3.9"
services:
webapp:
image: webapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
compress: "true"
nginx:
image: nginx:alpine
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
Cada servicio puede tener su propia config.
Valores recomendados en producción
La guía práctica de SigNoz (2024) sugiere:
- Desarrollo/pruebas:
max-size=10m, max-file=3, suficiente. - Tráfico medio:
max-size=50m, max-file=5, más historial para diagnóstico. - Alto tráfico:
max-size=100m, max-file=10, para no perder historial por rotación demasiado agresiva.
Los números exactos dependen de tu caso. El principio: equilibrar capacidad de disco e importancia de los logs. Disco holgado y logs críticos → retén más; disco justo y logs secundarios → aprieta.
3. Comparación de recolección centralizada
La rotación en un solo host basta a veces. Con decenas de contenedores repartidos en varias máquinas, investigar implica entrar en cada servidor y ejecutar docker logs uno a uno.
La recolección centralizada agrupa todo en un solo sitio: almacenamiento y consulta unificados.
Hay tres enfoques principales:
Stack ELK (Elasticsearch + Logstash + Kibana)
ELK lleva años siendo referencia. Logstash ingiere, Elasticsearch indexa y almacena, Kibana visualiza y consulta.
Ventajas: búsqueda full-text, consultas complejas, gráficos, ecosistema maduro. Inconvenientes: mucho consumo. Elasticsearch suele usar varios GB de RAM; Logstash también pesa y su configuración tiene curva de aprendizaje.
Encaja en grandes empresas con equipo de operaciones, mucho volumen y necesidad de consultas avanzadas.
EFK (Fluentd en lugar de Logstash)
Variante de ELK con Fluentd. Más ligero (cientos de MB de RAM), muchos plugins, varias fuentes y destinos.
Más limpio que Logstash en configuración, pero Elasticsearch sigue siendo pesado. Consumo global aún alto; equipos medianos-grandes.
Loki + Promtail + Grafana
Loki (Grafana Labs) no indexa el texto completo: indexa etiquetas (nombre de contenedor, aplicación, etc.) y guarda el contenido comprimido. Las consultas usan patrones tipo grep, con rendimiento suficiente en la práctica.
Resultado: pocos cientos de MB de RAM y almacenamiento más barato que Elasticsearch. Promtail es el agente de recolección; Grafana es la interfaz, integrada con Loki.
Muy adecuado para cloud-native y Kubernetes. Equipos pequeños con presupuesto ajustado: buena relación coste/beneficio.
Tabla comparativa
| Solución | Ventajas | Desventajas | Escala | Coste |
|---|---|---|---|---|
| ELK | Potente, consultas flexibles, ecosistema maduro | Alto consumo, config compleja, almacenamiento caro | Gran empresa | Alto |
| EFK | Fluentd ligero, muchos plugins | Elasticsearch sigue pesado | Mediana-grande | Medio-alto |
| Loki | Muy ligero, bajo coste, cloud-native | Consultas más limitadas, no ideal para full-text | Pequeña/K8s | Bajo |
¿Cómo decidir?
- Equipo pequeño (< 10 personas), presupuesto limitado: Loki. Despliegue simple, pocos recursos, Grafana amigable.
- Equipo mediano (10-50), algo de operaciones: Loki o EFK según volumen.
- Gran empresa con operaciones dedicadas: ELK. Funcionalidad y ecosistema justifican la inversión.
Si ya monitorizas con Grafana, Loki encaja de forma natural: métricas y logs en la misma interfaz.
4. Errores comunes en producción
Para cerrar, varios fallos que yo cometí y conviene evitar.
1. Olvidar la rotación y llenar el disco
El más frecuente. Se despliega sin pensar en logs; meses después, alerta de disco y archivos de decenas de GB.
Recomendación: valores por defecto en daemon.json para contenedores nuevos. No confíes en acordarte de --log-opt en cada docker run: la gente olvida; la config no.
2. Perder logs al reiniciar contenedores
Con json-file, al eliminar el contenedor se borran los logs. Si reinicias con docker rm + docker run en lugar de docker restart, pierdes el historial.
Problema al investigar un crash de madrugada: el contenedor ya se recreó y los logs anteriores desaparecieron.
Recomendación:
- Usa
docker restartcuando baste con reiniciar el proceso. - Para apps críticas, envía logs con fluentd o syslog a almacenamiento externo.
- Haz backup periódico de logs importantes en producción.
3. Dirección de Fluentd incorrecta
Con el driver fluentd, los logs van por TCP a Fluentd. Si la dirección falla, el contenedor arranca igual pero no se recogen logs: crees que están centralizados y se pierden en el camino.
Ejemplo:
docker run -d \
--log-driver fluentd \
--log-opt fluentd-address=127.0.0.1:24224 \
--log-opt tag="docker.{{.Name}}" \
my-web-app
fluentd-address debe coincidir con donde escucha Fluentd. Puerto por defecto 24224, TCP.
Diagnóstico:
- Comprueba que Fluentd corre:
curl http://localhost:24224onetstat -tlnp | grep 24224. docker inspect <ID-contenedor>para ver el driver configurado.- Revisa los logs de Fluentd por tráfico entrante de Docker.
4. Monitorización y alertas
Configurar no basta; hay que vigilar.
Dos métricas clave:
- Espacio en disco: tamaño de
/var/lib/docker/containersde forma periódica. Alerta, p. ej. por encima de 10 GB. - Latencia de logs: en recolección centralizada, latencia de escritura en Fluentd o Loki. Retrasos altos pueden indicar red o cuello de botella en almacenamiento.
Prometheus + Grafana, o un script con Cron para revisiones simples.
Resumen
Puntos clave de la gestión de logs en Docker:
- Driver: json-file lo más general; syslog con infra empresarial; fluentd para centralizar.
- Rotación:
max-size+max-file; global en daemon.json o por contenedor/Compose. - Centralización: Loki para equipos pequeños; ELK para escala y presupuesto mayores.
- Evitar problemas: rotación por defecto, no perder logs al recrear, verificar Fluentd, monitorizar disco.
Plantilla rápida:
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
Acción: si aún no tienes rotación, revísalo ahora. Mira si hay logs enormes en /var/lib/docker/containers, añade parámetros en daemon.json y reinicia Docker. Son minutos que te ahorran levantarte a las dos de la madrugada por un disco lleno.
Configuración de rotación de logs de Docker
Configura la rotación de logs de contenedores Docker para evitar que los archivos saturen el disco
⏱️ Estimated time: 10 min
- 1
Step 1: Comprobar el estado actual de los logs
Ejecuta estos comandos para ver el uso de logs de los contenedores:
```bash
# Ver tamaño total del directorio de logs
du -sh /var/lib/docker/containers
# Ver tamaño de logs por contenedor
docker ps -q | xargs -I {} sh -c 'echo -n "{}: "; docker inspect --format="{{.LogPath}}" {} | xargs du -sh 2>/dev/null || echo "N/A"'
```
Si algún contenedor supera 1 GB, conviene configurar la rotación. - 2
Step 2: Configurar rotación global por defecto
Edita `/etc/docker/daemon.json` y añade la configuración del driver de logs:
```json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
```
Parámetros:
- max-size: 10 MB máximo por archivo
- max-file: conservar 3 archivos históricos
- compress: comprimir archivos antiguos para ahorrar espacio - 3
Step 3: Reiniciar Docker para aplicar
Reinicia el servicio para que la configuración surta efecto:
```bash
sudo systemctl restart docker
```
**Nota**: la configuración global solo aplica a contenedores nuevos; los existentes hay que recrearlos o configurarlos por separado. - 4
Step 4: Verificar la configuración
Crea un contenedor de prueba para comprobar que la configuración funciona:
```bash
# Crear contenedor de prueba
docker run -d --name test-nginx nginx:alpine
# Ver configuración de logs
docker inspect --format='{{.HostConfig.LogConfig}}' test-nginx
```
La salida debe mostrar los parámetros `max-size=10m,max-file=3`. - 5
Step 5: Limpiar logs de contenedores antiguos (opcional)
Si los logs de contenedores existentes son demasiado grandes, puedes limpiarlos manualmente:
```bash
# Método 1: vaciar el archivo de log (sin reiniciar el contenedor)
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' nombre-contenedor)
# Método 2: recrear el contenedor (recomendado)
docker rm -f nombre-contenedor
docker run ... # recrear con parámetros de log
```
Tras recrear, el nuevo contenedor heredará la configuración global.
FAQ
¿Cuál es el driver de logs por defecto de Docker y por qué no limita el tamaño?
¿Cómo combinar max-size y max-file de forma razonable?
¿Los logs siguen ahí tras eliminar el contenedor? ¿Cómo persistirlos?
¿ELK o Loki? ¿Cuál conviene a un equipo pequeño?
¿Qué pasa si la dirección de Fluentd está mal configurada? ¿Cómo diagnosticarlo?
¿Cómo aplicar nueva rotación de logs a contenedores existentes?
¿Cómo monitorizar el uso de disco de los logs de Docker?
8 min de lectura · Publicado el: 30 abr 2026 · Actualizado el: 21 ago 2026
Guía práctica de Docker
Si llegaste desde búsqueda, lo más rápido es ir al artículo anterior o siguiente de esta misma serie.
Anterior
Guía completa de limpieza de logs en Docker: 5 métodos para evitar que json.log llene el disco
¿Los archivos de log de Docker crecen sin parar y llenan el disco? Aprende a limpiar json.log, configurar la rotación de logs y elegir el driver adecuado para resolver de raíz el problema de logs que saturan el disco.
Parte 34 de 38
Siguiente
Guía de depuración de contenedores Docker: la forma correcta de usar exec
Explicación detallada de cómo usar docker exec para depurar contenedores: diferencias entre exec y attach, instalación de herramientas, permisos de usuario y escenarios prácticos, con ejemplos completos de comandos.
Parte 36 de 38



Comentarios
Inicia sesión con GitHub para dejar un comentario