Docker Compose para agente de IA: estrutura mínima em produção

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.

Fontes

Docker Composeagentes de IAinfraestruturasegredosbackup