В уроке про песочницу Claude Code ограничивал команды оболочки. идёт дальше: это Docker-контейнер, к которому подключается редактор, — на твоём компьютере или в облаке вроде GitHub Codespaces. Внутри него живёт весь процесс Claude Code: инструменты правки файлов, MCP-серверы, хуки. Команды выполняются в контейнере, а правки попадают в твой через монтирование.
Три слоя
Каждый следующий слой опирается на предыдущий:
| Слой | Что даёт |
|---|---|
| Фича Claude Code | CLI внутри любого dev-контейнера |
Именованный том в ~/.claude | Вход переживает пересборку |
| Эталонный контейнер | Обычный пользователь и файрвол — место для запуска без вопросов |
Слой 1: фича
Фича добавляется одной строкой в .devcontainer/devcontainer.json:
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "lts" },
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
},
"postCreateCommand": "sudo apt-get update && sudo apt-get install -y bubblewrap socat"
}
Подвох в теге :1.0. Он закрепляет скрипт установки фичи, а не Claude Code: фича ставит последний релиз, и дальше тот обновляется сам. postCreateCommand доставляет bubblewrap и socat — без них на Linux не работает песочница для Bash.
Слой 2: вход, который не пропадает
Войди в Claude Code, пересобери контейнер — и claude auth status вернёт код 1. Пересборка сохраняет папку с проектом, но выбрасывает домашнюю папку, а с ней и ~/.claude. В Codespaces то же самое: после Rebuild Container /workspaces на месте, а вход пропал.
Решение — именованный том Docker в ~/.claude плюс CLAUDE_CONFIG_DIR с тем же путём. Том живёт отдельно от контейнера, поэтому вход и настройки в нём переживают пересборку:
"mounts": [
"source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
],
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/home/node/.claude"
}
Если вход всё равно пропадает — проверь, что target тома и CLAUDE_CONFIG_DIR называют один и тот же путь.
Слой 3: эталонный контейнер
В репозитории Claude Code лежит эталонный .devcontainer/ из трёх файлов: devcontainer.json, Dockerfile и init-firewall.sh. Он добавляет:
- обычного пользователя
nodeвместо root; - файрвол: исходящий трафик идёт только на адреса из списка в
init-firewall.sh.
Именно такой контейнер документация поддерживает для прогонов с --dangerously-skip-permissions. От root CLI этот флаг вообще не примет.
Перед первой сборкой:
- Прочитай все три файла.
init-firewall.shвыполняется от root при каждом старте контейнера — какpostStartCommand. - Добавь домены входа. Рядом с
api.anthropic.comв списке должны бытьclaude.aiиplatform.claude.com, иначе вход и его обновление упрутся в файрвол. Нужен PyPI или приватный реестр пакетов — тоже допиши в список и пересобери. - Закрепи версию. В аргументе сборки
CLAUDE_CODE_VERSIONзамениlatestна конкретную версию, а вcontainerEnvдобавь"DISABLE_AUTOUPDATER": "1".
Проверить файрвол просто: внутри контейнера запрос к example.com должен падать, а к api.github.com — проходить.
Когда всё сходится, один прогон без присмотра внутри контейнера — с теми же лимитами, что в уровне про автономный запуск:
claude -p "Добавь в начало README.md однострочное описание репозитория" \
--dangerously-skip-permissions --model sonnet --max-turns 10
Уборка
Том переживает контейнер — а значит, и твой вход в нём. Закончил — выполни claude auth logout внутри контейнера, затем удали контейнер и тома, чьи имена начинаются с claude-code-config- и claude-code-bashhistory- (docker volume ls, потом docker volume rm). Codespace удали отдельно: остановленный он всё равно занимает место.
Мини-проверка
Фича Claude Code подключена с тегом :1.0. Какая версия Claude Code окажется в контейнере через месяц?
Осторожно
Контейнер не мешает проекту унести всё, что доступно внутри: в том числе учётные данные Claude Code в ~/.claude. Расширение Dev Containers в VS Code ещё и пробрасывает в контейнер твои Git-учётки и SSH-агент, а эталонный файрвол пропускает GitHub — так что прогон может запушить от твоего имени. Используй контейнер только с репозиториями, которым доверяешь, и никогда не монтируй туда ~/.ssh или файлы с облачными ключами. А после прогона без вопросов прочитай .git/config, список .git/hooks и дифф .devcontainer — до пересборки и до git commit.
Практика в терминале