Gerenciamento de logs no Docker: de drivers à coleta centralizada

O celular vibrou. Alerta de disco no servidor de produção, limite em 85%.
Abri o notebook ainda meio no susto e entrei por SSH. Um df -h mostrou o problema: a partição raiz só tinha 12% de espaço livre. Depois de uma rodada de investigação, achei o culpado em /var/lib/docker/containers: um contêiner Nginx que estava rodando havia duas semanas, com um arquivo de log já inflado para 12GB.
Muita gente não sabe que o Docker, por padrão, não limita o tamanho dos logs. Aquele contêiner gerava dezenas de milhares de linhas de acesso por dia, e o driver json-file registrava tudo sem reclamar. Em duas semanas, o disco ficou cheio.
Depois apaguei aquele arquivo de log e configurei rotação em todos os contêineres. Essa brincadeira foi até quatro da manhã.
Na semana seguinte, organizei com calma o tema de gerenciamento de logs no Docker: escolha de drivers, parâmetros de rotação e coleta centralizada em ambientes com vários contêineres. Este artigo é o resumo dessa queda no buraco.
1. Panorama dos drivers de log do Docker
Primeiro, um conceito básico: os logs de um contêiner Docker não são escritos de qualquer jeito. O “driver de log” decide para onde os logs vão e como eles são armazenados.
O Docker oferece vários drivers de log, cada um com cenários próprios. Quando você executa um contêiner, o Docker usa por padrão o driver json-file: ele grava o conteúdo de stdout e stderr em um arquivo local no formato JSON. Esse arquivo fica em /var/lib/docker/containers/<ID-do-container>/<ID-do-container>-json.log.
A vantagem do json-file é a simplicidade. Não exige configuração extra, o formato dos logs é uniforme e comandos do Docker, como docker logs, conseguem ler tudo diretamente. A armadilha também é clara: por padrão, não existe limite de tamanho. Enquanto o contêiner roda, os logs continuam acumulando até o disco estourar.
A tabela abaixo resume 6 drivers comuns:
| Driver | Cenário indicado | Suporte a estrutura | Depende de serviço externo | Impacto em desempenho |
|---|---|---|---|---|
| json-file | Debug em desenvolvimento, deploy em máquina única | Sim (JSON automático) | Não | Baixo |
| syslog | Empresas com infraestrutura syslog existente | Não (precisa de parsing) | Sim (rsyslog) | Baixo |
| journald | Ambientes systemd | Parcial | Não | Baixo |
| fluentd | Stack de observabilidade cloud-native, coleta centralizada de logs | Sim (tag personalizada) | Sim (serviço Fluentd) | Médio |
| gelf | Usuários da plataforma de logs Graylog | Sim | Sim (Graylog) | Médio |
| none | Logs desativados, contêineres temporários | Não | Não | Nenhum |
json-file e syslog são as duas escolhas mais comuns. json-file serve bem para debug local e deploys leves; syslog é mais adequado quando a empresa já tem infraestrutura syslog pronta. Nesse caso, os logs vão direto para rsyslog ou syslog-ng e o sistema centralizado cuida do resto.
O driver journald entrega os logs ao systemd journal. Se o seu servidor usa systemd para gerenciar serviços, como a maioria das distribuições Linux modernas, journald é uma opção conveniente, e os logs podem ser consultados com journalctl.
fluentd e gelf são drivers voltados à coleta centralizada. fluentd pode enviar logs para Elasticsearch, Kafka, armazenamento em nuvem e vários outros backends; gelf é o formato específico da plataforma Graylog. Ambos fazem sentido em ambientes de cluster com muitos contêineres, mas exigem um serviço adicional de coleta de logs.
O driver none simplesmente desativa os logs. Em alguns contêineres temporários ou tarefas em lote, onde os logs não importam, usar none economiza um pouco de recurso.
Como escolher?
Deploy em uma única máquina ou debug em desenvolvimento: json-file resolve, desde que você configure rotação, assunto da próxima seção. Empresa com syslog: use syslog e reaproveite a infraestrutura existente. Cluster de contêineres ou necessidade de consultar logs em um lugar só: fluentd ou Loki, que veremos mais adiante. Contêiner temporário, log sem valor: none direto.
2. Configuração prática de rotação de logs
Voltando ao problema do começo: um arquivo de log inflado para 12GB. Como evitar isso? Configure parâmetros de rotação.
O driver json-file aceita três parâmetros principais:
- max-size: tamanho máximo de um arquivo de log. Ao passar desse limite, o Docker cria um novo arquivo, e os arquivos antigos recebem numeração incremental. Por exemplo,
max-size=10mlimita cada arquivo a 10MB. - max-file: quantidade de arquivos históricos mantidos. Ao passar desse número, o arquivo mais antigo é removido. Por exemplo,
max-file=3mantém até 3 arquivos históricos + 1 arquivo atual. - compress: define se os arquivos antigos, depois da rotação, serão compactados. O padrão é false. Definir como true economiza espaço em disco, com um pequeno custo extra de CPU.
Juntos, esses três parâmetros controlam bem o espaço ocupado por logs. Com max-size=10m, max-file=3, por exemplo, os logs ocupam no máximo 30MB, menos ainda se houver compactação.
Formas de configuração: global vs contêiner individual
A rotação de logs do Docker pode ser configurada em três níveis:
1. Configuração global (daemon.json)
Serve para todos os contêineres e evita retrabalho. Em /etc/docker/daemon.json, adicione:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
Depois de alterar, reinicie o Docker daemon com sudo systemctl restart docker. A partir daí, todos os novos contêineres herdam essa configuração.
Atenção: a configuração global só vale para contêineres novos. Contêineres existentes precisam ser tratados separadamente ou removidos e recriados.
2. Configuração por contêiner (docker run)
É útil quando um contêiner específico precisa de parâmetros próprios:
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
Aplicações de alto tráfego podem usar limites mais folgados, como max-size=50m, max-file=10, permitindo um volume maior de logs.
3. Configuração no Docker Compose
Esta é a forma mais comum; em produção, deploy com Compose aparece o tempo todo:
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 serviço pode ter sua própria configuração, o que dá bastante flexibilidade.
Valores recomendados para produção
O guia prático de 2024 da SigNoz traz algumas sugestões:
- Ambiente de desenvolvimento/teste:
max-size=10m, max-file=3, suficiente para o dia a dia. - Aplicações de tráfego médio:
max-size=50m, max-file=5, retendo mais histórico para investigação. - Aplicações de alto tráfego:
max-size=100m, max-file=10, para evitar rotação rápida demais e perda de histórico.
Na prática, o número certo depende do seu cenário. O princípio é equilibrar capacidade de disco e importância dos logs. Disco grande e logs importantes: retenha um pouco mais. Disco apertado e logs pouco importantes: seja mais rígido.
3. Comparação de soluções de coleta centralizada
Em uma única máquina, rotação de logs já resolve bastante coisa. Mas, se você tem dezenas de contêineres, com logs espalhados por várias máquinas, investigar problema vira trabalho manual: entrar em cada servidor e rodar docker logs contêiner por contêiner.
Coleta centralizada de logs resolve isso: todos os logs dos contêineres vão para um lugar só, com armazenamento e consulta unificados.
Hoje, há três grupos principais de soluções:
ELK Stack (Elasticsearch + Logstash + Kibana)
ELK é a solução clássica e existe há muitos anos. Logstash coleta logs, Elasticsearch armazena e indexa, e Kibana fornece a interface visual de consulta.
A vantagem é o conjunto de recursos: busca em texto completo, consultas complexas, gráficos e um ecossistema maduro. A desvantagem também aparece rápido: alto consumo de recursos. O Elasticsearch é um serviço pesado por natureza, frequentemente usando vários GB de memória; Logstash também não é leve, a configuração é complexa e a curva de aprendizado é alta.
Combina com empresas grandes, que têm uma equipe de operações dedicada, grande volume de logs e necessidade de consultas complexas.
EFK (Fluentd no lugar do Logstash)
EFK é uma variação do ELK que troca Logstash por Fluentd. Fluentd é mais leve, costuma consumir algumas centenas de MB de memória, tem um ecossistema rico de plugins e aceita várias fontes de entrada e saída.
A configuração fica um pouco mais limpa que no Logstash, mas o peso do Elasticsearch continua o mesmo. O consumo geral de recursos ainda é relativamente alto, então a solução faz mais sentido para equipes médias ou grandes.
Loki + Promtail + Grafana
Loki é o sistema de logs da Grafana Labs e tem uma ideia de design bem diferente: ele não cria índice de texto completo. Indexa apenas rótulos dos logs, como nome do contêiner ou nome da aplicação, e armazena o conteúdo em arquivos compactados. Na consulta, usa uma lógica parecida com grep, com desempenho bom o bastante para muitos casos.
Esse desenho deixa o Loki muito leve: consumo de memória na casa de algumas centenas de MB e custo de armazenamento bem menor que o Elasticsearch. Promtail é o agente de coleta próprio do Loki e tem configuração simples; Grafana faz a interface de consulta e se integra diretamente ao Loki.
É uma boa opção para ambientes cloud-native, especialmente Kubernetes. Para equipes pequenas e orçamento limitado, Loki costuma entregar um bom custo-benefício.
Tabela comparativa
| Solução | Vantagens | Desvantagens | Escala indicada | Custo |
|---|---|---|---|---|
| ELK | Recursos completos, consultas flexíveis, ecossistema maduro | Alto consumo de recursos, configuração complexa, custo alto de armazenamento | Grandes empresas | Alto |
| EFK | Fluentd é leve, plugins abundantes | Elasticsearch continua pesado, configuração ainda complexa | Médio/grande | Médio-alto |
| Loki | Muito leve, baixo custo, amigável a cloud-native | Consulta mais limitada, não é ideal para busca em texto completo | Pequeno/K8s | Baixo |
Como escolher a solução?
Minha regra simples:
- Equipe pequena (< 10 pessoas), orçamento limitado: Loki. Deploy simples, baixo consumo de recursos e interface amigável no Grafana.
- Equipe média (10-50 pessoas), com alguma capacidade de operações: Loki ou EFK, dependendo do volume de logs.
- Empresa grande, com equipe profissional de operações: ELK. Recursos completos, ecossistema maduro e investimento justificável.
Se você já usa Grafana para monitoramento, Loki quase vira uma escolha natural: métricas e logs no mesmo lugar, com uma experiência bem fluida.
4. Armadilhas comuns em produção
Para fechar, algumas armadilhas que já encontrei na prática.
1. Esquecer a rotação e lotar o disco
É a mais comum. Muita gente sobe contêiner sem pensar em rotação de logs. Meses depois, vem o alerta de disco; na investigação, aparece um arquivo de log com dezenas de GB.
Recomendação: configure valores padrão globais em daemon.json, para que contêineres novos herdem automaticamente. Não dependa de lembrar parâmetros a cada docker run: pessoas esquecem, configuração não.
2. Reiniciar contêiner e perder logs
O driver json-file tem uma característica importante: quando o contêiner é removido, os arquivos de log vão embora junto. Se você “reinicia” usando docker rm + docker run, em vez de docker restart, os logs desaparecem.
Isso complica a investigação de problemas históricos. Imagine um contêiner que travou de madrugada; você quer ver os logs antes da falha, mas o contêiner já foi recriado e os logs sumiram.
Recomendações:
- Use
docker restartpara reiniciar contêineres, não remover e recriar. - Para aplicações críticas, envie logs para armazenamento externo com drivers fluentd ou syslog, evitando perda quando o contêiner é removido.
- Faça backup periódico de logs importantes, especialmente em produção.
3. Endereço do Fluentd configurado errado
Ao usar o driver fluentd, os logs são enviados por TCP ao serviço Fluentd. Se o endereço estiver errado, o contêiner inicia sem erro, mas os logs não são coletados. Você acha que os logs estão no armazenamento centralizado, quando na verdade ficaram perdidos no caminho.
Exemplo de configuração:
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 precisa bater com o endereço real em que o serviço Fluentd está escutando. A porta padrão é 24224, via TCP.
Como diagnosticar:
- Primeiro, confirme se o serviço Fluentd está rodando:
curl http://localhost:24224ounetstat -tlnp | grep 24224. - Use
docker inspect <ID-do-container>para conferir se a configuração do driver de log está correta. - Nos logs do Fluentd, verifique se ele recebeu o fluxo de logs enviado pelo Docker.
4. Monitoramento e alertas
Gerenciamento de logs não termina depois da configuração; ainda precisa de monitoramento.
Dois indicadores importantes:
- Espaço em disco: verifique periodicamente o tamanho de
/var/lib/docker/containers. Configure um limite de alerta, por exemplo notificar ao passar de 10GB. - Latência de logs: em cenários de coleta centralizada, monitore a latência de escrita do Fluentd ou do Loki. Latência alta pode indicar problema de rede ou gargalo de armazenamento.
Você pode usar Prometheus + Grafana para monitorar. Ou, se quiser algo mais simples, escrever um script que roda periodicamente com Cron.
Resumo
O artigo passou pelos pontos principais do gerenciamento de logs no Docker:
- Escolha do driver de log: json-file é o mais universal, syslog combina com infraestrutura corporativa, fluentd serve para coleta centralizada.
- Configuração de rotação: a combinação
max-size+max-filecontrola o espaço; configuração global é mais tranquila, configuração por contêiner é mais flexível. - Coleta centralizada: equipes pequenas podem usar Loki; empresas grandes tendem a usar ELK, dependendo de escala e orçamento.
- Armadilhas práticas: rotação global padrão, prevenção de perda de logs, diagnóstico do endereço do Fluentd e monitoramento de espaço em disco.
Para fechar, um modelo rápido de configuração:
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
Ação recomendada: se você ainda não configurou rotação de logs, confira isso agora. Veja se /var/lib/docker/containers tem arquivos grandes demais, adicione os parâmetros de rotação ao daemon.json e reinicie o Docker daemon. São poucos minutos que podem poupar você de acordar às duas da manhã para resolver alerta de disco.
Configuração de rotação de logs no Docker
Configure a rotação de logs em contêineres Docker para impedir que os arquivos de log lotem o disco.
⏱️ Estimated time: 10 min
- 1
Step 1: Verifique o estado atual dos logs
Execute os comandos abaixo para ver quanto espaço os logs dos contêineres estão ocupando:
```bash
# Ver o tamanho total do diretório de logs
du -sh /var/lib/docker/containers
# Ver o tamanho dos logs de cada contêiner
docker ps -q | xargs -I {} sh -c 'echo -n "{}: "; docker inspect --format="{{.LogPath}}" {} | xargs du -sh 2>/dev/null || echo "N/A"'
```
Se algum contêiner tiver logs acima de 1GB, é hora de configurar rotação. - 2
Step 2: Configure a rotação global padrão
Edite `/etc/docker/daemon.json` e adicione a configuração do driver de log:
```json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
```
Significado dos parâmetros:
- max-size: tamanho máximo de 10MB por arquivo
- max-file: mantém 3 arquivos históricos
- compress: compacta arquivos antigos para economizar espaço - 3
Step 3: Reinicie o Docker para aplicar
Execute o comando de reinício para aplicar a configuração:
```bash
sudo systemctl restart docker
```
**Atenção**: a configuração global só vale para novos contêineres. Contêineres existentes precisam ser recriados ou configurados separadamente. - 4
Step 4: Valide a configuração
Crie um contêiner de teste para confirmar se a configuração entrou em vigor:
```bash
# Criar contêiner de teste
docker run -d --name test-nginx nginx:alpine
# Ver a configuração de log
docker inspect --format='{{.HostConfig.LogConfig}}' test-nginx
```
A saída deve mostrar os parâmetros `max-size=10m,max-file=3`. - 5
Step 5: Limpe logs antigos de contêineres (opcional)
Se algum contêiner existente já tiver logs grandes demais, dá para limpar manualmente:
```bash
# Método 1: esvaziar o arquivo de log sem reiniciar o contêiner
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' nome-do-container)
# Método 2: recriar o contêiner (recomendado)
docker rm -f nome-do-container
docker run ... # recrie passando os parâmetros de log
```
Depois da recriação, o novo contêiner herda a configuração global.
FAQ
Qual é o driver de log padrão do Docker? Por que ele não limita o tamanho?
Como combinar max-size e max-file de forma razoável?
Depois que um contêiner é removido, os logs continuam existindo? Como persistir logs?
Como escolher entre ELK e Loki? Qual faz mais sentido para uma equipe pequena?
O que acontece se o endereço do Fluentd estiver errado? Como diagnosticar?
Como aplicar uma nova configuração de rotação a contêineres já existentes?
Como monitorar o espaço em disco ocupado pelos logs do Docker?
11 min de leitura · Publicado em: 30 abr 2026 · Atualizado em: 14 jul 2026
Guia prático Docker
Se você chegou pela busca, o caminho mais rápido é ir para o post anterior ou próximo desta série.
Anterior
Guia completo para limpar logs do Docker: 5 formas de evitar que o json.log ocupe todo o disco
Os arquivos de log do Docker não param de crescer e estão lotando o disco? Aprenda a limpar o json.log, configurar a rotação de logs e escolher o driver adequado para resolver o problema de vez.
Parte 34 de 38
Próximo
Guia para depurar contêineres Docker: como usar docker exec para investigar problemas
Aprenda a usar docker exec corretamente para entrar em contêineres e depurar problemas, incluindo diferenças entre exec e attach, instalação de ferramentas, definição de usuários e exemplos completos de comandos.
Parte 36 de 38



Comentários
Entre com GitHub para comentar