DeepSeek Harness в Docker

Официального образа нет, но DSH — обычное приложение на Node.js, так что в контейнере на базе образа node оно запускается. Ниже минимальная команда, одна неочевидная засада с сетью и список ограничений, с которыми придётся жить.

Официального образа нет

В репозитории deepseek-ai/deepseek-harness нет ни Dockerfile, ни docker-compose.yml, ни workflow, который публиковал бы образ. Docker там используется только в CI для сборки; я проверял по дереву репозитория 11 сентября 2026. Всё, что предлагают под названием «docker-образ DeepSeek Harness», собрал кто-то посторонний. Относиться к такому стоит как к любому чужому коду, внутри которого будет работать агент с доступом к вашим файлам.

Нужен ли вообще Docker? Для обычной работы нет. DSH ставится одной командой на Windows, macOS и Linux, а команды агента и так изолирует встроенная песочница (о ней ниже). Контейнер имеет смысл в двух случаях: когда хочется жёстко ограничить, что агент видит на диске, и когда DSH нужно держать на сервере вместе с окружением проекта. Во втором случае контейнер обычно живёт на VPS с Linux: какой брать и как подключаться, разобрано на странице Linux и сервер.

Запуск в контейнере на Linux

Перейдите в папку проекта и выполните (нужны Docker Engine и доступ к реестру npm изнутри контейнера):

docker run -it --rm --network host \
  -v "$PWD":/work -w /work \
  -v dsh-home:/root/.dsh \
  node:22 npx @deepseek-ai/dsh web --no-open

Что здесь что:

  • --network host: контейнер использует сетевой стек хоста. Без этого не заработает, почему — ниже.
  • -v "$PWD":/work -w /work: папка проекта монтируется внутрь и становится рабочей папкой агента. Ничего другого агент не увидит.
  • -v dsh-home:/root/.dsh: именованный том под $DSH_HOME, где живут профиль web, настройки и ключ модели. Без тома всё это пропадёт вместе с контейнером, и ключ придётся вводить при каждом запуске.
  • --no-open: браузера внутри контейнера нет, так что DSH только напечатает адрес. Скопируйте строку dsh web: с токеном в браузер на этой же машине.
  • node:22: полный образ, не -slim и не -alpine. В нём есть git и базовые инструменты сборки, без которых агент в проекте мало что сможет.

Дальше как обычно: Settings → Models → ключ API, Choose workspace → /work. Остановить через Ctrl+C; из-за --rm контейнер удалится, а том с настройками останется.

Почему не -p 3080:3080

Сервер DSH привязан к 127.0.0.1, а флаг --host 0.0.0.0 CLI отвергает с ошибкой. В исходниках это сделано намеренно, с формулировкой «it would expose remote code execution to the network». Публикация порта через -p направляет соединения на внешний интерфейс контейнера, а не на его loopback. Сервер их просто не увидит, и браузер получит «connection refused». С --network host loopback у контейнера и хоста общий, поэтому 127.0.0.1:3080 на вашей машине и есть DSH внутри контейнера.

В Docker Desktop на macOS и Windows контейнеры работают внутри виртуальной машины, и сеть хоста там по умолчанию не даёт общего loopback с вашей системой. На этих платформах проще запускать DSH нативно: macOS, Windows. Обходной путь на случай, когда сеть хоста недоступна, такой: поднять внутри контейнера прокси (например, socat), который принимает соединения на всех интерфейсах и передаёт их на 127.0.0.1:3080, а в DSH добавить имя, по которому вы заходите, флагом --trusted-host (он расширяет список адресов, разрешённых при проверке заголовка Host). Я этот вариант не проверял и советовать его могу только для экспериментов: по сути это то самое сетевое раскрытие, от которого авторы закрыли --host.

Ограничения

  • Агент видит только смонтированное. Файлов за пределами /work для него не существует. С одной стороны, ради этого всё и затевалось. С другой, соседние репозитории, глобальные конфиги и SSH-ключи придётся монтировать отдельно, и каждый раз думать, стоит ли.
  • Инструменты проекта должны быть в образе. Нужен Python, Rust, Go или конкретная версия компилятора? Собирайте свой образ поверх node:22 и ставьте их туда. Проектам на Node.js обычно хватает базового.
  • Плагины ставятся внутрь тома. dsh plugin --profile web add … нужен pnpm в PATH; в образе node он включается через corepack enable. Поставленные плагины лягут в профиль внутри тома dsh-home.
  • Встроенная песочница в контейнере может работать не полностью. На Linux DSH ограничивает команды агента через bwrap или Landlock. Первому нужны пользовательские пространства имён, которые Docker по умолчанию урезает, второму нужна поддержка в ядре хоста. В этом случае изоляцию даёт сам контейнер, а не песочница DSH.
  • Файлы от root. Процесс в node:22 работает от root, и всё, что агент создаст в /work, на хосте будет принадлежать root. Лечится флагом --user "$(id -u):$(id -g)", но тогда $DSH_HOME придётся направить в папку, доступную этому пользователю (переменная DSH_HOME), вместо /root/.dsh.

Не путать с песочницей внутри DSH

У DSH есть собственный механизм изоляции команд, и Docker к нему никакого отношения не имеет. Подсистема dsh-sandbox оборачивает каждую команду агента в политику файловых эффектов, а платформенный провайдер её исполняет: на Linux это bwrap или Landlock, на macOS Seatbelt, на Windows ограниченный токен с ACL. Режимов три: read-only (только чтение), workspace-write (запись в рабочую папку и временный каталог; это режим по умолчанию) и danger-full-access (без ограничений). Политика касается только файлов, сеть и видимость процессов она не регулирует. Провайдер сообщает, насколько полно он обеспечивает режим: full или partial; старые версии Landlock и Windows-провайдер сейчас относятся к partial. Контейнеры и виртуальные машины авторы называют «соседними реализациями» изоляции, а не частью этой песочницы. Подробности в docs/subsystems/sandbox.md (англ.), а о том, почему ни один из этих механизмов нельзя считать единственной защитой, авторы пишут в SAFETY.md.

Дальше