COMPOSE_PROJECT_NAME · отдельные тома данных и таблица портов · сверка env_file и переменных в контейнере
При параллельном запуске двух стеков OpenClaw на одном VPS чаще всего ломается изоляция из‑за занятых портов, совпадения имён сети по умолчанию и томов и ситуации, когда на хосте есть API Key, а в контейнере переменные окружения пустые. Здесь — сводная таблица базовой линии одного экземпляра и минимального набора отличий для нескольких с полями COMPOSE_PROJECT_NAME, каталогами данных и таблицей портов, пояснение путей инъекции через env_file и environment, а также шестишаговый чеклист и условия отката к одному экземпляру. Удобно читать вместе с Docker Compose: производственная база и Exit 137 и первичная диагностика.
Скопировать docker-compose.yml, поменять несколько портов и считать задачу решённой нельзя: имя проекта по умолчанию оставляет пересечения по сети и анонимным томам; export в оболочке хоста сам по себе не попадает в контейнер; upstream обратного прокси может по-прежнему указывать на IP старого контейнера. Увидев такие сигналы, вернитесь к сводной таблице и отмечайте пункты по порядку вместо бесконечного добавления контейнеров.
Меняли только порты, не трогая COMPOSE_PROJECT_NAME: сеть bridge по умолчанию и внутренний DNS всё ещё могут резолвить имена контейнеров другого стека.
Симлинки или пересечение монтирования каталогов данных: два набора ~/.openclaw или workspace фактически лежат под одним префиксом на диске, скрипты обновления перезаписывают друг друга.
API Key только в профиле shell: дочерний процесс docker compose up не видит путь env_file, который ожидает compose.
Слишком короткий healthcheck: второй экземпляр дольше выходит на рабочий режим после холодного старта, оркестратор ошибочно перезапускает его и он конкурирует за блокировки с первым.
Обратный прокси всё ещё смотрит на старый порт 127.0.0.1: при смене двух Gateway на периферии трафик уходит в уже остановленный экземпляр. Как выровнять конфигурацию, см. в статье про обратный прокси и TLS.
Ниже — поля, которые чаще всего составляют минимальный набор отличий для двух стеков на одном хосте. Если вы поднимаете короткий тестовый второй экземпляр, сначала закройте как минимум имя проекта, каталог данных, порты хоста и путь env_file, и только потом автоматизируйте. Лимиты ресурсов и ротацию логов по-прежнему нужно соблюдать по материалу о производственной базе.
| Поле | Базовая линия одного экз. | Обязательное разделение для нескольких | Типичный подводный камень |
|---|---|---|---|
COMPOSE_PROJECT_NAME | Имя каталога по умолчанию | Уникальное короткое имя на стек (например oc_a / oc_b) | Переименовали папку, но не имя проекта — анонимные тома переиспользуются |
| Путь тома данных | Один путь привязки на хосте | Полное разделение /srv/openclaw-a и /srv/openclaw-b | Симлинк в подкаталоге ведёт к одному и тому же родителю |
| Порты хоста | Одна пара 3000:3000 | Разные порты хоста и фиксация в операционной таблице портов | Второй стек не поднимается, но systemd продолжает дёргать перезапуск |
| Инъекция окружения | Один файл .env | Отдельный .env.oc-a на стек и явный env_file в compose | export на хосте вне области, которую парсит compose |
| Healthcheck | Один набор start_period | При более медленном холодном старте увеличить start_period и retries | Одновременный перезапуск двух стеков даёт пик CPU |
Сначала зафиксируйте имя проекта и каталоги данных, потом таблицу портов; обратный порядок при первом же скрипте обновления смешает состояние двух экземпляров в одном префиксе.
Шаги ниже предполагают, что одиночный запуск официального или внутреннего фрагмента Compose у вас уже работает; цель — чтобы у второго стека и срендеренная конфигурация, и env во время выполнения поддавались сопоставимому аудиту.
Имя проекта и каталоги: задайте COMPOSE_PROJECT_NAME, создайте отдельный каталог данных и убедитесь, что нет вложенных симлинков.
Таблица портов: выделите свободные порты хоста для Gateway, Control UI и дополнительных каналов и занесите их в операционную таблицу.
Разделение env_file: отдельный путь к файлу секретов на стек без общего .env; при необходимости задайте docker compose --project-directory.
Проверка рендера: выполните docker compose -f ... config и сравните у двух стеков блоки networks, volumes и ports на предмет совпадающих имён монтирования.
Проверка в рантайме: через docker compose exec выведите целевые переменные в контейнере и сверьте с маскированной проверкой на хосте.
Здоровье и логи: по базовой линии задайте start_period и лимиты json-file, чтобы два стека одновременно не забили диск.
export COMPOSE_PROJECT_NAME=oc_b docker compose --env-file ./.env.oc-b -f docker-compose.yml config > /tmp/oc-b.rendered.yml docker compose --env-file ./.env.oc-b -f docker-compose.yml up -d docker compose --env-file ./.env.oc-b exec -T openclaw-gateway sh -lc 'env | grep -E "ANTHROPIC|OPENAI" | sed "s/=.*/=***MASK***/"'
Подсказка: подкоманда config только разбирает и сливает конфигурацию, контейнеры не запускает; сохраните diff рендера перед up, чтобы сравнить со первым стеком.
Ниже — отправная точка для дежурства и разборов: подставьте свои фрагменты compose и пороги мониторинга хоста; это не внешняя SLA. При «редком попадании не в тот экземпляр» сохраните как минимум срендеренные конфиги обоих стеков, сегмент сети из docker inspect и снимок upstream обратного прокси.
up второго стека выполните ss -lntp или эквивалент и приложите вывод к тикету.json-file двумя стеками узким местом чаще становятся inode и полоса, а не CPU; ритм обхода см. в материале о базовой линии.| Симптом | С чего проверять | Команда или артефакт |
|---|---|---|
| В контейнере нет API Key | Путь env_file, рабочий каталог compose | docker compose config и сравнение с выводом env из exec |
| Дрожь перезапусков по healthcheck | start_period, CPU steal | dmesg на хосте, статистика cgroup и временная шкала логов контейнера |
| Запросы попадают не в тот экземпляр | upstream прокси, «зависшие» старые контейнеры | docker ps -a до и после reload прокси и diff файла upstream |
Важно: перезаписать один и тот же путь .env, не остановив первый стек, перепутает порядок ротации ключей между стеками; всегда копируйте новый файл и только потом переключайте ссылку.
На малопамятном VPS насильно держать два производственных OpenClaw чаще ломается по диску и логам, а не по вычислительной мощности; без отдельных каталогов данных и таблицы портов разбор инцидентов превращается в угадывание, к какому Gateway вы подключились. Ручные правки compose без сохранённого diff рендера потом не ответят на вопрос, кто и какую переменную окружения менял.
Командам, которым нужны стабильный хост, предсказуемая полоса и изолируемые рабочие каталоги, проще пройти этот чеклист на заказном облачном Mac или выделенном тарифе VPS; если тестовые несколько экземпляров и продакшен должны жить в одной операционной истории, аренда Mac Mini в облаке VpsMesh часто удобнее: роли узлов разделяются, цепочку можно аудировать, а набор отличий compose и политику очередей так же принять по чеклисту.
По сводной таблице из основного текста проверьте, не пересекаются ли с первым стеком анонимные тома, имя сети по умолчанию, порты хоста и env_file; чаще всего проблема в том, что переименовали только каталог. Подробнее про healthcheck и restart — в статье о производственной базе Compose.
Часто не загружен нужный env_file, не совпадает рабочий каталог или переменные объявлены только в секции build; пройдите шесть шагов из статьи с docker compose config и exec. Для старта см. раздел про переменные окружения в статье про Exit 137 и первичную диагностику.
Сначала выполните docker compose down для второго стека и убедитесь, что порты свободны, затем сделайте резервные копии обоих каталогов данных; не удаляйте тома до экспорта конфигурации. Тарифы — на странице цен, справка — в центре помощи, оформление заказа — на странице заказа.