Прямой ответ
Devcontainer переносит в контейнер не приложение, а среду разработки: при открытии проекта редактор (VS Code, JetBrains, Codespaces) читает .devcontainer/devcontainer.json, собирает образ с нужными тулчейнами и открывает окно уже внутри — с расширениями, настройками и запущенными сервисами. «Works on my machine» исчезает: машина разработчика перестаёт быть частью окружения, онбординг новичка — одна команда «Reopen in Container». Ресурсы: стоимость равна контейнерной разработке вообще (Docker-движок + образ 1–3 ГБ на диске), внутри — обычный Linux-тулчейн без дублирования установок на хосте.
Анатомия devcontainer.json
Минимальный, но рабочий пример для Python-проекта:
{
"name": "api-dev",
"build": { "dockerfile": "Dockerfile" },
"customizations": {
"vscode": {
"extensions": ["ms-python.python", "charliermarsh.ruff"],
"settings": { "python.defaultInterpreterPath": "/usr/local/bin/python" }
}
},
"forwardPorts": [8000],
"postCreateCommand": "uv sync",
"remoteUser": "vscode"
}
Ключевые поля, которые делают среду живой: postCreateCommand — установка зависимостей после создания контейнера (аналог make install); forwardPorts — порты автоматически доступны в браузере хоста; remoteUser — работа не от root (гигиена прав); mounts — доступ к SSH-агенту и git-конфигу хоста (~/.ssh через agent forwarding, не копированием ключей). Для стека из нескольких сервисов используется dockerComposeFile — devcontainer поднимается поверх compose-файла: БД и кэш из статьи про Compose-стек стартуют вместе со средой.
Что devcontainer даёт против ручного setup
Сравните два онбординга. Классический: README на три экрана («поставьте Python 3.11, но не 3.12, установите libpq-dev, если ошибка — поставьте pkg-config…»), половина шагов устарела, вечер потерян. Devcontainer: клон → «Reopen in Container» → через две минуты (сборка образа) редактор открыт в готовой среде, где версии зафиксированы Dockerfile'ом. Отличия от dotfiles-подхода (статья про dotfiles) — в границах: dotfiles настраивают вашу машину, devcontainer — среду проекта; они дополняют друг друга: личные настройки редактора пробрасываются в контейнер штатно. Бонус для CI: тот же образ используется в пайплайне — локальные и CI-окружения совпадают физически.
Секреты и чувствительные данные
Правила те же, что везде, но с контейнерной спецификой: .env не попадает в образ (монтируется или инжектится), ключи SSH — через агент-форвардинг ("mounts": ["source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind"] — с осторожностью; агент предпочтительнее), корпоративные credentials — через remoteEnv из окружения хоста. Антипаттерн — вписывать токены в Dockerfile/devcontainer.json: эти файлы в git, и утечка неотличима от любой другой (порядок действий — в статье про секреты). Отдельный нюанс: образ devcontainer может публиковаться в registry (предсборка ускоряет онбординг) — убедитесь, что в слоях нет ничего чувствительного.
Ресурсы и производительность на ноутбуке
Контейнер-среда живёт в Docker-движке: на Windows/macOS — внутри WSL2/VM, и лимиты памяти задаются там же, как для любого контейнера (порядок цифр — в статье про WSL2 и Docker линии). Проект держите внутри контейнерной файловой системы или WSL — код на NTFS-маунте замедляет и сборку, и LSP-индексацию кратно. Кэш сборки образа экономит минуты на повторных открытиях; полная пересборка нужна только при изменении Dockerfile — редактор предложит её сам. На 16 ГБ ноутбуке devcontainer + стек сервисов — рабочая норма при лимитах; на 8 ГБ — тесно, как и любая контейнерная разработка.
Когда devcontainer избыточен
Честные границы: для соло-проекта с одним языком достаточно менеджера версий и README; devcontainer раскрывается в командах (единая среда), мультиязыковых репозиториях (свой контейнер на сервис) и open source (контрибьютор стартует без танцев с установкой). Издержки: образ требует места и пересборки при эволюции тулчейна; специфичное железо (GPU, USB-устройства) пробрасывается в контейнер с оговорками. Разумный путь: начать с простого Dockerfile-образа и добавить devcontainer.json, когда в проекте появляется второй разработчик.
Эволюция конфигурации: от первого файла к зрелой схеме
Начинать разумно с минимализма: один контейнер, готовый базовый образ (devcontainers-образы для Python/Node/Go включают популярные тулчейны), пара расширений. Первая эволюция — когда в проекте появляются сервисы: добавляется dockerComposeFile, и среда открывается вместе с БД и кэшем. Вторая — предсборка образа в registry: сборка при первом открытии занимает минуты, готовый образ — секунды; для команды из десяти человек это часы суммарной экономии на каждом обновлении тулчейна. Третья — features (модули из реестра containers.dev): установка инструментов декларативными блоками вместо разрастания Dockerfile.
Зрелая схема выглядит так: образ предсобирается в CI при изменении Dockerfile и публикуется в registry с тегом по хешу; devcontainer.json ссылается на образ, а не на сборку; зависимости ставятся postCreateCommand'ом из lock-файла — детерминированно и быстро; личные настройки разработчика (тема, шрифты, его dotfiles-алиасы) пробрасываются штатными средствами и не смешиваются с проектной конфигурацией. Такой стенд переживает смену состава команды без потери знаний: окружение — код, а код читается и версионируется.
FAQ
Devcontainer или Codespaces? Codespaces — облачная реализация того же стандарта: ваш devcontainer.json поднимается на удалённой машине. Конфигурация переносится без изменений — это лучшая демонстрация ценности стандарта.
Поддерживают ли JetBrains devcontainers? Да, через Gateway/плагины удалённой разработки: среда поднимается по той же спецификации. Стандарт containers.dev редактор-независим.
Как обновлять тулчейн в среде?
Правкой Dockerfile (версии явные!) и пересборкой; postCreateCommand переустановит зависимости. Хуки postCreateCommand/onCreateCommand идемпотентны — повторная пересборка безопасна.
Можно ли в devcontainer без VS Code?
Да: devcontainer CLI (npm i -g @devcontainers/cli) поднимает среду из терминала, подключайтесь SSH-клиентом или любым редактором с remote-поддержкой; GUI — удобство, не требование.
Не потеряются ли мои изменения при пересборке контейнера? Код живёт в монтируемой папке проекта (или в volume) и пересборку переживает; пропадает только то, что установлено внутри контейнера руками мимо Dockerfile — отсюда правило: любое изменение среды фиксируйте в образе или postCreateCommand.
Подходит ли devcontainer для тяжёлых сборок? Да, с оговоркой про ресурсы Docker-движка: на Windows/macOS лимиты памяти VM задаются глобально, и тяжёлая сборка в контейнере конкурирует с остальными. Для экстремальных сценариев среда переносится на удалённую машину — конфигурация devcontainer при этом не меняется.
Источники: containers.dev, документация VS Code Dev Containers, спецификация devcontainers (ссылки в шапке).