Claude Code в контейнере — это не просто удобно, это безопасно. Ты даёшь модели полный доступ к shell, но ограничиваешь его контейнером: ничего не разъедется по системе, ключи .ssh вне досягаемости, rm -rf / максимум почистит контейнер.

Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper

Базовый Dockerfile

FROM node:22-alpine

RUN apk add --no-cache git bash curl jq python3 py3-pip

RUN npm install -g @anthropic-ai/claude-code

WORKDIR /workspace

RUN addgroup -g 1000 dev && adduser -D -u 1000 -G dev dev
USER dev

CMD ["claude"]

Собираем и запускаем:

docker build -t claude-sandbox .
docker run -it --rm \
  -v $(pwd):/workspace \
  -v claude-config:/home/dev/.claude \
  claude-sandbox

Volume claude-config сохраняет логин между запусками — не придётся каждый раз логиниться через /login.

Devcontainer для VS Code

Файл .devcontainer/devcontainer.json делает проект одной кнопкой «Reopen in Container» переносимым на любую машину:

{
  "name": "Claude Code Dev",
  "image": "node:22",
  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "postCreateCommand": "npm install -g @anthropic-ai/claude-code",
  "remoteEnv": {
    "ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}"
  },
  "mounts": [
    "source=claude-data,target=/home/node/.claude,type=volume"
  ],
  "customizations": {
    "vscode": {
      "extensions": ["anthropic.claude-code"]
    }
  }
}

Коллега клонирует репо → «Reopen in Container» → через 30 секунд у него рабочий Claude Code с тем же окружением, что у тебя.

Docker Compose — проект + Claude в одном

services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
    environment:
      - DATABASE_URL=postgres://dev:dev@db/dev

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: dev
      POSTGRES_USER: dev
    volumes:
      - pgdata:/var/lib/postgresql/data

  claude:
    image: claude-sandbox
    volumes:
      - .:/workspace
      - claude-data:/home/dev/.claude
    network_mode: service:app
    depends_on:
      - app
    tty: true
    stdin_open: true

volumes:
  pgdata:
  claude-data:

Claude живёт в том же network namespace, что и app — может делать curl http://localhost:3000 без лишних настроек.

Изоляция секретов

Главная выгода — модель физически не может прочитать то, чего нет в контейнере:

docker run -it --rm \
  --read-only \
  --tmpfs /tmp \
  -v $(pwd):/workspace:rw \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  claude-sandbox
  • --read-only — ФС только на чтение, кроме /workspace
  • --cap-drop ALL — никаких привилегий ядра
  • no-new-privileges — запрещает эскалацию через suid

Даже если Claude сгенерит «плохой» curl | bash, ему будет некуда писать.

Подводные камни

  • File watching не всегда работает через bind-mount. На Windows/macOS может быть проблема с inotify. Решение — polling в webpack/vite.
  • Volume claude-data привязан к юзеру. Если в контейнере uid=1000, а на хосте ты uid=501 — будут конфликты прав. Решается --user $(id -u):$(id -g).
  • ANTHROPIC_API_KEY в env светится в docker inspect. На prod используй Docker secrets.

Как попробовать

1. Создай Dockerfile из сниппета выше 2. docker build -t claude-sandbox . 3. Запусти с текущей папкой как volume 4. Внутри выполни /login — один раз 5. Следующие запуски сразу готовы к работе

Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper