Claude Code no Docker

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;

5 – Diversidade

Algumas dicas e truques!

5.1 – Desviando para outros modelos

Usando API do DeepSeek no Claude Code:

Bash
# Exporte no terminal ou inclua no container
export ANTHROPIC_BASE_URL="https://api.deepseek.com/anthropic";
export ANTHROPIC_AUTH_TOKEN="your_actual_deepseek_api_key";
export ANTHROPIC_MODEL="deepseek-v4-pro";
export CLAUDE_CODE_EFFORT_LEVEL="max";

# Entrar na pasta de trabalho
cd /workspace;

# Rodar o claude:
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