Перейти к содержимому

Развёртывание Chimera на сервере (VPS)

Chimera работает как долгоживущий процесс — шлюз. Добавьте --cron, и она вдобавок будет запускать задания по расписанию, то есть действовать вовремя, а не только когда ей напишут. Это руководство описывает развёртывание на VPS за $5 двумя способами: Docker Compose (рекомендуется) или systemd.

Состояние — долговременная память, задания по расписанию, траектории, журнал аудита — живёт в CHIMERA_HOME (это каталог). Сохраните его (том Docker или настоящий путь), и агент переживёт перезапуски.


0. Что нужно заранее

  • VPS на Linux (одного ядра и 1 ГБ памяти вполне достаточно для одного агента).
  • Хотя бы один ключ поставщика. Самое дешёвое начало — ключ OpenRouter.
  • Для публичных входящих вебхуков (WhatsApp Cloud API, POST /webhook/<hook>) — домен и обратный прокси с TLS (Caddy или nginx). Не нужно для Discord, Telegram, Slack и Signal, которые подключаются наружу сами.

Создайте файл окружения из шаблона и впишите ключ:

cp .env.example .env
# edit .env — e.g. set CHIMERA_OPENROUTER_KEYS=sk-or-...

1. Docker Compose (рекомендуется)

docker compose up -d       # build + run; restarts on crash and on reboot
docker compose logs -f     # watch it
docker compose ps          # status + health

Это запускает chimera serve --host 0.0.0.0 --cron: HTTP-шлюз (/chat, /webhook/<hook>, /health) плюс демон расписания. Состояние сохраняется в томе chimera-data.

Обслуживать платформу общения (на примере Discord) — задайте токен в .env, затем переопределите команду в docker-compose.yml:

    command: ["serve", "--host", "0.0.0.0", "--cron", "--discord"]

и снова выполните docker compose up -d. (Telegram, Slack и Signal работают так же через свои флаги; каждому нужен свой токен CHIMERA_* — смотрите .env.example.)

Обновление до новой версии:

git pull && docker compose up -d --build

2. systemd (без Docker)

Установите в виртуальное окружение прямо на хосте:

git clone https://github.com/brcampidelli/chimera-agent.git /opt/chimera
cd /opt/chimera
python3 -m venv .venv && . .venv/bin/activate
pip install '.[messaging,mcp]'
cp .env.example .env   # then edit it

Создайте /etc/systemd/system/chimera.service:

[Unit]
Description=Chimera Agent gateway + cron daemon
After=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/chimera
EnvironmentFile=/opt/chimera/.env
Environment=CHIMERA_HOME=/opt/chimera/state
ExecStart=/opt/chimera/.venv/bin/chimera serve --host 0.0.0.0 --cron
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now chimera
sudo systemctl status chimera
journalctl -u chimera -f

3. Как поручить работу заранее (демон --cron)

--cron только выполняет задания, которые вы завели. Добавляйте их из командной строки (они сохраняются в CHIMERA_HOME):

chimera cron add "morning-brief" "0 8 * * *" "Summarize overnight news and post it."
chimera cron add "nightly-backup" "0 3 * * *" "Back up the important files."
chimera cron list

Внутри Docker:

docker compose exec chimera chimera cron add "morning-brief" "0 8 * * *" "..."

Демон тикает каждые --cron-tick секунд (по умолчанию 30) и передаёт агенту действие каждого задания, когда подходит его срок. Сбойное задание записывается в журнал и никогда не останавливает демон.

Спросить у расписания то, о чём оно молчит

chimera cron doctor

Расписание может замолчать двумя способами, и пока вы не спросите, оба выглядят одинаково — как расписание, у которого ничего не назначено:

  • Ничего не выполнялось. Демон умер, контейнер так и не перезапустили, хост уснул. Ни исключения, ни строки в журнале, ни вердикта. Все остальные механизмы честности здесь стоят ниже по течению от состоявшегося запуска, поэтому ни одному из них не достаётся хода.
  • Всё выполнялось и всё провалилось. Демон жив, last_run был минуту назад, расписание движется — и при этом каждая отправка проваливается уже месяц. Это выглядит здоровее первого случая, потому что поле, похожее на признак здоровья, записывает попытку, а не исход.

cron doctor задаёт оба вопроса и даёт разные советы, потому что у этих неисправностей нет ничего общего: просрочка — про демон, а провалы — про задание. chimera cron list печатает строку, когда хоть что-то проваливается, чтобы вам не нужно было знать о существовании команды, чтобы это обнаружить.

Чем это не является. Это вопрос, а не наблюдатель: пока процесс лежит, здесь никто ничего не замечает — по той же причине, по которой упавший процесс не может записать собственное падение. Он честно отвечает в тот миг, когда кто-нибудь спросит: оболочка, приложение, следующий запуск. Настоящему сторожу нужны собственные часы и собственная живучесть, а это отдельное решение и оно отслеживается как issue #26. Если вам нужно оповещение, а не ответ, запускайте это из собственного cron хоста:

*/30 * * * * cd /opt/chimera && .venv/bin/chimera cron doctor | mail -s "chimera" you@example.com

Это работает, потому что за ним присматривает не сама Chimera, — в чём и весь смысл.


4. Здоровье, резервные копии, безопасность

  • Здоровье: GET /health возвращает {"ok": true}. В Compose проверка здоровья уже настроена.
  • Резервные копии: сохраняйте том chimera-data (Docker) или каталог CHIMERA_HOME (systemd) — это всё долговечное состояние. Например: docker run --rm -v chimera-data:/d -v $PWD:/b busybox tar czf /b/chimera-state.tgz -C /d .
  • Секреты: держите ключи в .env (он в gitignore); никогда не запекайте их в образ.
  • Доступ снаружи: привязывайте шлюз к 0.0.0.0 только за брандмауэром или обратным прокси. Задайте CHIMERA_SERVER_TOKEN, чтобы требовать Authorization: Bearer <token> на HTTP-шлюзе и в API приложения (интерфейсу токен выдаётся автоматически только для клиентов с loopback, поэтому выставленный наружу экземпляр остаётся за вашей собственной аутентификацией). Аутентификация включается по желанию и по умолчанию пуста, так что без этой переменной её нет — ограничьте порт или откройте только путь вебхука. Как достучаться до этого экземпляра из приложения, смотрите в §5.
  • Песочница: задайте CHIMERA_SANDBOX=docker, чтобы инструменты оболочки и выполнения кода работали в одноразовом контейнере, а не на хосте.
  • Выполнение на хосте без присмотра: с 2026-07-20 запуск без человека отказывает в командах на хосте при значении по умолчанию CHIMERA_HOST_EXEC=ask (подтверждать не на чем — терминала нет). Развёртывание, которому действительно нужно, чтобы агент выполнял оболочку на хосте, осознанно ставит CHIMERA_HOST_EXEC=allow; более безопасный вариант — CHIMERA_SANDBOX=docker, где эта проверка пропускается, потому что контейнер действительно изолирует. Точно так же сервер API взводит сужение по заражению (CHIMERA_TAINT_NARROW=1): после того как агент прочитал недоверенное содержимое, инструменты выполнения, записи и отправки наружу отказывают. Поставьте 0, чтобы он продолжал действовать самостоятельно.

5. Как достучаться до этого экземпляра из приложения

Приложение по умолчанию говорит с той Chimera, которую само запускает на вашей машине. Начиная с v0.44 оно может указывать и на ту, которую вы держите сами, — на этот VPS, — и тогда приложение становится окном в агента, который и так всю ночь выполняет ваши задания.

Прочитайте эту часть, прежде чем открывать порт. То, что вы выставляете наружу, — не панель наблюдения. Каждый экран этого приложения — поверхность управления: он выполняет команды оболочки, правит файлы, раздаёт доску самостоятельных задач и меняет настройки. Экземпляр, доступный из интернета без токена, — это не «Chimera, на которую кто-то может посмотреть», а машина, на которой любой нашедший адрес может выполнять команды за счёт ваших ключей.

Должны выполняться три условия, и без первых двух приложение отказывается подключаться:

1 — TLS. Поставьте её за обратный прокси с настоящим сертификатом (Caddy получит его за вас):

chimera.seudominio.com {
    reverse_proxy 127.0.0.1:8765
}

Приложение отказывает адресу без https за пределами вашей машины, потому что токен едет в заголовке Authorization на каждом запросе — по обычному http это удостоверение, вручаемое каждому узлу между вами и сервером, и на экране при этом ничто не выглядело бы неправильно.

2 — Токен. Аутентификация включается по желанию и по умолчанию пуста:

CHIMERA_SERVER_TOKEN=$(openssl rand -hex 32)

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

Обратите внимание, чего сервер намеренно не делает: когда удалённый клиент запрашивает интерфейс, страница отдаётся без токена. Токен никогда не выдаётся по сети — вы копируете его в свой клиент один раз, отдельным путём. Именно поэтому в приложении есть поле для него.

3 — Источник вашего приложения. Приложение обслуживается собственным местным помощником, поэтому его запросы к этому экземпляру идут с другого источника, и браузер отбрасывает ответы, пока этот экземпляр не назовёт тот источник:

CHIMERA_ALLOWED_ORIGINS=http://127.0.0.1:45813

Приложение показывает точное значение, когда подключение не удаётся, — оно прямо в сообщении об ошибке, готовое к копированию. Порт постоянен для установки (он запоминается между запусками с версии v0.43), так что это задаётся один раз на каждую машину, с которой вы подключаетесь. Несколько источников перечисляются через запятую.

Эта настройка не является границей безопасности, и читать её так нельзя. CORS решает, какая страница может прочитать ответ, и ничего не решает о том, кто может вызывать. Воротами служит токен. Назвать источник, не задав токен, ничего не защищает — это лишь делает незащищённый экземпляр доступным из браузера в дополнение к curl.

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

Что приложение говорит при неудаче

  • «Токен отклонён» — адрес и источник верны, а значение неправильное.
  • «Не удалось достучаться» — либо адрес неверный, либо источник не разрешён. Браузер намеренно не даёт их различить, поэтому приложение называет оба и выдаёт вам источник, который нужно разрешить.
  • Предупреждение о версии — приложение сравнивает версию своего сервера с этой и называет оба числа. Оно не отказывает: сервер на выпуск позади обычно работает, а отказ запер бы вас на том самом экране, который нужен, чтобы это исправить. Некоторые конечные точки на старой стороне могут отсутствовать.

Ещё безопаснее

Обойдитесь вовсе без публичного порта: дотянитесь до VPS через WireGuard или сеть Tailscale и направьте приложение на частный адрес. Токен всё равно важен — частная сеть это комната поменьше, а не пустая.


6. Честное положение дел

Chimera находится в стадии альфа. Это разворачивается и работает, а демон расписания делает её действующей по собственному почину — но опыта промышленной эксплуатации у неё нет. Начинайте с заданий, где ставки невелики, следите за logs и держите в уме меры управления (--guard у solve, CHIMERA_SANDBOX=docker) для всего, что касается настоящих систем.

Где публикуются эти страницы

Эти файлы — исходник документации на chimeraagent.space, которая отрисовывает их прямо из этого каталога во время сборки. Правьте markdown здесь, и сайт последует за вами; второй копии, которую нужно держать в согласии, нет.

Конфигурация MkDocs, которая раньше лежала в mkdocs.yml, удалена. Она была полной — тема, навигация, десять страниц — и её никогда не публиковали: не было ни рабочего процесса, ни ветки gh-pages, поэтому инструкции по развёртыванию, стоявшие на этом месте, описывали сайт, которого не существовало. Конфигурация, которую никто не запускает, хуже её отсутствия, потому что следующий человек правит её навигацию и не может понять, почему ничего не меняется.

Изменить эту страницу на GitHub