Основа платформи
Libre WebUI підтримує локальний профіль solo і спільний team. Solo використовує SQLite, зашифровані локальні блоби, зашифровані вбудовані вектори, локальну координацію й вбудований обробник постійних завдань. Team використовує PostgreSQL, приватні сумісні з S3 блоби, PGVector, Redis і зовнішній обробник. Запуск відхиляє змішані профілі замість мовчазного розподілу стану між локальними та спільними серверними частинами.
Поточний етап
| Область | Реалізована основа | Залишкова робота викликувачів |
|---|---|---|
| Постійність | Репозиторії SQLite/PostgreSQL, незмінні міграції, транзакції пулу | Нові домени мають дотримуватися меж репозиторію |
| Блоби | Зашифровані локальні/S3 потокові сховища, діапазони, контрольні суми, квоти | Перенести вкладення, аватари й решту вбудованих двійкових полів |
| Вектори | Зашифровані вбудовані вектори, ACL PGVector і безпечна перебудова індексу | Нові виклики векторних подань мають зберігати контракт повноважень і життєвого циклу |
| Координація | Локальні/Redis події, кеш, оренди, ліміти, скасування кешу, стан | Redis має залишатися неавторитетним |
| Завдання/події | Черги SQLite/PostgreSQL, транзакційні події, обробники, повтори, скасування, адміністрування | Кожен новий наслідок потребує ідемпотентності або вихідної черги |
| Операції | Перевірки стану, підписані/зашифровані архіви, чисте відновлення, перевірка | Тренувати відновлення й приймання між репліками для кожного середовища |
Профілі середовища
LIBRE_PLATFORM_MODE=solo типово вибирає SQLite, локальні блоби, вбудовані вектори, локальну координацію й вбудованого обробника. Redis можна вибрати в solo, але він не робить SQLite або локальні файли безпечними для кількох реплік.
LIBRE_PLATFORM_MODE=team одночасно потребує:
DATABASE_BACKEND=postgresізDATABASE_URL;BLOB_STORE_BACKEND=s3;VECTOR_STORE_BACKEND=pgvector;COORDINATION_BACKEND=redisізREDIS_URL; іJOB_WORKER_MODE=external.
Це цілісний набір. Team не запускається без будь-якої спільної залежності або за змішування локальної серверної частини.
Міграція наявного встановлення solo
Зупиніть усі програми й обробники. Приклади використовують установлений libre-webui з npm/Homebrew; без встановлення замініть на npx --yes libre-webui@latest. Із вихідного коду зберіть один раз і замініть libre-webui migrate-postgres на npm run migrate:postgres --. Налаштуйте цільові PostgreSQL, S3 і версії ключів точно як team, а потім виконайте аналіз лише для читання:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode dry-run
Застосовуйте лише до порожньої цілі зі звіту. Збій залишає журнал із контрольними сумами; відновлюйте ту саму пару, не починайте непов’язаний імпорт:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply
# Only after an interrupted apply of this exact source and target:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply --resume
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode validate
Позначка завершення з’являється лише після перенесення й автентифікації реляційних рядків, плагінів, локальних зашифрованих блобів, вбудованих векторів і старих векторів персон у PostgreSQL/S3/PGVector. Команда не створює ключ джерела: ENCRYPTION_KEY має збігатися з .encryption_key, а STORAGE_ENCRYPTION_KEYS містити активний ключ і legacy.
Запуск вбудованого профілю team
Почніть із шаблону з безпечною відмовою. Готовий файл тримайте поза репозиторієм із доступом оператора:
cp deploy/team/.env.example /absolute/path/to/libre-team.env
chmod 600 /absolute/path/to/libre-team.env
Замініть усі REPLACE_*. Пароль PostgreSQL створіть абеткою, безпечною для URL, наприклад openssl rand -hex 32, оскільки літерал використовується на сервері й у DATABASE_URL. ENCRYPTION_KEY та значення STORAGE_ENCRYPTION_KEYS мають містити 64 шістнадцяткові символи. У новому встановленні legacy дорівнює ENCRYPTION_KEY; під час міграції обидва дорівнюють джерелу. Для нових записів блобів використовуйте інший активний ключ і зберігайте старі до підтвердження відсутності використання.
Файл також задає POSTGRES_MIGRATION_MODE, POSTGRES_POOL_MAX, час очікування PostgreSQL, REDIS_CONNECT_TIMEOUT_MS, OLLAMA_BASE_URL, OLLAMA_TIMEOUT, OLLAMA_LONG_OPERATION_TIMEOUT, OLLAMA_MAX_CONTEXT; Compose однаково передає їх програмі й обробнику. Час очікування приймає 1 000–3 600 000 мс, контекст 128–2 097 152 токенів, довгий час не може бути коротшим за звичайний; неправильні значення зупиняють обидві точки входу до створення стану. Локальні Agent CLI й файли Codex OAuth не підтримуються зовнішніми обробниками, тому team закріплює їх вимкненими й відхиляє ввімкнення. Запустіть репліки, обробник, PostgreSQL/PGVector, Redis, версіонований MinIO і шлюз:
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml ps
Базовий team не підключає сокет Docker, тому Docker Work недоступний. Умикайте лише виробниче перевизначення в усіх командах:
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml \
up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml ps
Перевизначення спрямовує програму й обробник до одного фільтрованого проксі сокета у внутрішній мережі. Вони не отримують необроблений сокет чи групу, а каталоги Work на хості вимкнено. Проксі надає info, images, containers, exec, volumes, networks і потрібні методи запису. Це звужує API, але не створює межу орендарів: контейнер може підключати шляхи хоста. Для ізоляції використовуйте виділену віртуальну машину або окремий/непривілейований демон Work.
Не відкривайте PostgreSQL, Redis і MinIO з Compose. Для керованих залежностей використовуйте Helm team із TLS; Compose вимикає TLS PostgreSQL лише в приватній мережі. Перевірка готовності не проходить без зовнішнього обробника.
Межа постійності й міграції
Ідентичність і авторизація використовують асинхронні репозиторії. Зворотний виклик транзакції отримує одиницю роботи на тому самому з’єднанні; глобальний репозиторій усередині відхиляється. Це межа пулу PostgreSQL зі збереженням поведінки SQLite.
Координатор SQLite приймає старе встановлення лише після перевірки схеми. Він записує номер, ім’я й контрольну суму міграції, перевіряє під час кожного запуску, відхиляє новіші, невідомі чи невідповідні журнали й зупиняє запуск за помилки. Готовність та інвентаризація відновлення використовують той самий контракт.
До імпорту служб зі станом запуск копіює SQLite й активні WAL/SHM до приватного тимчасового каталогу й перевіряє. PLATFORM_PREFLIGHT_TMP_DIR має вміщувати базу та WAL. Docker/Helm підключають виділене дискове тимчасове сховище, а не обмежений /tmp. Відсутній старий ключ або вкладений каталог блокує запуск до створення заміни, бази чи плагінів.
Схема v4 додає ключовий маркер рівності для зашифрованої електронної пошти. Відновлення потребує наявності й збігу. У вузькому вікні збою після фіксації v4 запуск допускає відсутній маркер за автентифікованої адреси або старе значення без оболонки, щоб ініціалізація завершила доповнення. Старі випуски приймали будь-які рядки й очищали поле порожнім; прийняття зберігає непорожні та нормалізує порожні в NULL. Пошкоджені значення, схожі на оболонку, і невідповідності зупиняють перевірку.
Служби використовують асинхронні репозиторії діалектів. Вбудований SQLite обмежено адаптерами, перевіркою міграції/відновлення та явно доданими перевірками стану. Сховище середовища створюється з Persistence; PostgreSQL не повертається до єдиного SQLite чи JSON, залежного від поточного каталогу.
Спільне середовище постійних завдань нейтральне до драйвера. Авторизація читається з репозиторію ідентичності, створення вбудованого репозиторію завдань обмежено межею складання адаптерів. Публікатори отримують непрозорий виконавець SQLite або прив’язаний до транзакції PostgreSQL, ніколи better-sqlite3. Тест відхиляє вбудовані дескриптори в контрактах завдань, ресурсів, ідентичності, чату й Work.
Основа сховищ блобів і векторів
Галерея й джерела документів використовують BlobStore; RAG і пам’ять персон — VectorStore. Старі рядки галереї SQLite читаються двома шляхами й під час першого доступу перетворюються на посилання на блоби. Реляційні метадані й постійне посилання авторитетні; адреси постачальника й фізичні ключі S3 не зберігаються як вміст. Вкладення, аватари й інші вбудовані поля ще не перенесено.
Відновлення послідовно автентифікує кожен постійний об’єкт і оболонку вектора за лімітами. Розпізнавані старі текстові оболонки й двійкові оболонки голосів суворо перевіряються ENCRYPTION_KEY; резервний механізм середовища, що повертає оригінал, не використовується. Джерело не ініціалізується, виправляється, переписується чи видаляється; пошкоджений шифротекст, неправильні ключі, неканонічні структури й ліміти блокують знімок.
Ліміти: 250 000 об’єктів, 64 GiB зашифрованих і відкритих байтів блобів, 250 000 рядків векторів, 4 GiB шифротексту векторів і 500 мільйонів складників. Тести можуть перевизначити через RecoveryInventoryOptions; CLI не вибирає зразки й не пропускає надлишок.
Перевірка старого шифротексту обмежена мільйоном полів і 16 GiB збережених та автентифікованих відкритих даних. Справжній відкритий текст старих схем сумісний, оскільки позначки немає; рахуються автентифіковані оболонки. Збережені голоси однозначні й використовують профіль, власника й поле як додаткові дані.
Зашифровані локальні блоби
BlobStore прив’язаний до власника й надає потокові put/read, metadata/stat, включні діапазони й ідемпотентне видалення. LocalEncryptedBlobStore записує об’єкти UUID під коренем програми; ціль ${DATA_DIR}/blobs. Використовує виняткове проміжне сховище, fsync, атомарне перейменування, каталоги 0700 і файли 0600.
Об’єкт має випадковий 256-бітовий ключ даних. AES-256-GCM шифрує приватні метадані й незалежно автентифікує фрагменти. Додаткові дані пов’язують ID блоба, власника, призначення, індекс фрагмента й довжину відкритих даних. Версіоноване сховище ключів обгортає ключ даних. Опис містить розмір, SHA-256, тип, час, версію формату й ID ключа. Повне читання перевіряє SHA-256; діапазонне — усі зачеплені фрагменти.
Квота резервує місткість до потоку, враховує справжні байти, фіксує лише після атомарної видимості й звільняє невдалі резервування. SQLite використовує BEGIN IMMEDIATE; PostgreSQL — серіалізовані транзакції й блокування рядків. Метадані S3 і квота фіксуються чи відкочуються однією транзакцією. Запуск узгоджує завершені резервування й записи без фізичного блоба. BLOB_QUOTA_BYTES_PER_USER задає ліміт, BLOB_QUOTA_RESERVATION_TTL_MS — час залишеного резервування.
BLOB_STORE_BACKEND=s3 використовує приватне сумісне з S3 сховище. Libre завантажує непрозорі ключі й зашифровані потоки фрагментів, зберігає описи в PostgreSQL, підтримує діапазони HTTP, перевіряє SHA-256 відкритих і зашифрованих даних та ідемпотентно видаляє. Рядок видалення залишається до фізичного й атомарного видалення метаданих/квоти; узгодження повторює перервані видалення й вилучає старі залишки. Тест MinIO охоплює читання/видалення між репліками, ізоляцію орендарів, суперечки квот, невикористані потоки й помилки БД.
Зашифровані вбудовані вектори
VectorStore потребує виконавця під час кожного запиту чи зміни. Записи містять простір імен, непрозорий ID орендаря, власника, ресурс, модель векторних подань, виміри, версію, редакцію джерела, атрибути рівності й права користувачів/груп.
SQLite застосовує умови простору імен, моделі, вимірів, версії, власника/права, ресурсу й атрибутів до виходу шифротексту. Лише обмежені дозволені кандидати розшифровуються й оцінюються косинусною відстанню. Однаковий ID ізольовано за власником без розкриття інших орендарів. Оновлення атомарно замінює вектори, ACL й атрибути; видалення прив’язане до власника й каскадне.
Векторні подання використовують AES-256-GCM з ідентичністю й метаданими моделі як додатковими даними. Доступні для запиту ідентичність, права, модель, версія, редакція й фільтри залишаються відкритими, тому секрети заборонено. Векторні подання — чутливі похідні дані.
VECTOR_STORE_BACKEND=pgvector застосовує всі умови в тому самому SQL, що й упорядкування відстані та LIMIT. Післяфільтрування глобальних найближчих сусідів заборонено. Групи визначаються з довіреного поточного членства під час кожного запиту; groupIds викликувача ігноруються. Відкликання негайне, підроблені твердження не працюють.
Опрацювання документа й повторне створення векторних подань фіксують одну незмінну специфікацію до роботи: увімкнення, модель, версії вектора/поділу, розмір, перекриття й поріг. Та сама специфікація керує фрагментами, реляційною публікацією, оновленням і запитом; зміна налаштування не змішує моделі чи пороги. Метадані фіксують сукупну редакцію й специфікацію, тому SQL залишається маніфестом.
Повторне створення тримає автоматично поновлювану оренду документа й перевіряє рядок власника та позначку видалення до публікації, до й після зміни. Видалення може зафіксуватися під час оновлення; наступна перевірка видаляє відтворені вектори. Читання PostgreSQL/team не змінює PGVector. SQLite ліниво публікує лише за точного маніфесту й оренди; зайнята чи замінена редакція пропускається для пошуку ключових слів або явного повторення.
Індекси замінюються компенсованими партіями до 1 000; перевірки посторінково обходять повний маніфест. Документ може мати 100 000 фрагментів; 100 001 відхиляється до створення вектора/публікації й потрапляє до черги невдалих без повтору. Збільште розмір фрагмента або вилучіть зайві розриви.
Solo до маніфесту може мати автентифіковані вбудовані вектори без моделі/подільника. Перше семантичне використання лише за наявністю запускає повторний поділ авторитетного тексту й повне створення за поточною специфікацією та орендою. Старий вміст не копіюється й не позначається поточним налаштуванням. Помилка постачальника чи зайнята оренда залишає старий пошук ключових слів.
Міграція SQLite до team безпечно відмовляє, якщо старий документ не покрито поточними метаданими маніфесту й точним зашифрованим платформним індексом. Поточні налаштування не доводять історичну модель. За блокування запустіть поточний solo/SQLite з тими самими DATA_DIR і ENCRYPTION_KEY, виберіть модель, використайте Settings -> Documents -> Regenerate embeddings для власників і повторіть пробу. Лише тоді team ігнорує вбудований шифротекст і переносить доведені вектори.
Конфіденційність різниться. SQLite шифрує векторні подання AES-256-GCM після ACL. PGVector працює з числами й не шифрує колонку на рівні програми. Вимагайте TLS, зашифровані томи/копії PostgreSQL, роль найменших привілеїв, обмежене адміністрування й журнали SQL без даних. Текст джерела, пам’ять персон, метадані галереї й описи залишаються зашифрованими оболонкою. Атрибути відкриті й не мають містити секретів.
Ключі шифрування сховища
За версіонованого сховища ключів потрібно задати сталий 64-символьний ENCRYPTION_KEY, той самий під legacy у STORAGE_ENCRYPTION_KEYS і STORAGE_ENCRYPTION_ACTIVE_KEY_ID. Записи використовують активний ключ; читання приймає всі ID для поетапної ротації. Вимога запобігає окремому ключу старої служби. Зберігайте старі до переписування чи повторного обгортання й перевірки всіх об’єктів.
Без карти адаптер приймає 64-символьний ENCRYPTION_KEY як legacy або читає ${DATA_DIR}/.encryption_key. Фабрика приймає лише звичайний приватний файл без символічного посилання; не створює й не змінює. Суперечність середовища з постійним ключем закриває запуск. Під час ротації старий ключ залишається як legacy до переписування й перевірки. Відсутні, неправильні, невідповідні й невідомі ключі безпечно відхиляються.
Вбудовані запити застосовують ACL/метадані в SQLite, а потім підсумовують кількість кандидатів, зашифровані байти й обсяг обчислень за вимірами до повернення шифротексту в Node. Перевищення бюджету закриває запит і потребує звуження.
Координація
Контракт надає події, кеш із завершенням, захищені оренди й ліміти фіксованого вікна. Локальна реалізація лише для однієї репліки solo. Redis використовує окремі клієнти команд/підписок, обмежений вміст, перевірки стану, простір імен, атомарні сценарії, унікальні маркери власника, завершення й огородження. Після помилки Redis немає локального запасного варіанта.
Redis не є джерелом істини. Авторизація, постійні завдання й відтворювані події залишаються в БД; Redis використовується для пробудження, скасування кешу, присутності, квот і координації. Критична робота перевіряє оренду БД/огородження до наслідку.
Квитки, кеші, спільне скасування, ліміти з’єднань, події Work і розподілені блокування використовують межу. Сам Redis не робить локальну постійність спільною; потрібен повний team.
Постійні завдання й події
Міграція SQLite v3 створює таблиці постійних завдань, спроб, голів потоків і впорядкованих подій. Контракт підтримує ідемпотентне додавання до черги, обмежений повтор, скасування, поступ, поновлення/повернення оренди, чергу невдалих і відтворення за курсором. Зашифрований JSON використовує сховище ключів платформи з ідентичністю завдання/події як додатковими даними; посилання — непрозорі обмежені ID.
SQLite v13 і PostgreSQL v12 додають індекс (stream_id, subject_id, global_cursor) для відтворення за генеруванням. Фільтри застосовуються до ліміту наздоганяння, тому старі генерування не витрачають бюджет і не спричиняють повне сканування.
Програма й окремий обробник реєструють перевірені обробники для опрацювання документів, продовження медіа й очищення. Адміністратор отримує обмежені перегляд/скасування. Додавання до черги ідемпотентне, а реляційне створення/видалення вставляє завдання в тій самій транзакції. Очищення видаляє вектори, приватні блоби, посилання, кеш і завдання черги безпечно для повторення.
Відновлення рахує стани/результати, потоки/курсори, блокує активну роботу й автентифікує вміст. Відхиляє невідповідність голів і непослідовні ряди.
Монотонні маркери оренди огороджують застарілі обробники. Це не забезпечує виконання рівно один раз: обробник може здійснити зовнішній наслідок і не записати успіх. Потрібні ключі ідемпотентності постачальника або транзакційна вихідна/вхідна черга й повторна авторизація виконавця перед наслідком.
SQLite v4 додає унікальний ключовий маркер пошуку електронної пошти поруч із випадковим шифротекстом. Це HMAC під ключем програми, що забезпечує виявлення дубліката без відкритого тексту чи детермінованого шифрування. Запуск автентифікує й доповнює старі адреси до приймання трафіку.
Стан і відновлення
Перевірки розрізняють працездатність процесу й готовність залежностей:
/healthі/health/liveперевіряють лише процес;/health/readyперевіряє БД, журнал схеми, сховище з записом і потрібні залежності з приховуванням подробиць. Не чекає необов’язкових постачальників; і/health/deepпотребує адміністратора й виконує перевірки цілісності SQLite та зовнішніх ключів в обмеженому обробнику поза циклом HTTP. Необов’язкові постачальники, як Ollama, дають попередження без зміни готовності.
Запустіть libre-webui recovery-check --json; із вихідного коду використовуйте npm run recovery:check -- --json. Інвентаризація лише для читання повідомляє ідентичності схеми/ключа, корінь блобів, старі/платформні вектори, автентифікує блоби/вектори, старі дані програми/голосу й зашифрований вміст завдань/подій, розміри, плагіни та їх розташування, медіа, ресурси/мітки Work, контрольні точки, активні виконання/завдання, блокування й винятки. Це перевірка до копії, а не копія. Див. Готовність до відновлення.
Сертифікована робота кількох реплік
Team сертифіковано для ≥3 реплік програми й ≥1 зовнішнього обробника за повного набору PostgreSQL, PGVector, Redis, S3, спільних секретів і JOB_WORKER_MODE=external. Helm перевіряє під час створення: більше однієї репліки без team не розгортається. Міграції вибирають лідера консультативним блокуванням PostgreSQL, унеможливлюючи перегони версій.
Сертифікація виконується: процес випуску запускає навчання трьох реплік (npm run test:team-platform) зі справжнім образом і перевіряє відновлення потоків між репліками, смерть обробника під час запису з детермінованим відтворенням, збій Redis з авторитетним SQL, відкликання за втрати координатора, спільні ліміти, повтор видалення S3 й ізоляцію орендарів. Посилення: secrets.existingSecret і networkPolicy.enabled. Безпека pod: без root, коренева система лише для читання, скинуті можливості, seccomp RuntimeDefault, без підвищення прав.
Відомі залишкові переходи
Основа не означає, що кожне двійкове поле вже є блобом. Аудіо збережених голосів, вкладення, аватари й майбутні двійкові дані плагінів потребують метаданих посилань, подвійного читання/доповнення, політики зберігання й тестів видалення. Кожен виклик векторних подань має передавати модель, виміри, версію, редакцію джерела, власника, область ресурсу й довірені права через VectorStore; прямий доступ до таблиці заборонено.
Нові тривалі або зовнішні наслідки мають реєструвати постійну ціль ресурсу, підтримувати скасування/повтор і транзакційну чергу з реляційною зміною. Додавайте кожен ресурс до міжреплічних перевірок завантаження, читання, пошуку, видалення, резервного копіювання й відновлення до ввімкнення в team.