← Все гайды AI Release
EN Подписаться на @ai_release1

Как запустить ИИ-агента в Docker: изоляция, права доступа и безопасность

Обновлено: 15.10.2026 · AI Release · @ai_release1
Как запустить ИИ-агента в Docker: изоляция, права доступа и безопасность

Агент, который сам вызывает инструменты, пишет файлы и ходит в интернет, — это уже не чат, а процесс с правами вашей учётной записи. Гайд показывает, как упаковать такого агента в Docker (Docker — система контейнеров: приложение запускается в изолированной среде с собственными файлами и процессами) и выдать ему минимум прав. Подходит для Linux, macOS и Windows с WSL2, Docker Engine 20.10+ или Docker Desktop 4.x, для агентов на Python (LangChain, LlamaIndex) и любых других. Идея простая: если агент ошибётся или его «уведёт» промпт-инъекция, пострадает только контейнер, а не ваш ноутбук. Если вы ещё не собрали самого агента, начните с гайда Как превратить обычный чат с LLM в полноценного AI-агента.

Требования и подготовка

Иллюстрация к разделу «Требования и подготовка»
Иллюстрация к разделу «Требования и подготовка»

- [ ] Агент не запускается от root внутри контейнера.

- [ ] Корневая файловая система контейнера — только для чтения.

- [ ] Секреты не попали в образ (проверяется `docker history`).

- [ ] Смонтирована ровно одна папка, а не весь диск.

- [ ] Сокет Docker `/var/run/docker.sock` НЕ смонтирован.

Пошаговая инструкция

Иллюстрация к разделу «Пошаговая инструкция»
Иллюстрация к разделу «Пошаговая инструкция»

1. Проверьте Docker. Выполните `docker --version` и `docker run --rm hello-world`. Ожидаемый результат: строка вида `Docker version 27.1.1, build 6312585` и сообщение `Hello from Docker!`. Почему это работает: `hello-world` — крошечный образ, который скачивается и запускается за пару секунд; если он прошёл, движок и права настроены.

2. Создайте структуру проекта. В терминале: `mkdir -p ai-agent/workspace && cd ai-agent`, затем создайте `Dockerfile`, `agent.py`, `requirements.txt` и `.env`. Ожидаемый результат: `ls` показывает все четыре файла. Почему: контекст сборки (папка, которую Docker отправляет на сборку) должен быть компактным и без секретов.

3. Добавьте `.dockerignore`. Впишите в файл строки `.env`, `__pycache__`, `*.log`, `.git`. Ожидаемый результат: файл `.env` не попадёт в образ. Почему это работает: `.dockerignore` исключает файлы из контекста сборки так же, как `.gitignore` — из репозитория.

4. Напишите `Dockerfile` с непривилегированным пользователем.

FROM python:3.12-slim

RUN useradd --create-home --uid 10001 agent
WORKDIR /app

COPY --chown=agent:agent requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY --chown=agent:agent agent.py .
USER agent

ENTRYPOINT ["python", "agent.py"]

Ожидаемый результат: последняя инструкция перед запуском — `USER agent`. Почему: внутри контейнера root почти равен root на хосте, а `USER agent` убирает эту возможность.

5. Соберите образ: `docker build -t ai-agent:0.1 .`. Ожидаемый результат: `Successfully tagged ai-agent:0.1`. Проверьте, что пользователь не root: `docker run --rm ai-agent:0.1 whoami` → `agent`. Почему: команда `whoami` выполняется внутри контейнера и показывает его пользователя, а не вашего.

6. Запустите агента с ограничениями.

docker run --rm --name agent-run \
  --read-only \
  --tmpfs /tmp:rw,size=64m \
  --cap-drop=ALL \
  --security-opt=no-new-privileges \
  --pids-limit=128 \
  --memory=1g --cpus=1.0 \
  --env-file .env \
  -v "$PWD/workspace:/workspace:rw" \
  ai-agent:0.1

Ожидаемый результат: агент работает, пишет только в `/workspace` и `/tmp`. Почему: `--read-only` запрещает менять корень файловой системы, `--cap-drop=ALL` снимает Linux-capabilities (набор привилегий вроде смены владельца файлов), `--pids-limit` защищает от «вилки» процессов.

7. Ограничьте сеть. Если агенту нужен только внешний API модели, запустите его в своей сети: `docker network create agent-net`, затем добавьте в команду `--network=agent-net`. Если сеть не нужна вовсе — `--network=none`. Проверка: `docker run --rm --network=none ai-agent:0.1 curl -s https://example.com` вернёт ошибку соединения — значит, изоляция работает. Почему: встроенный bridge-сеть Docker не фильтрует домены, поэтому самый надёжный вариант — вообще не давать сеть или выпускать трафик через отдельный прокси.

8. Настройте лимиты и наблюдаемость. Запустите контейнер в фоне (`-d` вместо `--rm`) и посмотрите `docker stats agent-run` и `docker logs agent-run`. Ожидаемый результат: в `stats` видно потребление CPU/RAM, в логах — шаги агента. Почему: без лимитов один зацикленный вызов инструмента съест всю память хоста.

Шпаргалка по ключевым флагам:

ФлагЧто делаетПример значения
`--read-only`Корень ФС только для чтениябез значения
`--tmpfs /tmp`Временная папка в памяти`size=64m`
`--cap-drop`Снимает привилегии`ALL`
`--pids-limit`Лимит процессов`128`
`--memory`, `--cpus`Лимиты ресурсов`1g`, `1.0`
`-v`Монтирует папку`"$PWD/workspace:/workspace:rw"`

9. Передавайте секреты только во время запуска. Ключ держите в `.env` и подключайте через `--env-file .env`. Проверка: `docker history ai-agent:0.1 --no-trunc` не должен показывать ваш ключ. Почему: переменные, заданные в `Dockerfile` через `ENV`, навсегда остаются в слоях образа. Больше про утечки и права — в гайде Безопасность ИИ-агентов: как защитить данные и избежать утечек.

Пример:агент должен разобрать файл `report.csv` из `workspace/` и сохранить результат в `workspace/out.json`. Команда из шага 6 даёт ему ровно эти два пути — всё остальное на диске для него не существует.

Возможные проблемы и решения

Иллюстрация к разделу «Возможные проблемы и решения»
Иллюстрация к разделу «Возможные проблемы и решения»

1. Симптом: при запуске с `--read-only` в логах `PermissionError: [Errno 30] Read-only file system: '/app/cache'`. Решение: агент пытается писать в папку образа. Смонтируйте её как временную: добавьте `--tmpfs /app/cache:rw,size=32m` или пишите в `/tmp`. Если нужны постоянные файлы — только через `-v` в `workspace`.

2. Симптом: `docker run --rm ai-agent:0.1 whoami` печатает `root`. Решение: в `Dockerfile` пропущен `USER agent` либо перед ним нет `RUN useradd`. Добавьте строку `USER agent` в конец `Dockerfile`, пересоберите образ и проверьте снова. Быстрый обходной путь без пересборки: флаг `--user 10001:10001`.

3. Симптом: агент падает с `ConnectionError`, `Name or service not known` или таймаутом обращения к API. Решение: вы включили `--network=none`. Создайте сеть `docker network create agent-net` и запустите с `--network=agent-net`, оставив остальные ограничения на месте.

4. Симптом: `docker: Error response from daemon: ... port is already allocated` при публикации порта. Решение: смените внешний порт, например `-p 8081:8080` вместо `-p 8080:8080`, или уберите `-p` совсем, если веб-интерфейс вам не нужен.

FAQ

Чем контейнер лучше виртуальной машины для агента?

Он запускается за секунды, весит десятки-сотни мегабайт и использует общее ядро системы. Для изоляции одного процесса этого достаточно, а ресурсов уходит намного меньше.

Можно ли запустить саму LLM внутри того же контейнера?

Технически да, но образ должен содержать нужные библиотеки, а для GPU-ускорения понадобится проброс ускорителя (например, `--gpus all`). Обычно модель держат отдельно от агента, а внутрь контейнера отдают только адрес API — как развести локальный запуск, разбирается в гайде Как запустить ИИ-модель локально на своём компьютере.

Дать агенту доступ к папке проекта, но не ко всему диску — как?

Монтируйте одну папку: `-v "$PWD/workspace:/workspace:rw"`. Всё, что за её пределами, контейнер не видит. Никогда не монтируйте `/`, домашний каталог целиком и особенно `/var/run/docker.sock` — через сокет агент получит управление Docker на хосте.

Хватит ли `--read-only` и `--cap-drop=ALL`, чтобы считать агента безопасным?

Нет, это базовый слой. Дальше нужны: непривилегированный пользователь, лимиты CPU/RAM/процессов, отсутствие лишней сети, секреты вне образа и регулярное обновление базового образа.

🤖 Кратко для ИИ