Hermes Agent — Docker

Есть два различных способа использования Docker с Hermes Agent:

  1. Запуск Hermes В Docker — сам агент работает внутри контейнера (основная тема этой страницы)

  2. Docker как терминальный backend — агент работает на вашем хосте, но выполняет каждую команду внутри единого постоянного Docker-контейнера-песочницы, который сохраняется между вызовами инструментов, /new и сабагентами на время жизни процесса Hermes (см. Configuration → Docker Backend)

Эта страница описывает вариант 1. Контейнер хранит все пользовательские данные (конфигурацию, API-ключи, сессии, skills, воспоминания) в одной директории, смонтированной с хоста по пути /opt/data. Сам образ не имеет состояния и может быть обновлён путём загрузки новой версии без потери конфигурации.

Быстрый старт

Если вы запускаете Hermes Agent впервые, создайте директорию для данных на хосте и запустите контейнер в интерактивном режиме для работы мастера настройки:

mkdir -p ~/.hermes
docker run -it --rm \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent setup

Это запустит мастер настройки, который запросит ваши API-ключи и запишет их в ~/.hermes/.env. Это нужно сделать только один раз. Настоятельно рекомендуется на этом этапе настроить чат-систему для работы шлюза.

Запуск в режиме шлюза

После настройки запустите контейнер в фоновом режиме как постоянный шлюз (Telegram, Discord, Slack, WhatsApp и т.д.):

docker run -d \\
  --name hermes \\
  --restart unless-stopped \\
  -v ~/.hermes:/opt/data \\
  -p 8642:8642 \\
  nousresearch/hermes-agent gateway run

Порт 8642 открывает доступ к OpenAI-совместимому API серверу и endpoint-у для проверки здоровья шлюза. Это необязательно, если вы используете только чат-платформы (Telegram, Discord и т.д.), но требуется для работы панели управления или внешних инструментов, обращающихся к шлюзу.

Примечание: API-сервер включается только при API_SERVER_ENABLED=true. Чтобы открыть доступ к нему за пределами 127.0.0.1 внутри контейнера, также установите API_SERVER_HOST=0.0.0.0 и API_SERVER_KEY (минимум 8 символов — сгенерируйте ключ командой openssl rand -hex 32). Пример:

docker run -d \\
  --name hermes \\
  --restart unless-stopped \\
  -v ~/.hermes:/opt/data \\
  -p 8642:8642 \\
  -e API_SERVER_ENABLED=true \\
  -e API_SERVER_HOST=0.0.0.0 \\
  -e API_SERVER_KEY=your_api_key_here \\
  -e API_SERVER_CORS_ORIGINS='*' \\
  nousresearch/hermes-agent gateway run

Открытие любого порта на машине, подключённой к интернету, представляет угрозу безопасности. Не делайте этого, если не понимаете связанные риски.

Запуск панели управления

Встроенная веб-панель управления запускается как опциональный фоновый процесс внутри того же контейнера, что и шлюз. Установите HERMES_DASHBOARD=1 и откройте порт 9119 вместе с портом шлюза 8642:

docker run -d \\
  --name hermes \\
  --restart unless-stopped \\
  -v ~/.hermes:/opt/data \\
  -p 8642:8642 \\
  -p 9119:9119 \\
  -e HERMES_DASHBOARD=1 \\
  nousresearch/hermes-agent gateway run

Точка входа запускает hermes dashboard в фоне (от имени непривилегированного пользователя hermes) перед exec основной команды. Вывод панели управления помечается префиксом [dashboard] в docker logs, что позволяет легко отделить его от логов шлюза.

Переменная окружения Описание По умолчанию
HERMES_DASHBOARD Установите в 1 (или true / yes), чтобы запустить панель управления вместе с основной командой (не установлена — панель не запускается)
HERMES_DASHBOARD_HOST Адрес привязки HTTP-сервера панели управления 0.0.0.0
HERMES_DASHBOARD_PORT Порт HTTP-сервера панели управления 9119
HERMES_DASHBOARD_TUI Установите в 1, чтобы открыть вкладку чата в браузере (встроенный hermes --tui через PTY/WebSocket) (не установлена)

Значение по умолчанию HERMES_DASHBOARD_HOST=0.0.0.0 необходимо, чтобы хост мог обращаться к панели управления через опубликованный порт; точка входа автоматически передаёт флаг --insecure в hermes dashboard в этом случае. Замените на 127.0.0.1, если хотите ограничить доступ к панели управления только изнутри контейнера (например, за обратным прокси в sidecar-контейнере).

Фоновый процесс панели управления **не супервизируется** — если он упадёт, он останется остановленным до перезапуска контейнера. Запуск панели в отдельном контейнере не поддерживается: для обнаружения активности шлюза панели требуется общее пространство имён PID с процессом шлюза.

Интерактивный запуск (CLI чат)

Чтобы открыть интерактивную чат-сессию с существующей директорией данных:

docker run -it --rm \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent

Или, если вы уже открыли терминал в запущенном контейнере (например, через Docker Desktop), просто выполните:

/opt/hermes/.venv/bin/hermes

Постоянные тома

Том /opt/data является единым источником истины для всего состояния Hermes. Он соответствует директории ~/.hermes/ на вашем хосте и содержит:

Путь Содержимое
.env API-ключи и секреты
config.yaml Вся конфигурация Hermes
SOUL.md Личность/идентичность агента
sessions/ История разговоров
memories/ Постоянное хранилище воспоминаний
skills/ Установленные навыки
cron/ Определения запланированных задач
hooks/ Событийные хуки
logs/ Логи выполнения
skins/ Пользовательские темы CLI
Никогда не запускайте два контейнера **gateway** Hermes против одной и той же директории данных одновременно — файлы сессий и хранилища воспоминаний не рассчитаны на одновременную запись.

Поддержка нескольких профилей

Hermes поддерживает несколько профилей — отдельные директории ~/.hermes/, позволяющие запускать независимых агентов (разные SOUL, навыки, память, сессии, учётные данные) из одной установки. При работе под Docker использовать встроенную функцию множественных профилей Hermes не рекомендуется.

Вместо этого рекомендуется подход один контейнер на профиль, где каждый контейнер монтирует свою собственную директорию хоста как /opt/data:

# Рабочий профиль
docker run -d \\
  --name hermes-work \\
  --restart unless-stopped \\
  -v ~/.hermes-work:/opt/data \\
  -p 8642:8642 \\
  nousresearch/hermes-agent gateway run

# Личный профиль
docker run -d \\
  --name hermes-personal \\
  --restart unless-stopped \\
  -v ~/.hermes-personal:/opt/data \\
  -p 8643:8642 \\
  nousresearch/hermes-agent gateway run

Почему отдельные контейнеры лучше профилей в Docker:

В Docker Compose это означает объявление одного сервиса на профиль с отдельными container_name, volumes и ports:

services:
  hermes-work:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-work
    restart: unless-stopped
    command: gateway run
    ports:
      - "8642:8642"
    volumes:
      - ~/.hermes-work:/opt/data

  hermes-personal:
    image: nousresearch/hermes-agent:latest
    container_name: hermes-personal
    restart: unless-stopped
    command: gateway run
    ports:
      - "8643:8642"
    volumes:
      - ~/.hermes-personal:/opt/data

Проброс переменных окружения

API-ключи считываются из /opt/data/.env внутри контейнера. Вы также можете передавать переменные окружения напрямую:

docker run -it --rm \\
  -v ~/.hermes:/opt/data \\
  -e ANTHROPIC_API_KEY="sk-ant-..." \\
  -e OPENAI_API_KEY="sk-..." \\
  nousresearch/hermes-agent

Флаги -e напрямую переопределяют значения из .env. Это удобно для CI/CD или интеграций с менеджерами секретов, когда не нужно хранить ключи на диске.

Пример Docker Compose

Для постоянного развёртывания со шлюзом и панелью управления удобно использовать docker-compose.yaml:

services:
  hermes:
    image: nousresearch/hermes-agent:latest
    container_name: hermes
    restart: unless-stopped
    command: gateway run
    ports:
      - "8642:8642"   # API шлюза
      - "9119:9119"   # панель управления (доступна только при HERMES_DASHBOARD=1)
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_DASHBOARD=1
      # Раскомментируйте для проброса конкретных переменных окружения вместо использования .env:
      # - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      # - OPENAI_API_KEY=${OPENAI_API_KEY}
      # - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"

Запустите командой docker compose up -d и просматривайте логи командой docker compose logs -f. Вывод панели управления помечается префиксом [dashboard], что позволяет легко отфильтровать его от логов шлюза.

Ограничения ресурсов

Контейнеру Hermes требуются умеренные ресурсы. Рекомендуемые минимумы:

Ресурс Минимум Рекомендуется
Память 1 ГБ 2–4 ГБ
CPU 1 ядро 2 ядра
Диск (том данных) 500 МБ 2+ ГБ (растёт с сессиями/skills)

Автоматизация браузера (Playwright/Chromium) — самая требовательная к памяти функция. Если вам не нужны инструменты браузера, достаточно 1 ГБ. При активных инструментах браузера выделите не менее 2 ГБ.

Установите лимиты в Docker:

docker run -d \\
  --name hermes \\
  --restart unless-stopped \\
  --memory=4g --cpus=2 \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent gateway run

Что делает Dockerfile

Официальный образ основан на debian:13.4 и включает:

Скрипт точки входа (docker/entrypoint.sh) инициализирует том данных при первом запуске:

Не переопределяйте точку входа образа, если вы не сохраняете `/opt/hermes/docker/entrypoint.sh` в цепочке команд. Точка входа понижает привилегии root до пользователя `hermes` перед созданием файлов состояния шлюза. Запуск `hermes gateway run` от root внутри официального образа по умолчанию отклоняется, так как это может оставить файлы, принадлежащие root, в `/opt/data` и нарушить последующие запуски панели управления или шлюза. Устанавливайте `HERMES_ALLOW_ROOT_GATEWAY=1` только если вы намеренно принимаете этот риск.

Обновление

Загрузите последний образ и пересоздайте контейнер. Ваша директория данных останется нетронутой.

docker pull nousresearch/hermes-agent:latest
docker rm -f hermes
docker run -d \\
  --name hermes \\
  --restart unless-stopped \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent gateway run

Или с Docker Compose:

docker compose pull
docker compose up -d

Skills и файлы учётных данных

При использовании Docker в качестве среды выполнения (не описанными выше методами, а когда агент выполняет команды внутри Docker-песочницы — см. Configuration → Docker Backend), Hermes повторно использует один долгоживущий контейнер для всех вызовов инструментов и автоматически монтирует директорию навыков (~/.hermes/skills/) и любые файлы учётных данных, объявленные навыками, в этот контейнер как тома только для чтения. Скрипты навыков, шаблоны и ссылки доступны внутри песочницы без ручной настройки, а поскольку контейнер сохраняется на время жизни процесса Hermes, любые установленные зависимости или созданные файлы остаются доступными для следующего вызова инструмента.

Та же синхронизация происходит для backend-ов SSH и Modal — навыки и файлы учётных данных загружаются через rsync или Modal mount API перед каждой командой.

Подключение к локальным серверам инференса (vLLM, Ollama и др.)

При запуске Hermes в Docker, когда ваш сервер инференса (vLLM, Ollama, text-generation-inference и т.д.) также работает на хосте или в другом контейнере, настройка сети требует дополнительного внимания.

Поместите оба сервиса в одну сеть Docker. Это самый надёжный подход:

services:
  vllm:
    image: vllm/vllm-openai:latest
    container_name: vllm
    command: >
      --model Qwen/Qwen2.5-7B-Instruct
      --served-model-name my-model
      --host 0.0.0.0
      --port 8000
    ports:
      - "8000:8000"
    networks:
      - hermes-net
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]

  hermes:
    image: nousresearch/hermes-agent:latest
    container_name: hermes
    restart: unless-stopped
    command: gateway run
    ports:
      - "8642:8642"
    volumes:
      - ~/.hermes:/opt/data
    networks:
      - hermes-net

networks:
  hermes-net:
    driver: bridge

Затем в вашем ~/.hermes/config.yaml используйте имя контейнера в качестве имени хоста:

model:
  provider: custom
  model: my-model
  base_url: http://vllm:8000/v1
  api_key: "none"

Ключевые моменты

  • Используйте имя контейнера (vllm) в качестве имени хоста — не localhost или 127.0.0.1, которые ссылаются на сам контейнер Hermes.

  • Значение model должно соответствовать --served-model-name, переданному vLLM.

  • Установите api_key в любую непустую строку (vLLM требует заголовок, но по умолчанию его не проверяет).

  • Не добавляйте косую черту в конце base_url.

Самостоятельный Docker run (без Compose)

Если ваш сервер инференса работает непосредственно на хосте (не в Docker), используйте host.docker.internal на macOS/Windows или --network host на Linux:

macOS / Windows:

docker run -d \\
  --name hermes \\
  -v ~/.hermes:/opt/data \\
  -p 8642:8642 \\
  nousresearch/hermes-agent gateway run
# config.yaml
model:
  provider: custom
  model: my-model
  base_url: http://host.docker.internal:8000/v1
  api_key: "none"

Linux (сетевое взаимодействие хоста):

docker run -d \\
  --name hermes \\
  --network host \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent gateway run
# config.yaml
model:
  provider: custom
  model: my-model
  base_url: http://127.0.0.1:8000/v1
  api_key: "none"

С флагом --network host флаг -p игнорируется — все порты контейнера напрямую открываются на хосте.

Проверка подключения

Изнутри контейнера Hermes убедитесь, что сервер инференса доступен:

docker exec hermes curl -s http://vllm:8000/v1/models

Вы должны увидеть JSON-ответ со списком вашей модели. Если это не сработало, проверьте:

  1. Оба контейнера находятся в одной сети Docker (docker network inspect hermes-net)

  2. Сервер инференса слушает на 0.0.0.0, а не на 127.0.0.1

  3. Номер порта совпадает

Ollama

Ollama работает аналогично. Если Ollama запущен на хосте, используйте host.docker.internal:11434 (macOS/Windows) или 127.0.0.1:11434 (Linux с --network host). Если Ollama работает в своём контейнере в той же сети Docker:

model:
  provider: custom
  model: llama3
  base_url: http://ollama:11434/v1
  api_key: "none"

Устранение неполадок

Контейнер сразу завершает работу

Проверьте логи: docker logs hermes. Частые причины:

Ошибки «Отказано в доступе»

Точка входа контейнера понижает привилегии до непривилегированного пользователя hermes (UID 10000) через gosu. Если ваша директория ~/.hermes/ на хосте принадлежит другому UID, установите HERMES_UID/HERMES_GID в соответствии с вашим пользователем хоста или убедитесь, что директория данных доступна для записи:

chmod -R 755 ~/.hermes

Инструменты браузера не работают

Playwright требует разделяемую память. Добавьте --shm-size=1g в команду Docker run:

docker run -d \\
  --name hermes \\
  --shm-size=1g \\
  -v ~/.hermes:/opt/data \\
  nousresearch/hermes-agent gateway run

Шлюз не переподключается после сетевых проблем

Флаг --restart unless-stopped обрабатывает большинство временных сбоев. Если шлюз завис, перезапустите контейнер:

docker restart hermes

Проверка здоровья контейнера

docker logs --tail 50 hermes          # Последние логи
docker run -it --rm nousresearch/hermes-agent:latest version     # Проверка версии
docker stats hermes                    # Использование ресурсов