Programa
Agentes autônomos de codificação com IA são poderosos. Eles navegam pelo seu sistema de arquivos, executam comandos de shell, fazem commits e modificam arquivos — tudo sem você digitar uma linha de código. Esse poder, porém, traz uma questão real: o que acontece se algo der errado? E se o agente modificar um arquivo de configuração que não deveria tocar ou instalar um pacote que conflita com o seu sistema?
A resposta à qual a maioria dos desenvolvedores focados em produção chega é Docker — e foi a mesma à qual voltei depois de uma sessão em que o Claude Code, muito solícito, "limpou" o .env do meu projeto porque parecia não usado. (Ele estava em uso.)
Containers criam um limite rígido entre o agente e sua máquina host — e é esse limite que faz as execuções não supervisionadas parecerem seguras, não estressantes.
Neste tutorial, vou mostrar como executar o Claude Code dentro do Docker: desde construir uma imagem mínima de base até orquestrar um aplicativo com múltiplos serviços usando o Docker Compose. No fim, você terá um fluxo de trabalho seguro e repetível para usar em qualquer projeto.
Se você se interessa pelos modelos mais novos da Anthropic, recomendo ler nossos guias sobre o Claude Opus 4.6 e o Claude Sonnet 4.6.
Como o Claude Code se integra ao Docker
Para entender por que o Docker combina tão bem com o Claude Code, vale relembrar rapidamente o que cada ferramenta faz.
Claude Code é a ferramenta de linha de comando com agentes de codificação da Anthropic, lançada em disponibilidade geral em maio de 2025. Ele roda no seu terminal, lê sua base de código e executa tarefas (refatoração, escrita de testes, gestão de fluxos de trabalho com git) por meio de prompts em linguagem natural. Nosso tutorial completo do Claude Code 2.1 traz tudo o que você precisa saber.
Docker é uma plataforma para empacotar e executar aplicações em containers leves e isolados que compartilham o kernel do SO host, mas mantêm limites rígidos de processos e sistema de arquivos. Se você é totalmente novo em Docker, recomendo conferir nosso guia sobre a plataforma gratuita Play with Docker e fazer alguns testes por lá.
O Claude Code precisa de um ambiente para rodar. O Docker fornece um ambiente reproduzível e descartável. Essa combinação é poderosa, mas para tirar o máximo dela é preciso entender o modelo de execução, os padrões de segurança e qual abordagem de implantação se encaixa no seu cenário.
Arquitetura do container e fluxo de execução
Vamos começar entendendo como uma sessão do Claude Code em container funciona no nível da requisição.
- Você envia um prompt pelo terminal do host.
- O Docker inicia o container com o CLI do Claude Code pré-instalado e o seu workspace montado como volume.
- O Claude Code lê os arquivos desse volume, raciocina sobre a base de código, executa comandos dentro do espaço de processos isolado do container e grava a saída de volta no volume montado.
- Ao fim da sessão, o sistema de arquivos efêmero do container (tudo fora do volume) é descartado.
A distinção-chave aqui é entre estado efêmero e estado persistente. Tudo o que é escrito no container, mas fora do volume montado, é deletado na limpeza. Seu workspace, que vive no host e é montado no container, permanece.
Isso significa que dependências temporárias, artefatos de build e instalações de ferramentas somem, mas seus arquivos de projeto ficam exatamente como o Claude os deixou. Essa separação é realmente tranquilizadora: antes de entendê-la, eu ficava apreensivo, assistindo às sessões do agente. Hoje eu inicio a tarefa e vou pegar um café.
Modelos de segurança e padrões seguros
Com o fluxo de execução em mente, vale ser explícito sobre o que a isolação do Docker realmente protege — e o que não protege.
Isolamento de sistema de arquivos é o principal ganho de segurança. O Claude Code só consegue ler e escrever arquivos nos caminhos que você monta explicitamente. Se você não montá-los no container, suas chaves SSH, credenciais de ~/.aws, variáveis de ambiente do host e arquivos de configuração do sistema ficam invisíveis ao agente — a menos que você os exponha deliberadamente. Porém, essa proteção só vale se você configurar os mounts com cuidado.
Uma regra crítica: nunca monte o socket do Docker do host (/var/run/docker.sock) dentro do container do Claude Code. Se o agente puder falar com o daemon do Docker no host, ele potencialmente pode subir containers privilegiados, escapar do sandbox e obter acesso de root à sua máquina.
Esse é um caminho conhecido de escalonamento de privilégios, sem boa justificativa. Já vi isso sugerido em alguns Dockerfiles da comunidade como forma de deixar o agente "gerenciar containers" — e toda vez eu quero mandar uma mensagem bem enfática ao autor.
Escolhendo o caminho de implantação certo
Além dos padrões de segurança, há mais uma decisão antes de escrever qualquer código: qual modelo de implantação se encaixa no seu caso? Existem três opções principais — e elas não são intercambiáveis.
|
Método de implantação |
Melhor para |
Principal trade-off |
|
Sandbox Docker (container único) |
Tarefas isoladas e pontuais do agente |
Sem rede entre serviços |
|
Docker Compose |
Apps com múltiplos serviços em desenvolvimento |
Mais configuração, superfície de ataque maior |
|
Devcontainers |
Ambientes padronizados para todo o time |
Requer VS Code ou IDE compatível |
Para a maioria das tarefas (rodar o agente em um único repositório, depurar um script, refatorar um módulo), um sandbox simples com Docker é o padrão mais seguro.
O Docker Compose faz sentido quando o Claude Code precisa interagir com um banco de dados, API ou frontend em execução.
Devcontainers são ideais para ambientes padronizados de time, com extensões de IDE pré-configuradas. Vale notar: o devcontainer de referência oficial da Anthropic inclui um firewall embutido que restringe conexões de saída a uma lista de confiança — e é esse isolamento que torna seguro rodar o Claude Code com --dangerously-skip-permissions para operação totalmente não supervisionada.
Neste tutorial, vamos cobrir tanto o sandbox de um único container quanto uma configuração com Compose.
Configurando um container Docker para o Claude Code
Agora que a arquitetura e as opções de implantação estão claras, vamos garantir que o ambiente esteja configurado corretamente antes de escrever qualquer código. Já vi essa etapa ser pulada mais vezes do que consigo contar — e ela é a razão mais comum para tutoriais como este falharem no meio do caminho.
Requisitos de sistema e software
Veja o que você precisa ter pronto antes do primeiro docker build:
-
Docker Desktop (macOS ou Windows) ou Docker Engine (Linux), com o daemon ativo. No macOS e Windows, a virtualização deve estar habilitada nas configurações de BIOS/firmware. No Linux, adicione seu usuário ao grupo
dockercomsudo usermod -aG docker $USER, ou prefixe cada comando Docker comsudo. -
Node.js v18 ou superior na sua máquina host, já que o CLI do Claude Code é um pacote npm. Confirme com
node --version. -
Uma chave de API da Anthropic, que você pode gerar no Claude Console.
Verifique se o próprio Docker está saudável com um teste rápido antes de seguir:
docker run --rm hello-world
Se você vir Hello from Docker!, seu daemon está respondendo corretamente e você pode prosseguir.
Autenticação e variáveis de ambiente
Com o daemon em ordem, a próxima coisa é acertar as credenciais. Injetar sua chave de API da Anthropic como variável de ambiente em tempo de execução é substancialmente mais seguro do que fazer login interativo dentro do container.
Aprendi isso da maneira difícil: logins interativos podem gravar credenciais nas camadas da imagem ou em históricos de shell que ficam no disco por muito tempo depois de você esquecer deles.
O padrão correto é passar a chave em tempo de execução usando -e:
docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" my-claude-image
Perceba que estou referenciando $ANTHROPIC_API_KEY no shell do host. A chave não é escrita no Dockerfile, não é commitada no controle de versão e não aparece em nenhuma camada da imagem. Defina uma vez no seu perfil de shell (~/.zshrc ou ~/.bashrc) e ela fluirá para cada execução de container daí em diante.
Inicialização do workspace
Com a autenticação resolvida, o último passo de preparo é criar um workspace limpo. Eu sempre crio um diretório dedicado para cada sessão do agente, em vez de apontar o Claude para um projeto existente, porque isso elimina o risco de o agente explorar códigos adjacentes que você não queria que ele tocasse.
mkdir ~/claude-docker-tutorial
cd ~/claude-docker-tutorial
echo "# My Project" > README.md
echo "def hello(): return 'world'" > app.py
Mantenha esse diretório limpo. Não copie seu .env real nem quaisquer credenciais para dentro dele. O workspace deve conter apenas o código no qual você quer que o agente trabalhe — e nada além disso. Com isso em mãos, vamos construir.
Executando o Claude Code no Docker
Com o ambiente configurado e os conceitos claros, é hora de construir. Esta seção percorre os passos: primeiro, uma imagem mínima de container único; depois, uma sessão de sandbox funcional; e, por fim, uma stack completa com Compose. Cada etapa se apoia na anterior — recomendo seguir na ordem em vez de pular passos.
1. Construindo a imagem base do container
Tudo aqui se baseia nos princípios de segurança que discutimos. A seguir, um Dockerfile mínimo que coloca esses princípios em prática, instalando o CLI do Claude Code em cima de uma imagem base enxuta do Node.js:
FROM node:20-slim
# Create a non-root user for safer execution
RUN useradd -m -u 1001 claude
# Install Claude Code CLI globally
RUN npm install -g @anthropic-ai/claude-code
# Set the working directory
WORKDIR /workspace
# Switch to non-root user
USER claude
ENTRYPOINT ["claude"]
Algumas decisões de design merecem explicação. Estou usando node:20-slim em vez de node:20-alpine porque o Alpine usa a libc musl, que às vezes causa problemas de compatibilidade com pacotes npm nativos.
Eu bati exatamente nesse problema na primeira tentativa com Alpine: o CLI do Claude Code instalou, mas caiu na primeira execução com um erro de linkagem enigmático que levou uma hora para eu rastrear até o musl.
A variante slim é baseada em Debian: leve e confiável — sem esse drama. Além disso, crio um usuário dedicado claude e alterno para ele antes do entrypoint, o que significa que o processo do agente roda sem privilégios de root e tem limitações mesmo dentro do container.
Construa a imagem com:
docker build -t claude-code:latest .
Na primeira build, o Docker baixa a imagem base e instala o CLI. Nas builds seguintes, sem mudanças no Dockerfile, você verá “CACHED” em cada camada, tornando as reconstruções quase instantâneas depois que a base está estabelecida.
2. Iniciando uma sessão de sandbox isolada
Com a imagem pronta, é hora de rodar a primeira sessão real.
Operações somente leitura
Para tarefas de leitura — como listar ou resumir arquivos — o comando básico dá conta:
docker run --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v $(pwd):/workspace \
claude-code:latest \
"List the files in this workspace and describe what each one does."
O -v $(pwd):/workspace monta seu diretório atual no container, então o comando funciona em qualquer pasta de projeto. A flag --rm remove o container automaticamente após a saída.
Operações de escrita
Para escrever, você precisa de duas flags adicionais.
A flag -u $(id -u):$(id -g) passa o UID e o GID do seu usuário host para dentro do container, dando ao processo claude permissão para escrever nos arquivos montados. Sem isso, você verá erro de somente leitura porque o usuário claude do container não corresponde ao dono dos arquivos no host.
A flag --dangerously-skip-permissions pula os prompts interativos de aprovação do Claude Code, necessários quando se roda de forma não interativa dentro de um container. O próprio limite do Docker é o que torna isso seguro.
docker run --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v $(pwd):/workspace \
-u $(id -u):$(id -g) \
claude-code:latest \
--dangerously-skip-permissions \
"Add a docstring to the hello function in app.py."

Operação de escrita com Claude Code no Docker
Depois, confira seu arquivo local: cat app.py. Se você vir a docstring, o volume está funcionando nos dois sentidos — e você já pode avançar para um setup com múltiplos serviços.
3. Orquestrando um app com múltiplos serviços
O sandbox de um container funciona bem para tarefas isoladas, mas desenvolvimento real costuma envolver múltiplos serviços rodando em paralelo. É aqui que o Docker Compose mostra seu valor.
A configuração abaixo conecta o agente Claude Code a um serviço web e a um banco PostgreSQL — um cenário representativo para muitos projetos de backend:
services:
claude:
build: .
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
volumes:
- ./workspace:/workspace
depends_on:
db:
condition: service_healthy
networks:
- app-network
web:
image: python:3.12-slim
working_dir: /app
volumes:
- ./workspace:/app
command: python -m http.server 8080
ports:
- "8080:8080"
networks:
- app-network
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: appdb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d appdb"]
interval: 5s
timeout: 3s
retries: 5
networks:
- app-network
networks:
app-network:
driver: bridge
Note que version foi omitido, pois está obsoleto no Docker Compose moderno e gera um aviso se incluído.
Mais dois detalhes importantes:
Primeiro, o serviço claude monta .:/workspace (o diretório atual), e não um subdiretório. Usar ./workspace exigiria que a subpasta existisse previamente — e o agente veria um workspace vazio.
Segundo, DATABASE_URL deve ser passado explicitamente para o agente saber como alcançar o Postgres. Sem isso, o Claude não tem string de conexão e vai pedir uma.
A linha user: "${UID}:${GID}" aplica o mesmo override de UID/GID do host que usamos nos comandos docker run standalone, garantindo que as escritas de arquivo funcionem. Exporte ambos antes de rodar:
export UID=$(id -u) GID=$(id -g)
O serviço claude não tem um command persistente — diferentemente de web e db, ele não deve rodar continuamente. Inicie os serviços de apoio primeiro e invoque o Claude sob demanda com docker compose run:
# Start the database and web service
docker compose up -d web db
# Run a one-off Claude task
docker compose run --rm \
claude \
--dangerously-skip-permissions \
"Check the database connection and summarize the schema in README.md."

Claude Code com Docker Compose
Inicie primeiro os serviços de apoio com docker compose up -d web db e acompanhe seus logs com docker compose logs -f. Repare no depends_on com condition: service_healthy.
Eu ignorei isso em um projeto anterior e perdi 20 minutos caçando erros de conexão até perceber que o Claude havia iniciado antes de o Postgres estar pronto. O health check não custa nada e evita exatamente essa dor de cabeça.
4. Fazendo a limpeza da sessão
Depois que a sessão termina, a limpeza é tão importante quanto a configuração. Containers órfãos consomem memória e atrapalham execuções futuras — e, pela minha experiência, esta é a etapa que mais se pula até algo começar a se comportar de forma estranha.
Aqui estão os comandos que você mais vai usar — e quando usar cada um:
|
Comando |
O que faz |
Quando usar |
|
|
Para e remove todos os containers da stack |
Após cada sessão com Compose |
|
|
Remove todos os containers parados |
Se você esqueceu do --rm em uma execução avulsa |
|
|
Remove containers, redes e volumes nomeados |
Reset completo — apaga o estado do banco |
|
|
Lista containers em execução |
Para confirmar que nada ficou ativo |
A flag -v no docker compose down é a que merece cuidado. Ela apaga volumes nomeados — o que significa que qualquer dado acumulado no Postgres vai embora. Eu só uso quando realmente quero um recomeço do zero. Caso contrário, docker compose down sem -v é suficiente.
Integrações e troubleshooting do Claude Code no Docker
Com o fluxo principal rodando bem, vamos ver como estendê-lo — e como depurar quando algo quebra.
Integrando modelos locais e extensões
O Claude Code permite redirecionar a inferência para qualquer endpoint local compatível com Anthropic via ANTHROPIC_BASE_URL. O Docker Model Runner, embutido no Docker Desktop, expõe exatamente essa API, tornando a integração nativa no ecossistema Docker.
Baixe um modelo e aponte o Claude Code para o endpoint local:
docker model pull ai/smollm2
ANTHROPIC_BASE_URL=http://localhost:12434 claude --model ai/smollm2 "List the files of the repository."
Este é um padrão diferente do sandbox em container que vimos antes. Aqui, o Claude Code roda no host e a inferência fica local via Docker Model Runner — nenhuma chamada de API sai da sua máquina.
Além de modelos locais, você pode estender o alcance do Claude Code por meio de servidores MCP (Model Context Protocol). Se não conhece, nosso guia de MCP é um ótimo ponto de partida.
O MCP Toolkit do Docker oferece mais de 200 servidores MCP pré-prontos e conteinerizados — cobrindo GitHub, Jira, Supabase e muito mais — dando ao Claude Code acesso com permissões a essas ferramentas sem expor credenciais brutas de API.
Juntos, esses dois pontos de extensão dão a você controle real tanto sobre onde a inferência acontece quanto sobre quais serviços externos o agente pode alcançar.
Otimizando a performance de build
À medida que seu Dockerfile cresce, o tempo de build pode virar gargalo. Builds multiestágio resolvem isso separando instalação da imagem de runtime:
# Build stage
FROM node:20-slim AS builder
RUN npm install -g @anthropic-ai/claude-code
# Runtime stage
FROM node:20-slim
COPY --from=builder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=builder /usr/local/bin/claude /usr/local/bin/claude
RUN useradd -m -u 1001 claude
USER claude
WORKDIR /workspace
ENTRYPOINT ["claude"]
A ordem das camadas importa tanto quanto a estrutura — e eu demorei mais do que gostaria para acertar isso.
Instruções que mudam raramente (como instalação de pacotes do sistema) vão no topo. As que mudam com frequência (como copiar arquivos-fonte) vão mais para baixo. Isso maximiza acertos de cache e transforma rebuilds de 30 segundos em quase instantâneos.
Depurando falhas comuns de integração
Mesmo com uma configuração bem estruturada, problemas acontecem. Aqui vai um ciclo de debug repetível para os sintomas que mais encontro. Primeiro o sintoma, depois o comando para rodar:
-
Saída de rede bloqueada: o Claude Code não alcança a API da Anthropic. Rode
docker run --rm alpine wget -qO- https://api.anthropic.compara verificar saída. Se falhar, chequedocker network inspect bridgeem busca de configurações de proxy. -
Volumes montados incorretamente: o Claude Code diz que não encontra arquivos. Rode
docker run --rm -v $(pwd):/workspace alpine ls /workspace. Se a listagem vier vazia, seu caminho está errado. Confirme se o diretório existe antes de tudo. -
Cache de build obsoleto: você atualizou o Dockerfile, mas o comportamento não mudou. Force rebuild completo com
docker build --no-cache -t claude-code:latest .. -
Falhas de conexão entre serviços no Compose: um serviço não alcança outro. Serviços se comunicam pelos nomes dos serviços (
db,web), não porlocalhost. Rodedocker compose exec web ping dbpara testar alcançabilidade. Se falhar, os serviços não estão na mesma rede.
Conclusão
Rodar o Claude Code dentro do Docker traz algo realmente valioso: a liberdade de deixar um agente autônomo trabalhar à vontade, sabendo que o que ele pode tocar está estritamente delimitado.
Neste tutorial, passei por construir uma imagem mínima sem root, gerenciar volumes de workspace, orquestrar aplicações com múltiplos serviços usando Docker Compose e diagnosticar as falhas de integração mais comuns.
O setup me tomou uma tarde para acertar — e mudou completamente como eu encaro desenvolvimento assistido por agentes. Eu delego tarefas inteiras em vez de acompanhar cada passo — e o limite imposto pelo Docker é o que torna isso possível.
Daqui, dois caminhos valem a exploração:
Primeiro, avalie templates de devcontainer para o seu time. O devcontainer de referência do Claude Code no GitHub inclui um firewall pré-configurado que restringe conexões de saída a domínios confiáveis. Segundo, experimente o Docker MCP Toolkit para dar ao Claude Code acesso estruturado às suas ferramentas atuais: GitHub, bancos de dados, sistemas de gestão de projetos e mais.
Por fim, coloque um lembrete para atualizar suas imagens base periodicamente. Imagens Docker acumulam vulnerabilidades com o tempo, e um rápido docker pull node:20-slim seguido de rebuild leva apenas alguns minutos.
Se você tem interesse em desenvolver aplicações de IA, recomendo muito se inscrever na nossa trilha de habilidades AI Engineering with LangChain. Os cursos são IA-nativos, então você terá um tutor pessoal que te encontra no seu nível exato e te ajuda a alcançar suas metas no seu ritmo.
FAQs sobre Claude Code no Docker
Como integrar o Claude Code ao Docker Compose?
Adicione um serviço claude ao seu arquivo Compose, com sua chave de API como variável de ambiente e o diretório do projeto montado como volume. Use docker compose run --rm claude para acioná-lo sob demanda, em vez de mantê-lo rodando continuamente como os serviços web ou de banco de dados.
Como o Claude Code lida com permissões e segurança em um container?
Por padrão, o Claude Code pede aprovação antes de escrever arquivos. Dentro de um container, esses prompts não podem ser respondidos interativamente, então você passa --dangerously-skip-permissions para pulá-los. O limite do Docker é o que torna isso seguro: o agente só pode tocar os arquivos no seu workspace montado.
O Claude Code pode ser usado com modelos customizados ou apenas com modelos da Anthropic?
O Claude Code aceita endpoints de inferência personalizados via ANTHROPIC_BASE_URL. Você pode apontá-lo para o Docker Model Runner para rodar modelos como ai/smollm2 inteiramente na sua máquina, sem chamadas de API saindo do host.
Quais são as melhores práticas para usar o Claude Code em uma base de código grande no Docker?
Monte apenas o subdiretório de que o agente precisa, em vez do repositório inteiro; use um arquivo CLAUDE.md para dar contexto ao agente sobre a estrutura do projeto; e rode /init dentro da sessão para o Claude Code indexar a base de código antes de começar o trabalho.
Quais são as limitações de usar o Claude Code com arquiteturas complexas?
A principal limitação é o tamanho da janela de contexto. O Claude Code só consegue raciocinar sobre o que cabe no contexto ativo, então bases muito grandes exigem tarefas focadas em módulos específicos. Em setups com múltiplos serviços, todos precisam estar na mesma rede do Docker, e o serviço claude precisa de variáveis de ambiente explícitas para qualquer string de conexão de banco ou API que precise alcançar.
Como fundador da Martin Data Solutions e cientista de dados freelancer, engenheiro de ML e IA, tenho um portfólio diversificado em regressão, classificação, PNL, LLM, RAG, redes neurais, métodos de conjunto e visão computacional.
- Desenvolveu com sucesso vários projetos de ML de ponta a ponta, incluindo limpeza de dados, análise, modelagem e implantação no AWS e no GCP, fornecendo soluções impactantes e dimensionáveis.
- Criou aplicativos da Web interativos e dimensionáveis usando Streamlit e Gradio para diversos casos de uso do setor.
- Ensinou e orientou alunos em ciência e análise de dados, promovendo seu crescimento profissional por meio de abordagens de aprendizagem personalizadas.
- Projetou o conteúdo do curso para aplicativos RAG (retrieval-augmented generation) adaptados aos requisitos da empresa.
- Criou blogs técnicos de IA e ML de alto impacto, abordando tópicos como MLOps, bancos de dados vetoriais e LLMs, obtendo um envolvimento significativo.
Em cada projeto que assumo, certifico-me de aplicar práticas atualizadas em engenharia de software e DevOps, como CI/CD, code linting, formatação, monitoramento de modelos, rastreamento de experimentos e tratamento robusto de erros. Tenho o compromisso de fornecer soluções completas, transformando insights de dados em estratégias práticas que ajudam as empresas a crescer e tirar o máximo proveito da ciência de dados, do machine learning e da IA.



