
Docker Compose para agente de IA: estrutura mínima em produção
Como montar um Docker Compose para agente de IA com volumes, segredos e healthchecks, para reiniciar e fazer backup de forma previsível.
Quer aplicar isso na sua empresa?
Agendar conversa com o Juan →Docker Compose para agente de IA: estrutura mínima em produção
Para subir um agente de IA com Docker Compose em produção, o mínimo é um arquivo compose com versões de imagem fixas, um volume nomeado para o estado, segredos fora da imagem, healthchecks que indicam se o agente está apto a trabalhar e uma política de reinício explícita. O backup entra como rotina testada, não como esperança. Com isso, reiniciar o servidor ou atualizar uma imagem deixa de ser um evento imprevisível.
Principais pontos
- Comece com poucos serviços: o agente, um banco de dados e uma rotina de backup. Cada serviço extra precisa de um motivo claro.
- Separe configuração (somente leitura), estado (volume nomeado) e segredos (arquivos montados em memória, fora da imagem e do repositório).
- Healthcheck bom verifica o que o agente controla, como configuração e acesso ao banco, e não depende de chamar o provedor do modelo a cada intervalo.
- Reinício automático não substitui monitoramento: o Docker marca um contêiner como unhealthy, mas não o reinicia por isso.
- Backup só existe depois de uma restauração testada em outro ambiente, com retenção e acesso definidos.
Quais serviços entram na estrutura mínima?
A tentação é montar uma arquitetura completa no primeiro dia: fila, cache, banco vetorial, painel, proxy, orquestrador. Para um agente que atende um fluxo real (por exemplo, responder dúvidas e encaminhar casos a uma pessoa), três peças costumam bastar.
- agent: o processo do agente, com o código, as ferramentas permitidas e o registro de decisões.
- db: um banco relacional (PostgreSQL é uma escolha comum) para conversas, estado dos fluxos e logs de decisão.
- backup: um serviço que só roda sob demanda, usando um profile do Compose, para gerar cópias do banco e dos arquivos de estado.
Se o agente precisa receber webhooks, por exemplo de um provedor de WhatsApp, acrescente um proxy reverso na frente, e somente ele publica portas no servidor. O banco nunca deve ter a seção ports. Ele conversa com o agente por uma rede interna do Compose, e isso já elimina uma categoria inteira de exposição acidental. Para quem vai expor um gateway de agente na internet, vale revisar o checklist de segurança do OpenClaw Gateway antes de abrir qualquer porta.
Algumas decisões pequenas no arquivo compose valem mais do que parecem:
- Fixe a versão das imagens com uma tag específica, nunca com latest. Atualizar vira uma decisão sua, não uma surpresa do pull.
- Defina restart: unless-stopped para o agente e o banco. O contêiner volta após queda ou reboot do servidor, mas respeita uma parada manual.
- Configure rotação de logs no driver json-file (campos max-size e max-file), para que o disco não encha em silêncio.
- Rode o agente com usuário sem privilégios, sistema de arquivos somente leitura quando possível e tmpfs para diretórios temporários.
- Defina limites de memória e CPU no serviço do agente, para que um problema nele não derrube o banco.
Como organizar volumes sem perder o estado do agente?
A regra prática é separar três tipos de dado e tratar cada um de um jeito.
- Código e dependências: vivem na imagem. Não monte o diretório do código por cima em produção.
- Configuração: arquivos de prompts, lista de ferramentas permitidas e limites. Monte como bind mount somente leitura, versionados no repositório.
- Estado: dados do banco, arquivos de memória, filas locais e registros de decisão. Vão em volumes nomeados, gerenciados pelo Docker.
O estado é o que você não pode perder. Se o agente guarda histórico de conversa, aprovações humanas e logs de decisão, esse material precisa sobreviver a uma troca de imagem, a um docker compose down e a uma migração de servidor. Volumes nomeados sobrevivem a esses eventos, desde que você não use a opção que remove volumes junto com o down. Vale registrar isso no procedimento de operação, porque é um erro comum de quem está com pressa.
A documentação do Docker sobre volumes descreve como fazer backup e restauração de um volume com um contêiner temporário. Para o banco, porém, a cópia dos arquivos com o banco ligado não é a opção mais segura. Prefira um dump lógico (no PostgreSQL, o pg_dump), que gera um arquivo consistente enquanto o banco continua atendendo.
Se o plano inclui rodar um modelo local junto do agente, o desenho muda: pesos de modelo são grandes, ficam em volume próprio e não precisam entrar no backup diário. O artigo sobre Ollama na empresa detalha esse caso.
Como tratar segredos sem expor chaves?
Chave de API do modelo, token do WhatsApp, senha do banco e segredo de webhook são os itens típicos. Três lugares onde eles não devem estar: dentro da imagem, dentro do repositório e dentro de logs.
O Compose tem um mecanismo próprio para isso. Você declara os segredos na seção secrets de nível superior, apontando cada um para um arquivo no servidor, e lista no serviço quais segredos ele pode ler. Dentro do contêiner, cada segredo aparece como arquivo em /run/secrets, com o nome que você definiu. Só os serviços listados enxergam cada um deles.
O ponto de atenção é que a aplicação precisa ler o valor do arquivo. Muitas imagens oficiais já aceitam variáveis com o sufixo _FILE (o PostgreSQL aceita POSTGRES_PASSWORD_FILE, por exemplo). No código do agente, o padrão é simples: se existir a variável com sufixo _FILE, leia o arquivo; senão, use a variável comum, apenas para desenvolvimento local.
Boas práticas que cabem no dia a dia:
- Arquivos de segredo ficam fora do repositório, com permissão de leitura restrita ao usuário que opera o servidor.
- O arquivo .env serve para valores não sensíveis, como nome do ambiente e nível de log. Ele não é um cofre.
- Cada serviço recebe apenas os segredos de que precisa. O serviço de backup não precisa da chave do modelo.
- Há um procedimento escrito para trocar cada segredo, incluindo quem faz e como confirmar que o agente voltou saudável.
- O agente nunca imprime segredos nem o conteúdo completo de requisições nos logs.
Também vale lembrar que segredo no contêiner não protege contra um agente manipulado. Se o agente pode ser induzido a executar ações que ele não deveria, o problema está nas permissões das ferramentas e na entrada não confiável, tema tratado em prompt injection em agentes de IA e no OWASP Top 10 para aplicações com LLM.
Healthchecks e reinício: o que realmente acontece quando algo falha?
Um healthcheck é um comando que o Docker executa dentro do contêiner em intervalos regulares. O resultado define o estado: starting, healthy ou unhealthy. Os campos principais são test, interval, timeout, retries e start_period, este último dando tempo ao processo para iniciar sem contar falhas.
Dois usos são úteis.
O primeiro é a ordem de subida. Com depends_on e a condição service_healthy, o agente só inicia depois que o banco responde. No banco, o teste costuma ser o utilitário pg_isready. A documentação do Docker sobre ordem de inicialização lembra que o próprio aplicativo deve tolerar dependências que demoram, então o agente também deve tentar reconectar com espera crescente, e não morrer na primeira falha.
O segundo é o diagnóstico. Um estado unhealthy aparece em docker compose ps e pode alimentar um alerta. Mas, no Compose comum, o Docker não reinicia um contêiner só por estar unhealthy. A política restart cobre quando o processo termina. Por isso, duas coisas combinadas funcionam melhor: o agente deve encerrar o processo quando entra em estado irrecuperável, e o servidor deve ter um monitor simples que avisa uma pessoa quando algo fica unhealthy por tempo demais.
O que o endpoint de saúde do agente deve verificar?
- A configuração foi carregada e os segredos foram lidos.
- O banco responde a uma consulta simples.
- O espaço em disco do volume de estado está acima de um mínimo.
- A fila de mensagens pendentes não está parada além do tempo aceitável.
O que ele deve evitar: chamar o provedor do modelo a cada verificação. Isso gera custo, consome limite de uso e transforma uma instabilidade externa passageira em reinícios desnecessários. Acompanhe a disponibilidade do provedor em outro lugar, com métricas e logs (os conceitos de observabilidade da documentação do OpenTelemetry ajudam a separar sinais). E mantenha limites de passos, tempo e gasto dentro do próprio agente, como descrito em agente de IA em loop infinito, porque um contêiner saudável pode estar saudavelmente gastando demais.
Como fazer backup e restauração previsíveis?
Previsível significa que você sabe o que é copiado, quando, para onde vai e quanto tempo leva para voltar. Um desenho enxuto:
- O serviço backup fica sob um profile do Compose, então não sobe junto com o restante.
- Um agendador do próprio servidor (cron ou timer do systemd) executa docker compose run --rm backup em horário fixo.
- O serviço gera um dump do banco e um arquivo compactado dos volumes de estado que importam, com data no nome.
- O resultado é criptografado e enviado para fora do servidor, em um armazenamento separado.
- Uma regra de retenção apaga cópias antigas, e um alerta avisa quando o backup falha ou não roda.
Como conversas de atendimento contêm dados pessoais, o backup é parte do tratamento de dados no sentido da LGPD. Isso pede definição de quem acessa, por quanto tempo a cópia fica guardada e onde ela está. Se o armazenamento fica em outro país, entra a discussão de transferência internacional de dados com IA e LGPD. A ANPD é a referência oficial para acompanhar a orientação regulatória.
A parte que mais se pula é a restauração. Marque um dia recorrente para restaurar a última cópia em um ambiente separado, subir o agente apontando para ela e conferir se as conversas e os logs de decisão estão lá. Anote quanto tempo levou. Esse registro vale mais do que qualquer promessa sobre o backup.
Passo a passo para subir e operar
Uma sequência de implantação que funciona para um primeiro agente:
- Escreva o arquivo compose com os serviços agent e db, a rede interna, os volumes nomeados e as imagens com versão fixa.
- Crie os arquivos de segredo no servidor, com permissões restritas, e declare-os na seção secrets.
- Implemente o endpoint de saúde do agente e configure o healthcheck de cada serviço com start_period realista.
- Ajuste depends_on com service_healthy e defina restart: unless-stopped.
- Configure rotação de logs e limites de recursos.
- Adicione o serviço backup com profile, rode uma vez manualmente e confira os arquivos gerados.
- Agende a rotina, configure o alerta de falha e faça a primeira restauração de teste.
- Simule três eventos: reinício do servidor, queda do banco e troca de um segredo. Registre o que aconteceu em cada um.
- Só então ligue o tráfego real, com transferência para uma pessoa quando o agente não souber ou não puder agir.
Cenário ilustrativo: uma empresa pequena coloca um agente para responder dúvidas frequentes no WhatsApp. Numa madrugada, o servidor reinicia depois de uma atualização do sistema. Com restart definido, o banco e o agente voltam; o agente espera o banco ficar healthy e retoma a fila de mensagens pendentes, porque o estado estava em volume nomeado. Se o banco não subisse, o estado unhealthy dispararia o alerta, e a equipe teria o procedimento de restauração já testado. Sem essas peças, a mesma madrugada terminaria com mensagens perdidas e ninguém sabendo qual cópia usar.
Como isso se conecta ao método de implantação?
O arquivo compose é a parte técnica de um processo maior. No método que seguimos, primeiro mapeamos o processo atual e a linha de base, para saber o que o agente vai tocar. Depois limitamos dados e ações: quais segredos existem, quais ferramentas o agente pode chamar e o que exige aprovação humana. Em seguida pilotamos um fluxo real, com logs e uma métrica de sucesso combinada. Por fim, transferimos a operação com o procedimento de reinício, backup e restauração documentado, e a equipe decide se expande, ajusta ou encerra.
O Compose entra principalmente nas etapas de limitar e pilotar, porque transforma decisões de segurança e operação em arquivos que podem ser revisados. Quando o ambiente for mais complexo, com vários agentes ou orquestração em cluster, vale reavaliar a ferramenta. Para um agente e um fluxo, a simplicidade costuma ser uma vantagem de operação.
Perguntas frequentes
Docker Compose serve para produção ou só para desenvolvimento? Serve para produção em cenários de um servidor e poucos serviços, desde que você fixe versões, trate segredos, configure healthchecks e tenha backup testado. Ele não oferece alta disponibilidade entre servidores por conta própria. Se o negócio exige continuidade mesmo com a falha de uma máquina, é preciso outra arquitetura.
Posso usar variáveis de ambiente para guardar a chave da API do modelo? Pode, mas é a opção mais frágil, porque variáveis aparecem em inspeções do contêiner, em dumps de diagnóstico e às vezes em logs. Os segredos do Compose, montados como arquivos, reduzem esse risco e permitem controlar qual serviço lê cada valor. Use variáveis apenas para configuração não sensível.
O que devo colocar no backup de um agente de IA? O banco de dados, os arquivos de estado e os registros de decisão, além dos arquivos de configuração que estão no repositório. Imagens e pesos de modelo públicos normalmente podem ser baixados de novo. Os segredos devem ser guardados por um processo separado e controlado, não junto do backup dos dados.
Com que frequência devo testar a restauração? Defina uma rotina recorrente e também teste depois de qualquer mudança relevante, como troca de versão do banco ou de estrutura de volumes. O objetivo é saber o tempo real de recuperação e confirmar que o agente funciona com os dados restaurados. Registre cada teste, porque esse histórico mostra se o procedimento ainda é confiável.