Vlastní hosting
Node a zapisovatelný adresář jsou celý požadavek. Níže uvedená tvrzení byla přečtena ze souborů uvedených vedle nich; cokoli, co nebylo možné potvrdit, zde není.
Vstupní body
- package.json vyžaduje Node >= 22.5. Úložiště SQLite je vlastní modul Node node:sqlite.
- Neexistuje žádný seznam závislostí: aplikace, balíčky, skripty a testy běží na standardní knihovně Node a Dockerfile nic neinstaluje.
- Existují tři procesy; každý otevírá databázi a při spuštění spouští migraci.
node apps/web/server/main.mjs # hub + console + embedded API
API_EMBED=false node apps/api/src/main.mjs # API only, no pages
node apps/worker/src/run.mjs # probes, latency, rollup, housekeeping
Úložiště dat
DATABASE_URL=sqlite:./data/llmeu.db nepotřebuje server a adresář a soubor se vytvoří při prvním otevření. Handle běží v režimu WAL se zapnutými cizími klíči a 5s časovým limitem zaneprázdnění.
packages/shared/src/db/schema.sql je schéma. Je pouze pro vytváření a idempotentní, takže opětovné spuštění je bezpečné; sloupec přidaný do existující tabulky musí být také deklarován v aditivním kroku v packages/shared/src/db/index.mjs.
URL postgres:// používá samostatnou větev adaptéru. Tato větev vyžaduje balíček pg, který není deklarovanou závislostí, a záhlaví schema.sql říká, aby se s cestou Postgres zacházelo jako s neověřenou, dokud nebude existovat skutečný ovladač a otestovaná migrace. SQLite je cesta, kterou toto úložiště provozuje.
Operátorské CLI
node scripts/db.mjs čte DATABASE_URL a nepotřebuje žádné služby. Příkazy:
| Příkaz | Co dělá |
|---|---|
| node scripts/db.mjs migrate | Použije schema.sql a ohlásí počet příkazů. |
| node scripts/db.mjs seed | Vloží nebo obnoví katalog a demo organizaci a zapíše demo klíč do data/demo-key.txt s právy 0600. |
| node scripts/db.mjs reset | Pouze pro SQLite: odstraní databázový soubor a jeho -wal a -shm společníky, poté migruje a naplní. Na Postgresu odmítne. |
| node scripts/db.mjs status | Vypíše engine, počet tabulek a počet řádků každé neprázdné tabulky. |
| node scripts/db.mjs demo-key | Vydá nový klíč pro demo organizaci a jednou jej vypíše. |
| node scripts/db.mjs passwd <email> | Nastaví heslo uživatele ze serveru a smaže všechny relace tohoto uživatele. Toto je cesta pro obnovení, když není nakonfigurován poštovní přenos. Bez --password vygeneruje jedno a jednou jej vypíše. |
Prostředí
Seskupeno tak, jak je seskupuje .env.example.
| Skupina | Proměnné | Poznámky |
|---|---|---|
| URL a porty | APP_URL, API_URL, WEB_PORT, API_PORT, API_EMBED, PUBLIC_API_URL | Port API je ve výchozím nastavení 8088, ne 8080. API_EMBED=false je pro nasazení, které spouští API jako vlastní proces; PUBLIC_API_URL je základ zobrazovaný v úryvcích dokumentace. |
| Úložiště dat | DATABASE_URL, REDIS_URL | DATABASE_URL vybírá úložiště; REDIS_URL je vyhrazeno pro frontu úloh a cesta kódu v1 jej nečte. |
| Inference | INFERENCE_MOCK, GPU_ENABLED, VLLM_BASE_URL, VLLM_REGION, VLLM_MODEL_VERSION, VLLM_BASE_URL_<REGION>, DEFAULT_REGION, PARTNER_* | Viz část o inferenci níže; PARTNER_* pokrývá základní URL partnera, region, třídu suverenity a klíč API. |
| Fakturace | FX_EUR_USD, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | Účetní kniha je vedena v mikrojenech USD a EUR se pro zobrazení odvozuje při FX_EUR_USD. |
| MAIL_FROM, MAIL_SMTP_HOST, MAIL_SMTP_PORT, MAIL_SMTP_SECURE, MAIL_SMTP_USER, MAIL_SMTP_PASS, MAIL_TIMEOUT_MS, MAIL_API_URL, MAIL_API_KEY | Nastavte MAIL_SMTP_HOST pro SMTP, nebo MAIL_API_URL s MAIL_FROM pro HTTP relay, nebo ani jedno. | |
| Zabezpečení | NODE_ENV, LLMEU_IP_SALT, LLMEU_DEMO_PASSWORD, LLMEU_KEY_ENV | NODE_ENV=production označuje relační cookies jako Secure. LLMEU_IP_SALT solí hashovanou IP klienta a měl by se měnit pro každé nasazení. LLMEU_KEY_ENV přidává generovaným klíčům předponu llmeu_live_ nebo llmeu_test_. |
| Různé | LOG_LEVEL | LOG_LEVEL nastavuje minimální úroveň logu. |
Docker
Compose a image jsou volitelné: vlastní sada úložiště nevyžaduje Docker a primární cestou je lokální proces bez služeb.
- Výchozí profil spouští web: porty 3000 a 8088, SQLite na svazku llmeu-data v /app/data, vestavěné API a healthcheck na /healthz.
- Stejný image spouští worker s node apps/worker/src/run.mjs, čeká, až bude web zdravý, a sdílí svazek llmeu-data.
- Dva další profily jsou ve výchozím nastavení vypnuté: postgres (postgres:16-alpine) a redis (redis:7-alpine, rezervováno a nečteno cestou kódu v1).
- Profil gpu spouští vllm/vllm-openai s rezervací zařízení NVIDIA a připojuje váhy pouze pro čtení z hostitele; není ve výchozím nastavení povolen, protože tvrdit inference v EU bez GPU by bylo nepravdivé.
- Dockerfile je FROM node:24-alpine s tini, bez kroku sestavení a bez instalace závislostí, běží jako uživatel node, zapisuje pouze do /app/data, vystavuje 3000 a 8088 a spouští apps/web/server/main.mjs.
Zálohy
node scripts/backup.mjs bez přepínačů zapíše ./backups/llmeu-<stamp>.db. SQLite se kopíruje pomocí VACUUM INTO, nikdy cp, protože živá WAL databáze zkopírovaná pomocí cp může vést k roztrženému nebo zastaralému stavu.
node scripts/backup.mjs # ./backups/llmeu-<stamp>.db
node scripts/backup.mjs --out /srv/backups/ # explicit destination
node scripts/backup.mjs --verify ./backups/llmeu-<stamp>.db
node scripts/backup.mjs --restore ./backups/llmeu-<stamp>.db --yes
node scripts/backup.mjs --list
Každá záloha SQLite je ověřena předtím, než skript ohlásí úspěch: obnoví se do dočasné kopie, PRAGMA integrity_check musí vrátit ok, schéma se znovu použije a vypíší se počty řádků pro modely, organizace a uživatele.
S URL postgres:// skript použije pg_dump --format=custom a potřebuje pg_dump v PATH; výpis nelze otevřít jako databázi, takže jeho počty řádků vyžadují zkušební obnovení.
Pošta
Transakční pošta – reset hesla, ověření adresy, pozvánky – používá MAIL_SMTP_* nebo MAIL_API_URL s MAIL_FROM. Transport se volí jednou při spuštění a je uveden na každé stránce, která potřebuje poštu.
Nasazení bez ani jednoho z nich je podporovaný stav: registrace, přihlášení, změna hesla, týmy a pozvánky fungují, ale pošta pro reset hesla a ověření tam nemůže být zpracována. Stránky to uvádějí a node scripts/db.mjs passwd <email> je cesta k obnově.
Inferenční backendy
Řádek koncového bodu pojmenovává runtime a region a registr backendů vybírá adaptér podle regionu, takže na koncový bod může odpovědět pouze stroj v regionu, který pojmenovává.
- INFERENCE_MOCK=true zachovává deterministický mock backend, který nepotřebuje GPU ani váhy.
- GPU_ENABLED=false vylučuje spravované backendy; při GPU_ENABLED=true se VLLM_BASE_URL vztahuje na jediný region pojmenovaný VLLM_REGION.
- Nasazení s několika regiony nastavuje jednu proměnnou na region, pojmenovanou podle slugu regionu (například VLLM_BASE_URL_DE_FRA). Koncový bod v regionu bez nakonfigurovaného backendu je odmítnut, místo aby byl obsloužen ze stroje v jiném regionu.
- Partnerské backendy pocházejí z PARTNER_BASE_URL_<REGION> a přebírají PARTNER_SOVEREIGNTY a PARTNER_API_KEY; server povoluje použití partnera, když je nastaveno PARTNER_BASE_URL.
Bez GPU odpovídá mock backend. Jeho region je dev-mock a jeho výstup uvádí, že jde o mock backend, že neběžely žádné skutečné váhy a že inference první strany vyžaduje VLLM_BASE_URL a příznak gpu_enabled. Úspěch mocku, který by vypadal jako skutečný, by byl jediná věc, kterou tento produkt nikdy nesmí vydat.