Все системы работают Ваш IP: 216.73.217.113 info@cloudhosting.lv +371 66 66 29 69 Личный кабинет

← Все вопросы

OpenClaw в Docker: установка и запуск

Обновлено:

OpenClaw хорошо работает в Docker: скачай официальный образ ghcr.io/openclaw/openclaw, примонтируй (bind-mount) каталог хоста, принадлежащий uid 1000, в /home/node/.openclaw, держи API-ключи и токен шлюза (gateway) в файле .env, опубликуй порт 18789 только на 127.0.0.1 и запусти всё командой docker compose up -d. На небольшой виртуальной машине с Linux установка занимает около десяти минут; именно оговорку про песочницу (sandbox) в конце статьи большинство пользователей Docker и упускает.

Что даёт образ Docker

OpenClaw является персональным ИИ-агентом с открытым исходным кодом (лицензия MIT, OpenClaw Foundation), который работает как долгоживущий шлюз: один процесс Node.js держит соединения с каналами, общается с провайдером LLM и выполняет инструменты. Нативной установке нужен Node 24.16+ или 26.1+; образ несёт собственную среду выполнения, поэтому хосту нужны только Docker Engine и Compose v2.

Образ живёт в GitHub Container Registry как ghcr.io/openclaw/openclaw с зеркалом на Docker Hub под именем openclaw/openclaw. Теги следуют календарю релизов (например, 2026.9.3), плюс плавающие каналы latest, main и extended-stable, а также варианты вроде -slim и -browser. Обычные теги версий и датированные теги -rYYYYMMDD неизменяемы, и документация рекомендует закрепить один из них, чтобы развёртывание не следовало за плавающим тегом. На момент написания новейшим релизом является v2026.9.4 (11 сентября 2026 года).

Внутри образа процесс работает от непривилегированного пользователя node, uid 1000; Dockerfile заранее создаёт /home/node/.openclaw с правами 0700 и владельцем в лице этого пользователя, поэтому в шаге 1 так важен владелец каталога на хосте. Документация требует 6 ГБ RAM только при сборке из исходников; с готовым образом в наших развёртываниях шлюз в простое занимает несколько сотен мегабайт, так что для агента только с Telegram хватает 1 или 2 ГБ.

Шаг 1: подготовь каталог состояния

Всё, что должно пережить перезапуск, живёт в одном каталоге: openclaw.json, рабочее пространство (workspace), файлы состояния SQLite и состояние каналов. Документация монтирует его как bind-mount, чтобы он пережил замену контейнера, а страница устранения неполадок даёт то же лекарство от ошибок прав доступа: каталог на хосте должен принадлежать uid 1000, пользователю, от которого работает контейнер.

mkdir -p ~/.openclaw/workspace ~/.openclaw-auth-profile-secrets
sudo chown -R 1000:1000 ~/.openclaw ~/.openclaw-auth-profile-secrets
chmod 700 ~/.openclaw

На свежей Ubuntu VM первый пользователь обычно уже имеет uid 1000; если ты работаешь под root, именно chown избавляет от ошибок EACCES в логах.

Шаг 2: файл Compose

Официальный путь состоит в том, чтобы клонировать репозиторий и запустить ./scripts/docker/setup.sh, который собирает или скачивает образ, записывает .env и запускает первичную настройку (onboarding). На сервере написанный вручную файл Compose с закреплённым тегом и публикацией только на loopback проще проверять. Файл ниже урезан из апстримного docker-compose.yml: те же имена сервисов, пути внутри контейнера, усиление защиты и проверка здоровья, но с фиксированным тегом, привязкой к 127.0.0.1 и якорями YAML для общего окружения. Апстрим публикует ещё 18790 и 3978 (bridge и Microsoft Teams); агенту только с Telegram не нужен ни один из них.

x-openclaw-env: &openclaw-env
  HOME: /home/node
  OPENCLAW_HOME: /home/node
  OPENCLAW_STATE_DIR: /home/node/.openclaw
  OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
  OPENCLAW_CONFIG_DIR: /home/node/.openclaw
  OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
  OPENCLAW_GATEWAY_PORT: "18789"
  OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
  TZ: ${OPENCLAW_TZ:-UTC}

x-openclaw-volumes: &openclaw-volumes
  - "${HOME}/.openclaw:/home/node/.openclaw"
  - "${HOME}/.openclaw/workspace:/home/node/.openclaw/workspace"
  - "${HOME}/.openclaw-auth-profile-secrets:/home/node/.config/openclaw"

services:
  openclaw-gateway:
    image: ghcr.io/openclaw/openclaw:2026.9.3
    env_file:
      - path: .env
        required: false
    environment: *openclaw-env
    volumes: *openclaw-volumes
    ports:
      - "127.0.0.1:18789:18789"
    cap_drop:
      - NET_RAW
      - NET_ADMIN
    security_opt:
      - no-new-privileges:true
    extra_hosts:
      - "host.docker.internal:host-gateway"
    init: true
    restart: unless-stopped
    command: ["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789"]
    healthcheck:
      test: ["CMD", "node", "dist/docker-healthcheck.js"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 20s

  openclaw-cli:
    image: ghcr.io/openclaw/openclaw:2026.9.3
    network_mode: "service:openclaw-gateway"
    env_file:
      - path: .env
        required: false
    cap_drop:
      - NET_RAW
      - NET_ADMIN
    security_opt:
      - no-new-privileges:true
    environment:
      <<: *openclaw-env
      BROWSER: echo
    volumes: *openclaw-volumes
    stdin_open: true
    tty: true
    init: true
    entrypoint: ["node", "dist/index.js"]
    depends_on:
      - openclaw-gateway

--bind lan не ошибка: документация по сети объясняет, что внутри контейнера lan позволяет хосту достучаться до опубликованного порта, тогда как loopback доступен только изнутри сетевого пространства (namespace) самого контейнера. Открытость наружу определяет строка ports:, и 127.0.0.1:18789:18789 удерживает порт на loopback хоста; документация требует аутентификацию шлюза для любой привязки, кроме loopback, поэтому токен обязателен. Сервис openclaw-cli делит сетевое пространство со шлюзом, поэтому docker compose run --rm openclaw-cli ... выполняет любую команду openclaw против работающего шлюза.

Шаг 3: секреты в .env

Compose читает .env рядом с файлом Compose и через env_file передаёт каждую переменную в оба контейнера. Держи файл с правами 600 и вне git.

OPENCLAW_GATEWAY_TOKEN=replace-with-a-long-random-string
OPENAI_API_KEY=sk-...
TELEGRAM_BOT_TOKEN=123456789:AA...
OPENCLAW_TZ=Europe/London

Сгенерируй токен командой openssl rand -hex 32. OPENAI_API_KEY является той переменной, которую документация Docker использует для учётных данных провайдера; с --secret-input-mode ref первичная настройка сохраняет ссылку на эту переменную, а не сам ключ, и значения в openclaw.json тоже поддерживают подстановку ${VAR}. Для OpenAI-совместимой конечной точки справочник по onboard показывает --auth-choice custom-api-key с --custom-base-url и --custom-model-id; для провайдера без документированного неинтерактивного варианта (Anthropic, насколько нам удалось найти) запусти интерактивный мастер из ручного сценария в документации: docker compose run --rm --no-deps --entrypoint node openclaw-gateway dist/index.js onboard --mode local --no-install-daemon. TELEGRAM_BOT_TOKEN является документированным запасным вариантом для Telegram-аккаунта по умолчанию; конфигурация имеет приоритет над ним, и он должен остаться в .env после первичной настройки, потому что --use-env не копирует его в конфигурацию. Документация по конфигурации допускает и необязательный ~/.openclaw/.env внутри каталога состояния; мы используем его для заголовков MCP-серверов.

Шаг 4: первичная настройка и Telegram

Документация Docker даёт неинтерактивную команду первичной настройки для хостов без TTY. Она записывает openclaw.json в примонтированный каталог, направляет аутентификацию шлюза на токен из .env и пропускает каналы:

docker compose run -T --rm --no-deps --entrypoint node openclaw-gateway \
  dist/index.js onboard --non-interactive --accept-risk --skip-health \
  --mode local \
  --auth-choice openai-api-key \
  --secret-input-mode ref \
  --gateway-auth token \
  --gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN \
  --skip-channels \
  --no-install-daemon

docker compose run -T --rm --no-deps --entrypoint node openclaw-gateway \
  dist/index.js channels add --channel telegram --use-env

Обе команды скопированы из документации Docker; --use-env проверяет, что TELEGRAM_BOT_TOKEN задан, прежде чем записать конфигурацию. Теперь привяжи бота к себе: Telegram идентифицирует тебя по числовому id пользователя (напиши боту в личку, пока он ещё в режиме сопряжения, и прочитай id из его ответа, или спроси у @userinfobot), и документация по контролю доступа рекомендует dmPolicy: "allowlist" с этим id в allowFrom, плюс commands.ownerAllowFrom для команд, доступных только владельцу; имена пользователей, номера телефонов и id чатов не принимаются. Отредактируй ~/.openclaw/openclaw.json:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "dmPolicy": "allowlist",
      "allowFrom": ["123456789"]
    }
  },
  "commands": {
    "ownerAllowFrom": ["telegram:123456789"]
  }
}

dmPolicy по умолчанию равен pairing: неизвестные отправители ставятся в ожидание, пока ты их не одобришь; allowlist строже, и именно его мы поставляем. Файл в формате JSON5, поэтому комментарии и висячие запятые допускаются, но неизвестный ключ или недопустимое значение заставляют шлюз отказаться стартовать с кодом выхода 78.

Шаг 5: запуск, проверка здоровья, чтение логов

docker compose up -d openclaw-gateway
docker compose ps
docker compose logs -f openclaw-gateway
curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz
docker compose run --rm openclaw-cli gateway status
docker compose run --rm openclaw-cli doctor

Проверка здоровья запускает node dist/docker-healthcheck.js каждые 30 секунд после стартового периода в 20 секунд, поэтому docker compose ps показывает healthy, как только шлюз поднялся. Документация перечисляет три пробы без аутентификации: /healthz (живость), /startupz (запуск) и /readyz (готовность с учётом каналов). Здоровый gateway status печатает Runtime: running и Connectivity probe: ok.

Усиление защиты контейнера

OpenClaw по своей природе является удалённым выполнением кода: агент выполняет за тебя команды оболочки, в этом весь смысл, и по этой же причине шлюз никогда не должен быть доступен из интернета. В ранних релизах была CVE-2026-25253, удалённое выполнение кода в один клик через кражу токена шлюза, плюс изъяны проверки origin в панели управления. Защита одинакова для всех версий: порт остаётся на loopback, а ты добираешься до него через SSH или приватную оверлейную сеть.

  • Публикуй только на 127.0.0.1. Документация по безопасности указывает, что опубликованные порты контейнеров идут через цепочки форвардинга Docker, а не только через правила INPUT хоста, поэтому публикация на 0.0.0.0 может оказаться открытой, даже если твой файрвол утверждает обратное; всё, что ты всё же публикуешь, фильтруй в цепочке DOCKER-USER.
  • Добирайся до панели управления через SSH-туннель из документации по удалённому доступу: ssh -N -L 18789:127.0.0.1:18789 user@gateway-host, затем открой http://127.0.0.1:18789/. По той же причине документация предпочитает Tailscale Serve привязкам к LAN: шлюз остаётся на loopback.
  • Ограничь, кто может писать боту, через allowFrom, а что разрешено каждому отправителю, через tools.toolsBySender, если допущен больше чем один человек.
  • Запускай docker compose run --rm openclaw-cli security audit после каждого изменения; документация называет это единственной командой, которая говорит, отклонился ли ты от безопасного состояния.

Оговорка про песочницу

OpenClaw умеет выполнять инструменты в отдельном контейнере-песочнице. Настройка называется agents.defaults.sandbox.mode и имеет три документированных значения: off (по умолчанию), non-main (каждая сессия, кроме главной сессии агента) и all (каждая сессия). Бэкенд Docker создаёт такие песочницы через CLI docker с усиленными настройками по умолчанию: сеть none, корневая файловая система только для чтения, все capabilities сброшены, образ openclaw-sandbox:bookworm-slim, который ты собираешь сам скриптом scripts/sandbox-setup.sh (OpenClaw не подставит вместо него обычный образ Debian). Документация описывает это как стену вокруг выполнения инструментов, тогда как сам шлюз остаётся на хосте.

Подвох в том, что у шлюза в контейнере нет собственного демона Docker. Апстримный файл Compose прямо говорит об этом в комментарии: включение песочницы требует Docker CLI в образе (собери с --build-arg OPENCLAW_INSTALL_DOCKER_CLI=1 или запусти setup.sh с OPENCLAW_SANDBOX=1), монтирования /var/run/docker.sock в контейнер шлюза и добавления id группы docker хоста через group_add. Документация называет результат соседними контейнерами (sibling containers), созданными через Docker-сокет хоста. Передача этого сокета контейнеру, в котором работает ИИ-агент, даёт агенту контроль над хостом на уровне root, что сводит на нет большую часть того, что добавляет песочница.

Поэтому большинство развёртываний в Docker, включая наши, работают с выключенной песочницей и опираются на две границы: контейнер шлюза (непривилегированный uid 1000, сброшенные capabilities, no-new-privileges) и виртуальную машину вокруг него, в которой больше ничего нет. Если песочница тебе нужна, установи OpenClaw нативно на хосте, где шлюз может достучаться до Docker, как в нашей пошаговой инструкции по установке на VPS, или используй другой документированный бэкенд: podman, ssh, openshell или crabbox.

Образ -browser и память

В стандартном образе браузера нет. Для агента, который открывает веб-страницы, используй вариант -browser; в документации приводится пример ghcr.io/openclaw/openclaw:latest-browser, а для закреплённого развёртывания она советует вместо этого плавающего тега выбрать тег -browser конкретного релиза. Документация утверждает, что при шлюзе в Docker бинарник браузера должен находиться внутри контейнера; в образ с браузером встроены Chromium из Playwright и Xvfb, которые OpenClaw на Linux определяет автоматически; если при старте сообщается об отсутствующем дисплее, проверь browser.headless или OPENCLAW_BROWSER_HEADLESS. Не монтируй ничего поверх /home/node/.cache/ms-playwright, иначе встроенный браузер окажется скрыт. Цифр по памяти документация не даёт; в наших развёртываниях одна headless-сессия Chromium добавляет примерно от 0.5 до 1 ГБ сверх шлюза, поэтому для образа с браузером мы считаем минимумом 4 ГБ.

Обновление сменой тега

Поскольку состояние лежит на хосте, обновление сводится к смене тега. Сделай резервную копию, поменяй тег в обоих сервисах (например, на 2026.9.4), затем:

tar czf ~/openclaw-backup-$(date +%F).tgz -C ~ .openclaw
docker compose pull openclaw-gateway openclaw-cli
docker compose up -d openclaw-gateway
docker compose run --rm openclaw-cli doctor --json

Новый шлюз выполняет безопасные для старта миграции до того, как сообщит о готовности, и документация говорит, что обычное обновление образа не должно требовать отдельного прохода doctor --fix. Если починку нельзя безопасно завершить, шлюз завершает работу вместо того, чтобы отчитаться о здоровье, и контейнер перезапускается по кругу; документированное решение состоит в том, чтобы один раз запустить тот же образ с командой doctor --fix против того же каталога состояния, затем поднять шлюз и выполнить doctor --json как предварительную проверку только для чтения:

docker run --rm -v ~/.openclaw:/home/node/.openclaw ghcr.io/openclaw/openclaw:2026.9.4 openclaw doctor --fix

Архив tar является простой резервной копией средствами оболочки; документация предлагает ещё openclaw backup create --verify. Откат означает предыдущий тег плюс эту резервную копию: документация предупреждает, что база состояния, мигрированная на более новую версию, сама назад не откатывается.

Когда всё это можно пропустить

Для агента, который отвечает тебе в Telegram, запускает несколько инструментов и остаётся приватным, шаги выше и есть вся работа; для его размещения хватит небольшой Linux VM из нашей линейки VPS. Если ты вообще не хочешь поддерживать Docker, наш готовый сервер OpenClaw от 9.35 EUR в месяц поставляется с Ubuntu 24.04, шлюзом, уже установленным в Docker так, как описано здесь, портом на loopback и выключенной песочницей; ты добавляешь ключ LLM, подключаешь Telegram-бота и начинаешь общаться. О том, какую машину выбрать, читай в статье выбор сервера для ИИ-нагрузок.

Вопросы

Нужен ли Node.js на хосте, чтобы запускать OpenClaw в Docker?

Нет. Нативная установка требует Node 24.16+ или 26.1+, но образ несёт собственную среду выполнения; хосту нужны только Docker Engine и Compose v2.

Почему файл Compose привязывается к lan, если шлюз должен быть только на loopback?

Внутри контейнера loopback означает сетевое пространство самого контейнера, до которого хост не может достучаться, поэтому документация по сети для развёртываний в Docker по умолчанию использует lan и отдаёт решение об открытости строке ports; публикация на 127.0.0.1:18789 удерживает шлюз только на loopback, если смотреть со стороны хоста.

Можно ли включить песочницу позже?

Да, но со шлюзом в Docker для этого придётся выдать контейнеру Docker CLI и Docker-сокет хоста, чтобы он мог порождать соседние контейнеры-песочницы. Для большинства агентов с одним владельцем граница из контейнера плюс VM остаётся более безопасным компромиссом.

Где логи?

docker compose logs -f openclaw-gateway транслирует вывод шлюза; docker compose run --rm openclaw-cli logs --follow использует собственную команду логов OpenClaw. Если что-то выглядит неправильно, начни с gateway status и doctor.

Хотите, чтобы это работало приватно?
AI-ассистент на своём сервере в ЕС, и данные остаются там, куда вы их положили.
Посмотреть цены

Готовы начать?

Запустите за минуты или обсудите с инженером, что подходит вашему проекту.