Установка
Сборка/тесты: nix develop -c cargo build / cargo test; флейк даёт
тулчейн и линкер, reqwest на rustls — системный openssl не нужен.
Фреймворк — git-зависимость по ssh (запинен Cargo.lock’ом). В песочнице
nix-сборки ssh-ключей нет, поэтому вендоринг переписывает URL на https —
репозиторий публичный. Обновление фреймворка: cargo update -p eva +
новый хэш eva-0.1.0 в outputHashes флейка.
NixOS-модуль (основной путь)
nixosModules.default — сервис services.eva-kernel: несекретная часть
конфига декларируется в settings (уедет yaml’ом в /nix/store), секретные
секции — файлами в extraConfigFiles (ядро сливает несколько --config,
поздние поверх ранних; путь секрета sops-nix подходит, файл должен быть
читаем пользователем eva-kernel):
services.eva-kernel = {
enable = true;
settings = {
llm = {
provider = "openai";
model.general = "Hermes-4-70B";
base_url = "https://...";
};
memory.top_k = 8;
};
extraConfigFiles = [ "/run/secrets/eva-kernel-llm.yaml" ]; # llm: { api_key: ... }
};
Дефолты модуля: server.listen = 127.0.0.1:8090, db.path = /var/lib/eva-kernel/eva.db (StateDirectory сервиса). Опции user/group
(дефолт eva-kernel) модуль не создаёт — объяви на хосте. PATH юнита
включает системный профиль — инструменту shell нужны не только coreutils.
MCP-серверы объявляй секцией модуля services.eva-kernel.mcp.<имя>
(command/url/env/access/trusted_only/timeout), а не сырым settings.mcp:
stdio-бинарь модуль прячет за стабильный симлинк /run/eva-mcp/<имя>,
поэтому бамп пакета сервера не меняет config.yaml и не рестартует
ядро — activation перекидывает симлинк, убивает старый процесс, и ядро
лениво поднимает новый первым же вызовом:
services.eva-kernel.mcp = {
kana.command = [ "${kana-mcp}/bin/kana-mcp" ];
redose = { url = "http://127.0.0.1:8765/mcp"; trusted_only = true; };
};
Docker
Два пути, оба дают образ, который запускается где угодно без Nix.
Через Docker Compose (нужен только Docker, приватного доступа не
требует — зависимость eva публична по HTTPS):
cp config.example.yaml config.yaml # правь llm.api_key и т.д.
# для контейнера: server.listen: "0.0.0.0:8080", db.path: "/data/eva.db"
docker compose up -d
Конфиг монтируется из ./config.yaml в /config/config.yaml, состояние
(SQLite) живёт в томе /data. Секреты удобно вынести отдельным файлом и
подмешать вторым --config (см. закомментированный command в compose).
Через Nix (two-staged) — переиспользует сборку флейка, даёт минимальный воспроизводимый образ:
nix build .#dockerImage && ./result | docker load
docker run --rm -v "$PWD/config.yaml:/config/config.yaml:ro" \
-v eva-data:/data -p 8080:8080 eva-kernel:latest