Claude Code no Docker

há 7 horas 1

Saudações.

Hoje vou ensinar como usar o Claude Code no Docker.

O Claude Code é hoje o “estado de arte” em agentes de IA, com a única desvantagem o preço do mega token!

Pré-requisitos:

  • Servidor, VPS ou VM com Linux;
  • Docker;

1 – Sobre o Claude Code

O Claude Code é um atente em interface de terminal (TUI – Terminal User Interface), e recentemente lançaram o Claude Desktop para ajudar os usuários que tem medinho de digitar em tela preta.

Visto que ele pode ser instalado no Linux, ele é totalmente apto a rodar em containers.

2 – Claude Code no Docker

Publiquei a imagem no Docker Hub em tmsoftbrasil/claude-code:latest, logo você pode pular esse capítulo e usá-lo no capítulo 3.

Leia os tópicos abaixo para entender a engenharia da imagem.

2.1 – Caminhos e volumes

Esses caminhos precisam ser mapeados e direcionado para volumes, assim o container separa:

  • Programas: Os binários e bibliotecas de códigos;
  • Dados: Configurações e informações acumuladas pelo OC;
  • Cache: Arquivos gerados para acelerar a execução;
  • Workspace: Projeto de código onde serão produzidos os artefatos do agente, como códigos, documentações, etc;

Caminhos que configurei:

VolumePropósito
/dataVolume para todas as informações do Claude, memória, credenciais, skills, etc, requer explicitamente montagem em volume
/cacheCache e arquivos que não precisam ser armazenados a longo prazo, não requer montagem em volume, recomendado usar em tmpfs com opções rw,exec,suid,mode=1777,dev,size=1024m, se preferir reinicializações rápidas, crie um volume persistente.
/workspacePasta de trabalho padrão do agente. Montar volume em uma pasta do host onde os resultados do Claude serão armazenados e retidos.

2.2 – Serviços

Criei os seguintes serviços no container usando supervisor (supervisord como init, pid 1):

  • cron: O crontab foi criado e iniciado, cada pasta em /data/cron/ possui um temporizador de execução de scripts que forem hospedados nessas pastas, exemplo:
    • /data/cron/hourly/: Todo script aqui será executado a cada hora;
    • /data/cron/daily/: Todo script aqui será executado uma vez por dia.
  • ssh: O OpenSSH Server foi iniciado e opera na porta 22/tcp, arquivos para mapear cadastro de chaves públicas:
    • /data/ssh/trusted_keys: Chaves públicas de usuários do container;
    • /data/.ssh/authorized_keys: Chaves públicas de usuários do host (mapeie via volume bind em /root/.ssh/authorized_keys);

3 – Rodando Claude Code no Docker

Vamos rodar o OC no Docker, criando o container tmsoftbrasil/claude-code.

3.1 – Rede Docker

Criando a rede para containers (network_public):

Bash

# Rede de containers docker network create network_public \ -d bridge \ -o com.docker.network.bridge.name=br-net-public \ -o com.docker.network.driver.mtu=1500 \ -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \ --subnet 10.249.0.0/16 \ --gateway 10.249.255.254;

3.2 – Volume

A pasta /workspace dentro do container deve ser mapeada na pasta onde estará seu projeto de software no HOST, pasta: /storage/claude-code-test/workspace.

A pasta /data retem as informações do próprio Claude Code, nesse exemplo vou armazenar tudo em /storage/claude-code-test/data para você testar e aprender (depois você personaliza).

3.3 – Container do Claude

Comando para rodar no “docker run” completo, personalize a gosto:

Bash

#!/bin/sh # Variaveis NAME="claude-code-test"; IMAGE="tmsoftbrasil/claude-code:latest"; # Diretorio de dados persistentes: mkdir -p /storage/claude-code-test/data; mkdir -p /storage/claude-code-test/workspace; # Renovar/rodar docker container rm -f $NAME 2>/dev/null docker container run \ -d \ --user root \ --restart always \ --name $NAME \ --hostname $NAME.intranet.br \ \ --cpus 2.0 \ --cpu-shares 1024 \ --memory 2g \ --memory-swap 2g \ --memory-reservation 1g \ --shm-size 1g \ \ --network network_public \ --ip 10.249.111.202 \ -p 8822:22 \ \ --tmpfs /run:rw,size=32m \ --tmpfs /cache:rw,exec,suid,mode=1777,dev,size=1024m \ \ -v /storage/claude-code-test/data:/data \ -v /storage/claude-code-test/workspace:/workspace \ \ -v /var/run/docker.sock:$(readlink -f /var/run/docker.sock) \ -v /root/.ssh/authorized_keys:/data/.ssh/authorized_keys:ro \ \ -w /workspace \ \ $IMAGE $ARG; # Acesso echo; echo; echo "claude-code"; echo " Container.......: $NAME"; echo " Acesso ssh......: ssh root@$FQDN -p 9622"; echo " Acesso web......: https://$FQDN"; echo " Docker shell....: docker exec -it $NAME bash;"; echo; echo;

3.4 – Stack para Compose

Caso prefira no modelo de Stack para docker compose:

YAML

# docker-compose.yml services: claude-code-test: image: tmsoftbrasil/claude-code:latest container_name: claude-core-test hostname: claude-code-test.intranet.br user: root restart: always working_dir: /workspace # Recursos deploy: resources: limits: cpus: "2.0" memory: 2g reservations: memory: 1g cpu_shares: 1024 mem_swappiness: 0 shm_size: 1g # Limites extras (sem suporte em deploy, usando extensão direta) memswap_limit: 2g # Rede networks: network_public: ipv4_address: 10.249.111.204 ports: - "8022:22" # tmpfs tmpfs: - /run:rw,size=32m - /cache:rw,exec,suid,mode=1777,dev,size=1024m # Volumes volumes: - /storage/opencode-test/data:/data - /storage/opencode-test/workspace:/workspace - /var/run/docker.sock:/var/run/docker.sock - /root/.ssh/authorized_keys:/data/.ssh/authorized_keys:ro networks: network_public: external: true

4 – Primeiro acesso

Obtenha shell no container “claude-code-test“:

Bash

# Obter shell no container: docker exec -it claude-code-test bash; # Rodar Claude: claude; # Ou, rodar direto o claude dentro do container: docker exec -it claude-code-test claude;

Agora é contigo. Use sua criatividade.

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com

Se até uma formiga tem um propósito,
quem é você para não ter?
Gui Fleury