Αυτοφιλοξενία
Το 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. Μια υποκατάστατη επιτυχία που έμοιαζε πραγματική θα ήταν το ένα πράγμα που αυτό το προϊόν δεν πρέπει ποτέ να διαθέσει.