Αυτοφιλοξενία

Το Node και ένας εγγράψιμος κατάλογος είναι η όλη απαίτηση. Οι δηλώσεις παρακάτω διαβάστηκαν από τα αρχεία που αναφέρονται δίπλα τους· ό,τι δεν μπόρεσε να επιβεβαιωθεί δεν βρίσκεται εδώ.

Σημεία εισόδου

  • Το package.json απαιτεί Node >= 22.5. Ο χώρος αποθήκευσης SQLite είναι η δική του μονάδα node:sqlite του Node.
  • Δεν υπάρχει καθόλου λίστα εξαρτήσεων: εφαρμογές, πακέτα, σενάρια και δοκιμές εκτελούνται στη τυπική βιβλιοθήκη του Node, και το Dockerfile δεν εγκαθιστά τίποτα.
  • Υπάρχουν τρεις διεργασίες· καθεμία ανοίγει τη βάση δεδομένων και εκτελεί τη μετανάστευση κατά την εκκίνηση.
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

Αποθήκη δεδομένων

Το DATABASE_URL=sqlite:./data/llmeu.db δεν χρειάζεται διακομιστή, και ο κατάλογος και το αρχείο δημιουργούνται στο πρώτο άνοιγμα. Το handle εκτελείται σε λειτουργία WAL με ενεργοποιημένα ξένα κλειδιά και χρονικό όριο απασχόλησης 5 δευτερολέπτων.

Το packages/shared/src/db/schema.sql είναι το σχήμα. Είναι μόνο για δημιουργία και idempotent, οπότε η εκ νέου εκτέλεσή του είναι ασφαλής; μια στήλη που προστίθεται σε έναν υπάρχοντα πίνακα πρέπει επίσης να δηλώνεται στο βήμα προσθήκης στο packages/shared/src/db/index.mjs.

Ένα URL postgres:// ακολουθεί ξεχωριστό κλάδο προσαρμογέα. Αυτός ο κλάδος απαιτεί το πακέτο pg, το οποίο δεν είναι δηλωμένη εξάρτηση, και η κεφαλίδα του schema.sql λέει να αντιμετωπίζεται η διαδρομή Postgres ως μη επαληθευμένη μέχρι να υπάρξει πραγματικός driver και δοκιμασμένη μετεγκατάσταση. Το SQLite είναι η διαδρομή που εκτελεί αυτό το αποθετήριο.

CLI Διαχειριστή

Το node scripts/db.mjs διαβάζει το DATABASE_URL και δεν χρειάζεται υπηρεσίες. Εντολές:

Εντολή Τι κάνει
node scripts/db.mjs migrateΕφαρμόζει το schema.sql και αναφέρει τον αριθμό των δηλώσεων.
node scripts/db.mjs seedΕισάγει ή ανανεώνει τον κατάλογο και τον οργανισμό επίδειξης, και γράφει το κλειδί επίδειξης στο data/demo-key.txt με mode 0600.
node scripts/db.mjs resetΜόνο για SQLite: αφαιρεί το αρχείο βάσης δεδομένων και τους συνοδούς του -wal και -shm, στη συνέχεια κάνει migrate και seed. Στο Postgres αρνείται.
node scripts/db.mjs statusΕκτυπώνει το engine, τον αριθμό των πινάκων και τον αριθμό των γραμμών κάθε μη κενού πίνακα.
node scripts/db.mjs demo-keyΕκδίδει ένα νέο κλειδί για τον οργανισμό επίδειξης και το εκτυπώνει μία φορά.
node scripts/db.mjs passwd <email>Ορίζει τον κωδικό πρόσβασης ενός χρήστη από τον διακομιστή και διαγράφει κάθε συνεδρία αυτού του χρήστη. Αυτή είναι η διαδρομή ανάκτησης όταν δεν έχει ρυθμιστεί μεταφορά αλληλογραφίας. Χωρίς --password δημιουργεί έναν και τον εκτυπώνει μία φορά.

Περιβάλλον

Ομαδοποιημένα όπως τα ομαδοποιεί το .env.example.

Ομάδα Μεταβλητές Σημειώσεις
URL και θύρεςAPP_URL, API_URL, WEB_PORT, API_PORT, API_EMBED, PUBLIC_API_URLΗ θύρα API προεπιλέγεται σε 8088, όχι 8080. Το API_EMBED=false είναι για ανάπτυξη που εκτελεί το API ως δική της διεργασία· το PUBLIC_API_URL είναι η βάση που εμφανίζεται σε αποσπάσματα τεκμηρίωσης.
Αποθήκη δεδομένωνDATABASE_URL, REDIS_URLΤο DATABASE_URL επιλέγει τον χώρο αποθήκευσης· το REDIS_URL προορίζεται για την ουρά εργασιών και δεν διαβάζεται από τη διαδρομή κώδικα v1.
ΣυμπερασματολογίαINFERENCE_MOCK, GPU_ENABLED, VLLM_BASE_URL, VLLM_REGION, VLLM_MODEL_VERSION, VLLM_BASE_URL_<REGION>, DEFAULT_REGION, PARTNER_*Δείτε την ενότητα συμπερασματολογίας παρακάτω· το PARTNER_* καλύπτει το βασικό URL συνεργάτη, την περιοχή, την κλάση κυριαρχίας και το κλειδί API.
ΧρέωσηFX_EUR_USDΤο καθολικό τηρείται σε μικρομονάδες USD και το EUR προκύπτει για εμφάνιση στο 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Ορίστε το MAIL_SMTP_HOST για SMTP, ή το MAIL_API_URL με το MAIL_FROM για HTTP relay, ή κανένα.
ΑσφάλειαNODE_ENV, LLMEU_IP_SALT, LLMEU_DEMO_PASSWORD, LLMEU_KEY_ENVΤο NODE_ENV=production επισημαίνει τα cookies συνεδρίας ως Secure. Το LLMEU_IP_SALT αλατίζει τη κατακερματισμένη IP πελάτη και πρέπει να αλλάζει ανά ανάπτυξη. Το LLMEU_KEY_ENV προθέτει στα παραγόμενα κλειδιά τα llmeu_live_ ή llmeu_test_.
ΔιάφοραLOG_LEVELΤο LOG_LEVEL ορίζει το ελάχιστο επίπεδο καταγραφής.

Docker

Το Compose και η εικόνα είναι προαιρετικά: η ίδια η σουίτα του αποθετηρίου δεν απαιτεί Docker, και η κύρια διαδρομή είναι μια τοπική διεργασία χωρίς υπηρεσίες.

  • Το προεπιλεγμένο προφίλ εκτελεί το web: θύρες 3000 και 8088, SQLite στον τόμο llmeu-data στο /app/data, το ενσωματωμένο API, και έναν έλεγχο υγείας στο /healthz.
  • Η ίδια εικόνα εκτελεί τον worker με node apps/worker/src/run.mjs, περιμένοντας το web να γίνει υγιές και μοιράζεται τον τόμο llmeu-data.
  • Δύο επιπλέον προφίλ είναι απενεργοποιημένα από προεπιλογή: postgres (postgres:16-alpine) και redis (redis:7-alpine, δεσμευμένο και δεν διαβάζεται από τη διαδρομή κώδικα v1).
  • Το προφίλ gpu εκτελεί το vllm/vllm-openai με δέσμευση συσκευής NVIDIA και προσαρτά τα βάρη μόνο για ανάγνωση από τον κεντρικό υπολογιστή; δεν είναι ενεργοποιημένο από προεπιλογή, επειδή ο ισχυρισμός για συμπερασμό στην ΕΕ χωρίς GPU θα ήταν ψευδής.
  • Το Dockerfile είναι FROM node:24-alpine με tini, χωρίς βήμα build και χωρίς εγκατάσταση εξαρτήσεων, εκτελείται ως χρήστης node, γράφει μόνο κάτω από το /app/data, εκθέτει τις θύρες 3000 και 8088, και ξεκινά το apps/web/server/main.mjs.

Αντίγραφα ασφαλείας

node scripts/backup.mjs χωρίς σημαίες γράφει ./backups/llmeu-<stamp>.db. Το SQLite αντιγράφεται με VACUUM INTO, ποτέ cp, επειδή μια ζωντανή βάση δεδομένων WAL που αντιγράφεται με cp μπορεί να αποφέρει μια σκισμένη ή παρωχημένη κατάσταση.

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

Κάθε αντίγραφο ασφαλείας SQLite επαληθεύεται πριν το script αναφέρει επιτυχία: επαναφέρεται σε ένα προσωρινό αντίγραφο, το PRAGMA integrity_check πρέπει να επιστρέψει ok, το σχήμα εφαρμόζεται εκ νέου, και εκτυπώνονται οι μετρήσεις γραμμών για μοντέλα, οργανισμούς και χρήστες.

Με ένα URL postgres:// το script χρησιμοποιεί pg_dump --format=custom και χρειάζεται το pg_dump στο PATH; ένα dump δεν μπορεί να ανοίξει ως βάση δεδομένων, οπότε οι μετρήσεις γραμμών του χρειάζονται μια προσωρινή επαναφορά.

Αλληλογραφία

Η συναλλακτική αλληλογραφία — επαναφορά κωδικού, επαλήθευση διεύθυνσης, προσκλήσεις — χρησιμοποιεί MAIL_SMTP_* ή MAIL_API_URL με MAIL_FROM. Το μέσο μεταφοράς επιλέγεται μία φορά κατά την εκκίνηση και αναφέρεται σε κάθε σελίδα που χρειάζεται αλληλογραφία.

Μια ανάπτυξη με κανένα από τα δύο είναι υποστηριζόμενη κατάσταση: εγγραφή, σύνδεση, αλλαγή κωδικού, ομάδες και προσκλήσεις λειτουργούν, αλλά επαναφορά κωδικού και αλληλογραφία επαλήθευσης δεν μπορούν να υποβληθούν εκεί. Οι σελίδες το λένε, και το node scripts/db.mjs passwd <email> είναι η διαδρομή ανάκτησης.

Backend συμπερασματολογίας

Μια γραμμή endpoint ονομάζει ένα runtime και μια περιοχή, και το μητρώο backend επιλέγει τον προσαρμογέα ανά περιοχή, επομένως ένα endpoint μπορεί να απαντηθεί μόνο από μηχάνημα στην περιοχή που ονομάζει.

  • Το INFERENCE_MOCK=true διατηρεί το ντετερμινιστικό backend ανάπτυξης, το οποίο δεν χρειάζεται GPU ούτε βάρη.
  • Το GPU_ENABLED=false κρατά έξω τα διαχειριζόμενα backend· με GPU_ENABLED=true, το VLLM_BASE_URL εφαρμόζεται στη μοναδική περιοχή που ονομάζεται από το VLLM_REGION.
  • Μια ανάπτυξη με πολλές περιοχές ορίζει μία μεταβλητή ανά περιοχή, με όνομα βάσει του slug περιοχής (για παράδειγμα VLLM_BASE_URL_DE_FRA). Ένα endpoint σε περιοχή χωρίς διαμορφωμένο backend απορρίπτεται, αντί να εξυπηρετηθεί από μηχάνημα σε άλλη περιοχή.
  • Τα backend συνεργατών προέρχονται από το PARTNER_BASE_URL_<REGION> και λαμβάνουν τα PARTNER_SOVEREIGNTY και PARTNER_API_KEY· ο διακομιστής επιτρέπει τη χρήση συνεργάτη όταν έχει οριστεί το PARTNER_BASE_URL.

Χωρίς διαμορφωμένη GPU, το ντετερμινιστικό backend ανάπτυξης απαντά και η έξοδός του λέει ότι δεν έτρεξαν πραγματικά βάρη και ότι η συμπερασματολογία πρώτου μέρους χρειάζεται το VLLM_BASE_URL και τη σημαία gpu_enabled. Μια υποκατάστατη επιτυχία που έμοιαζε πραγματική θα ήταν το ένα πράγμα που αυτό το προϊόν δεν πρέπει ποτέ να διαθέσει.