Ogni impostazione dei tre container openplate è una variabile d'ambiente. Questa pagina le elenca tutte, per l'app, per il server centrale (openplate-core) e per il servizio di inferenza. La maggior parte è facoltativa. Quando ne lasci una non impostata, si applica il valore predefinito nella sua riga.
Alcune impostazioni bloccano l'avvio di proposito. Un valore che il servizio non può usare, oppure una sola metà di una coppia, fa arrestare il container. Il messaggio di uscita indica il nome della variabile. Il container non si avvia tirando a indovinare. Impostazioni che bloccano l'avvio elenca ciascuna di queste regole.
Come impostare una variabile
La colonna Predefinito indica cosa fa il servizio quando la variabile non è impostata. Un file compose può passare un proprio valore, ad esempio MODEL_PROFILE: lite. Il file compose mostra quel valore accanto al nome.
Nomi compilati per te dai file compose
I tre file di topologia, compose.core.yml, compose.inference.yml e compose.full.yml, compilano alcune variabili del container a partire da nomi condivisi in .env. Imposta lì il nome condiviso. La variabile del container da sola non ha alcun effetto in questi file.
In .env | Compila |
|---|
PUBLIC_APP_URL | il file APP_URL dell'app, e il file CLIENT_BASE_URL del server centrale |
PUBLIC_SYNC_URL | il file CORE_URL dell'app, e il file SERVER_PUBLIC_URL del server centrale |
PUBLIC_INFERENCE_URL | DEFAULT_INFERENCE_BASE_URL dell'app |
INFERENCE_API_KEY | DEFAULT_INFERENCE_API_KEY dell'app e API_KEYS del servizio di inferenza |
POSTGRES_USER, POSTGRES_PASSWORD, SYNC_DB_NAME | il database, e il file DATABASE_URL del server centrale |
docker/compose.yml, l'app da sola, accetta APP_URL con il proprio nome. Il file di avvio rapido del server centrale è apps/core/docker/compose.yml. Accetta SERVER_PUBLIC_URL e CLIENT_BASE_URL con i propri nomi. Compone DATABASE_URL a partire da POSTGRES_USER, POSTGRES_PASSWORD e POSTGRES_DB.
L'app
Il container dell'app, ghcr.io/lowcarbcheck/openplate. Si avvia senza alcuna impostazione definita. configuration.md ne spiega le funzionalità più ampie in modo approfondito.
Server e indirizzi
| Variabile | Predefinito | Cosa fa | Altro |
|---|
NODE_ENV | production nell'immagine, altrimenti development | production distribuisce l'app compilata, rende APP_URL obbligatoria e imposta 1 come valore predefinito di TRUST_PROXY. L'immagine la imposta. | |
APP_URL | http://localhost:3000, obbligatori in produzione | L'indirizzo pubblico aperto dalle persone, ad esempio https://openplate.example.com. La pagina iniziale lo include nei suoi link di condivisione. Senza di esso il server non si avvia in produzione. | Caddy |
PORT | 3000 | La porta su cui il server è in ascolto. | |
HOST | non impostato, tutte le interfacce | L'indirizzo su cui ascolta il server. Non impostarlo all'interno di un container. Senza un container, 127.0.0.1 mantiene il server su questa macchina, utile per un proxy locale. | Senza Docker |
TRUST_PROXY | 1 in produzione, altrimenti disattivato | Il numero di reverse proxy davanti all'app: un numero, true, false oppure un preset Express o un intervallo di indirizzi come loopback o 10.0.0.0/8. Il controllo che blocca i post dei moduli cross-site richiede il valore corretto dietro un proxy. Usa 0 se non ci sono proxy. | L'applicazione da sola |
CSP_CONNECT_EXTRA | non impostato | Origini aggiuntive per la direttiva connect-src della Content-Security-Policy, separate da spazi. Serve se usi un tuo endpoint di IA su un altro host. | Endpoint AI personalizzati |
Lingua e contenuti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
DEFAULT_UI_LANGUAGE | en | La lingua mostrata prima di una scelta esplicita: en, de, fr, it, es o tr. La preferenza dell'utente ha sempre la precedenza. Qualsiasi altro valore blocca l'avvio. | |
NUTRIENT_REFERENCE_BASIS | dge | I valori di riferimento mostrati nella schermata Nutrienti: dge (DGE tedesca), efsa (UE) o us (NASEM). Qualsiasi altro valore blocca l'avvio. | |
CONTENT_DIR | non impostato, nessuna pagina legale | Una cartella di file markdown per le pagine legali, montata in sola lettura. Se il valore non indica una cartella, l'avvio si blocca. | Pagine di contenuto |
Sincronizzazione e tipo di istanza
| Variabile | Predefinito | Cosa fa | Altro |
|---|
CORE_URL | non impostato, sincronizzazione disattivata | L'indirizzo del tuo server centrale, così come lo raggiunge un browser. La sua origine entra nella Content-Security-Policy. Su un'istanza gestita anche il server dell'app lo raggiunge, per verificare l'account a ogni ricerca di alimenti. Un valore non valido blocca l'avvio. | Sincronizzazione |
SYNC_SERVER_URL | non impostato | Deprecato. Il vecchio nome di CORE_URL. Funziona ancora per un'altra versione, e all'avvio viene registrato un avviso quando è l'unico impostato. Se entrambi sono impostati su indirizzi diversi, il vecchio nome ha la precedenza per questa versione e l'avvio registra un avviso che menziona entrambi. Rimuovi la vecchia riga prima della versione che eliminerà il vecchio nome. | Sincronizzazione |
INSTANCE_MODE | open | open o managed. Su un'istanza gestita un amministratore invita le persone, e il server centrale fornisce l'IA. managed richiede CORE_URL. Qualsiasi altro valore blocca l'avvio. | Istanze gestite |
AI fornita dall'istanza
| Variabile | Predefinito | Cosa fa | Altro |
|---|
DEFAULT_INFERENCE_BASE_URL | non impostato | Un endpoint compatibile con OpenAI offerto da questa istanza a ogni visitatore, raggiungibile dal browser. Un valore non valido blocca l'avvio. | AI fornita dall'istanza |
DEFAULT_INFERENCE_API_KEY | non impostato | La chiave per questo endpoint. È pubblico: la riceve il browser di ogni visitatore. | AI fornita dall'istanza |
DEFAULT_INFERENCE_MODEL | openplate-plate-1 | Il nome del modello inviato a questo endpoint. | AI fornita dall'istanza |
Database degli alimenti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
FOOD_DB_API_URL | https://lowcarbcheck.org | Il database degli alimenti LowCarbCheck in cui il server cerca i nomi dei cibi. Lascia vuoto per disattivare la ricerca. | La chiave del database degli alimenti |
FOOD_DB_API_KEY | non impostato, livello anonimo | La tua chiave LowCarbCheck. La legge solo il server e non raggiunge mai il browser. | La chiave del database degli alimenti |
FOOD_DB_BACKFILL | false | true invia a LowCarbCheck come proposte gli alimenti salvati dalle risposte dell'IA. Richiede FOOD_DB_API_KEY e senza di esso resta disattivato. Qualsiasi valore diverso da true o false blocca l'avvio. | Proposte per il database degli alimenti |
FOOD_DB_DAILY_CALL_LIMIT | 3200 | Il numero massimo di chiamate a LowCarbCheck effettuate da questo server in un giorno UTC. Oltre questa soglia, le ricerche di alimenti si interrompono fino alla mezzanotte UTC e l'app lo segnala. Il valore predefinito rispetta le 100.000 mensili di una chiave gratuita. Qualsiasi valore diverso da un numero intero positivo blocca l'avvio. | La chiave del database degli alimenti |
Dati di utilizzo, newsletter e aggiornamenti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
MATOMO_URL | non impostato, dati di utilizzo disattivati | Un'installazione di Matomo gestita da te. Impostala insieme a MATOMO_SITE_ID. | Analisi |
MATOMO_SITE_ID | non impostato | L'ID del sito su Matomo, un numero intero positivo. Impostalo insieme a MATOMO_URL. | Analisi |
MATOMO_EVENT_LEVEL | product | Il livello di tracciamento dell'istanza: pageviews, product o research. Richiede le due variabili precedenti. | Cosa determina un livello |
NEWSLETTER_SUBSCRIBE_URL | non impostato, nessun modulo | L'indirizzo a cui il server inoltra il modulo della newsletter della pagina principale. Impostalo insieme a NEWSLETTER_TURNSTILE_SITE_KEY. | Iscrizione alla newsletter |
NEWSLETTER_TURNSTILE_SITE_KEY | non impostato | La chiave del sito Cloudflare Turnstile di quel modulo. Non è il captcha di registrazione, vedi Registrazione con Turnstile. | Iscrizione alla newsletter |
UPDATE_CHECK | attivo | Impostando questo valore su off o false, il server smette di scaricare openplate.de/latest.json per le nuove versioni. Interrompe anche il conteggio giornaliero delle richieste da parte del progetto. | Il controllo delle versioni |
Registrazione log
| Variabile | Predefinito | Cosa fa | Altro |
|---|
LOG_LEVEL | info | Il livello di dettaglio dei log del server, come livello pino: debug, info, warn o error. | |
Chiusura di un'istanza
| Variabile | Predefinito | Cosa fa | Altro |
|---|
MOVED_TO_URL | non impostato | Chiude questa istanza e indirizza gli utenti verso un'altra, ad esempio https://app.openplate.de. Ogni richiesta di pagina mostra una pagina che specifica il nuovo indirizzo, il service worker installato sui telefoni svuota le proprie cache e annulla la propria registrazione, e l'API restituisce 410. Il valore deve essere un indirizzo https:// su un host diverso da APP_URL; qualsiasi altra configurazione blocca l'avvio. | Spostare gli utenti su un'altra istanza |
Il server centrale (openplate-core)
Il container del server centrale, ghcr.io/lowcarbcheck/openplate-core. Richiede due valori: DATABASE_URL, che i file compose compilano per te, e SERVER_SECRET. Tutto il resto è facoltativo e disattivato finché non lo imposti. il README di openplate-core spiega le funzionalità.
Server e indirizzi
| Variabile | Predefinito | Cosa fa | Altro |
|---|
NODE_ENV | production nell'immagine | Se configuri la posta, production richiede che entrambi gli indirizzi dei link sottostanti siano indirizzi https:// su un altro host. | La posta richiede gli indirizzi pubblici |
PORT | 3000 | La porta su cui ascolta il servizio. | |
HOST | non impostato, tutte le interfacce | L'indirizzo su cui ascolta il servizio. Non impostarlo in un container. 127.0.0.1 limita un'istanza di sviluppo alla propria macchina. | |
TRUST_PROXY | false | Quanti reverse proxy si trovano davanti: un numero, true o false. Se usi un valore errato dietro a un proxy, ogni richiesta sembrerà provenire dal proxy stesso. Un solo utente può quindi esaurire la quota per tutti. | Tre impostazioni importanti |
SERVER_PUBLIC_URL | non impostato | L'indirizzo pubblico di questo servizio. Viene inserito nei link delle email di invito e di reimpostazione della password. Impostalo insieme a CLIENT_BASE_URL. | La posta richiede gli indirizzi pubblici |
CLIENT_BASE_URL | non impostato | L'indirizzo dell'app openplate, l'altra metà di quei link. | La posta richiede gli indirizzi pubblici |
INSTANCE_NAME | openplate | Imposta il nome dell'istanza per l'handshake /health (instance.name) e per il log di avvio. Le email non lo utilizzano. Massimo 64 caratteri. | |
INSTANCE_LANGUAGE | en | Imposta la lingua delle email quando una richiesta non ne specifica alcuna. I valori accettati sono en, de, fr, it, es o tr. Qualsiasi altro valore blocca l'avvio. | |
NUTRIENT_REFERENCE_BASIS | dge | Una nuova istanza viene avviata con uno di questi valori di riferimento: dge, efsa o us. L'amministratore può modificare l'impostazione attiva in seguito tramite l'API di amministrazione. Qualsiasi altro valore blocca l'avvio. | |
CONTENT_DIR | non impostato | Una cartella, montata in sola lettura, contenente il testo delle informative. L'app può leggere le sue pagine legali da questa cartella. Il servizio non la controlla mai all'avvio. | Testi delle informative |
LEGAL_DECLARATION_RECEIPTS_PER_DAY | 200 | Il numero massimo di ricevute di dichiarazione che l'istanza invia per email in un intervallo di 24 ore, considerando tutti gli indirizzi insieme. Superata questa soglia, la dichiarazione viene comunque registrata e inviata a te, ma la ricevuta non viene spedita. | Testi delle informative |
LEGAL_DECLARATION_RECEIPTS_PER_NETWORK_PER_DAY | 10 | Lo stesso limite per una singola rete mittente, ovvero un indirizzo IPv4 o una /64 IPv6. Un riavvio azzera questo conteggio. | Testi delle informative |
Database
| Variabile | Predefinito | Cosa fa | Altro |
|---|
DATABASE_URL | nessuno, obbligatori | La stringa di connessione a Postgres. I file compose la generano automaticamente. | |
DATABASE_SSL | false | Imposta su true se Postgres richiede TLS. Accetta true, false, 1 o 0. | |
MIGRATIONS_DIR | drizzle/migrations | Indica dove il servizio cerca le migrazioni del database all'avvio. L'immagine le conserva già lì, quindi lascialo non impostato. | |
Segreti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
SERVER_SECRET | nessuno, obbligatori | Il segreto root deve contenere almeno 32 caratteri. Liberalo con openssl rand -hex 32 e salvalo insieme al database. Se modifichi questo segreto, bloccherai l'accesso a tutti gli account in modo permanente. | Tre impostazioni importanti |
ADMIN_TOKEN | non impostato | La credenziale di amministrazione dell'operatore deve contenere almeno 24 caratteri. Ti serve per creare il primo account. Senza un token e senza un account amministratore, l'API di amministrazione restituisce 404. | Crea il primo account |
Account e registrazione
| Variabile | Predefinito | Cosa fa | Altro |
|---|
OPEN_SIGNUP | non impostato, solo inviti | true consente a chiunque di richiedere un account usando il proprio indirizzo. Questo richiede la posta. Il server accetta solo true. Qualsiasi altro valore, compreso false, blocca l'avvio. | Registrazione con Turnstile |
TURNSTILE_SECRET_KEY | non impostato, nessun captcha | La chiave segreta di Cloudflare Turnstile che verifica il captcha di registrazione. Impostala insieme a TURNSTILE_SITE_KEY, e solo con OPEN_SIGNUP=true. | Registrazione con Turnstile |
TURNSTILE_SITE_KEY | non impostato | La chiave pubblica del sito di Turnstile. /health la pubblica, e l'app la usa per mostrare il captcha. | Registrazione con Turnstile |
Inviti e periodi di prova
| Variabile | Predefinito | Cosa fa | Altro |
|---|
MEMBER_INVITE_DAILY_AI_LIMIT | non impostato, i membri non possono invitare | Il numero di richieste IA per giorno UTC assegnate a un account quando viene invitato da un membro, da 1 a 10000. Impostalo insieme a MEMBER_INVITE_ALLOWANCE_DAYS. | Inviti dei membri |
MEMBER_INVITE_ALLOWANCE_DAYS | non impostato | Il numero di giorni dopo la registrazione durante i quali questa quota resta valida. | Inviti dei membri |
MEMBER_INVITE_LIFETIME_CAP | 5 | Il totale degli inviti che un membro può inviare in assoluto: 0 o più. Richiede la coppia indicata sopra, oppure MEMBER_INVITE_TRIAL=true. | Inviti dei membri |
MEMBER_INVITE_TRIAL | false | true fa sì che l'invito di un membro assegni la prova di scansioni indicata sotto anziché la quota giornaliera. Richiede il periodo di prova e non può essere usato con la coppia indicata sopra. | |
TRIAL_SCANS | non impostato, nessun periodo di prova | Le scansioni IA gratuite ricevute da un nuovo account, da 1 a 100. Impostalo insieme a TRIAL_DAILY_AI_LIMIT, e imposta TRIAL_ADDRESS_PEPPER con essi. | |
TRIAL_DAILY_AI_LIMIT | non impostato | Il numero di richieste IA per giorno UTC durante il periodo di prova, da 1 a 10000. | |
TRIAL_DAYS | non impostato, nessuna data di fine | Il periodo di prova termina anche alla mezzanotte successiva a questo numero di giorni, da 1 a 90, a seconda di quale condizione si verifichi per prima. Richiede la coppia della prova. | |
TRIAL_TIME_ZONE | UTC | Il fuso orario di quella mezzanotte, espresso come nome IANA ad esempio Europe/Berlin. Richiede TRIAL_DAYS. Un fuso orario sconosciuto arresta l'avvio. | |
TRIAL_ADDRESS_PEPPER | non impostato | Il segreto che impone un solo periodo di prova per casella di posta. Deve contenere almeno 32 caratteri. Obbligatorio insieme alla coppia della prova. Se modifichi questo valore, il sistema dimentica quali caselle di posta hanno già usufruito di una prova. | |
TRIAL_HASH_RETENTION_DAYS | 365 | I giorni in cui viene conservato l'hash della casella di posta di un account eliminato, da 1 a 3650, a partire dall'eliminazione. Dopodiché una pulizia oraria lo elimina, e la stessa casella di posta può usufruire di nuovo di un periodo di prova. Un'istanza priva di prova di scansione non conserva alcun hash. | |
AI_TRIAL_INSTANCE_DAILY_LIMIT | non impostato, nessun limite | L'importo totale che tutti gli account di prova possono spendere complessivamente per giorno UTC. Richiede il periodo di prova. | |
AI_TRIAL_NETWORK_DAILY_LIMIT | un decimo di AI_TRIAL_INSTANCE_DAILY_LIMIT, almeno 1 | La quantità del limite di prova che le richieste di prova provenienti da una singola rete (una /64 IPv6, o un indirizzo IPv4) possono consumare per giorno UTC. Senza AI_TRIAL_INSTANCE_DAILY_LIMIT è disattivata, e non deve superare tale valore. Chi si trova dietro lo stesso NAT carrier IPv4 condivide questa quota. | |
DEFAULT_FREE_DAILY_AI_LIMIT | non impostato, disattivato | Le richieste AI per giorno UTC assegnate a ogni account privo di un proprio limite gratuito, da 0 a 10000. Non scade mai e non prevede un conteggio delle scansioni. Esaurita la disponibilità giornaliera, risponde 429 con Retry-After. Sostituisce la prova di scansione, quindi se lo imposti insieme alla coppia di parametri della prova l'avvio si blocca. Un account che ha ancora a disposizione una prova rientra in questo limite. | |
DEFAULT_CAPABILITIES | non impostato, nessun controllo | Cosa può usare un account privo di un proprio elenco di capability: etichette separate da virgola come scan,recipes, oppure none per nessuna. Non impostato o vuoto significa che il proxy AI non controlla alcuna funzionalità e ogni richiesta passa. Una richiesta per una funzionalità che l'account non possiede riceve 403 capability-required. | |
CAPABILITY_SCHEMA_MAP | non impostato, vuoto | Coppie schemaName:label separate da virgola. Una richiesta che richiede lo schema di output strutturato che elenchi necessita di quell'etichetta, a prescindere da quanto indica la sua intestazione X-Openplate-Feature. | |
Posta
| Variabile | Predefinito | Cosa fa | Altro |
|---|
SMTP_HOST | non impostato | Il nome o l'indirizzo del server SMTP, senza schema, porta o percorso. | SMTP |
SMTP_PORT | 587 | 465 usa TLS fin dal primo byte. Ogni altra porta deve effettuare l'aggiornamento con STARTTLS, tranne un mail catcher presente su questa macchina. | SMTP |
SMTP_USER | non impostato | Il nome utente SMTP. Impostalo insieme a SMTP_PASSWORD, oppure lasciali entrambi non impostati se il server non richiede autenticazione. | SMTP |
SMTP_PASSWORD | non impostato | La password SMTP. | SMTP |
SMTP_FROM | non impostato | Il mittente, formattato come address o Name <address>. Obbligatorio per SMTP. | SMTP |
MAIL_API_URL | non impostato | Un'API di posta HTTP compatibile con Resend. Impostala insieme a MAIL_API_KEY, MAIL_API_FROM e MAIL_OPERATOR_EMAIL. | Un'API di posta HTTP |
MAIL_API_KEY | non impostato | La chiave API per la posta, inviata come token Bearer. | Un'API di posta HTTP |
MAIL_API_FROM | non impostato | L'indirizzo del mittente per l'API di posta. | Un'API di posta HTTP |
MAIL_OPERATOR_EMAIL | non impostato | Il tuo indirizzo. Riceve la tua copia di una cancellazione o di un recesso. Entrambi i metodi di trasporto lo richiedono. | SMTP |
NODE_EXTRA_CA_CERTS | non impostato | Il percorso all'interno del container verso un file PEM contenente autorità di certificazione aggiuntive. Node.js lo legge all'avvio. Monta il file se usi un relay di posta il cui certificato è firmato da un'autorità privata. | Un relay con un'autorità di certificazione privata |
Proxy IA e limiti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
UPSTREAM_BASE_URL | non impostato, nessuna IA | L'indirizzo compatibile con OpenAI del provider, ad esempio https://openrouter.ai/api/v1. Impostalo insieme a UPSTREAM_API_KEY. | Istanze gestite |
UPSTREAM_API_KEY | non impostato | La chiave del provider. Non raggiunge mai il browser. | Istanze gestite |
UPSTREAM_ZDR | non impostato | Solo OpenRouter. Impostalo su true e il proxy chiederà a OpenRouter di instradare una richiesta solo verso endpoint a conservazione dati zero. Qualsiasi altro host lo ignora. Un valore diverso da true, false o vuoto blocca l'avvio. | Il proxy AI |
UPSTREAM_PROVIDER_ONLY | non impostato | Solo OpenRouter. Un elenco separato da virgola di slug di provider, per esempio google-vertex. Una richiesta viene inviata a uno di essi oppure fallisce, senza mai ripiegare su un altro provider. Qualsiasi altro host lo ignora. | Il proxy AI |
UPSTREAM_TIMEOUT_MS | 120000 | Il tempo in millisecondi che il proxy attende per la prima risposta del provider, e poi tra una parte e l'altra della risposta. | |
AI_TIERS_FILE | non impostato | Da dove proviene il modello per ciascun tipo di richiesta. Se non impostato, il modello è AI_ADVERTISED_MODEL, con l'instradamento da UPSTREAM_ZDR e UPSTREAM_PROVIDER_ONLY, esattamente come prima dell'esistenza del file. bundled usa il file presente nell'immagine del core, ai-tiers.json, che raccoglie il modello, il suo instradamento e il suo prezzo. Un percorso assoluto usa un file montato da te. Un valore non valido o un file non corretto blocca l'avvio. | Il proxy AI |
AI_ADVERTISED_MODEL | non impostato | Il modello utilizzato da ogni scansione quando non è presente un file dei livelli. /health ne specifica il nome e il proxy lo inserisce in ogni richiesta. L'app non esegue scansioni senza un modello. Con un file dei livelli funge solo da override per il modello del livello predefinito, come misura di emergenza, e il core registra un avviso a ogni avvio. | Istanze gestite |
AI_MAX_OUTPUT_TOKENS | 8192 | Il numero massimo di token di output che una richiesta può domandare. | |
AI_RATE_LIMIT_PER_MINUTE | 20 | Il numero massimo di richieste che un account può effettuare in un intervallo di 60 secondi. | |
AI_INSTANCE_DAILY_LIMIT | non impostato, nessun limite | Il limite giornaliero dell'istanza in unità IA per giorno UTC. Una scansione della foto del piatto costa un'unità. | Il proxy AI |
AI_BUDGET_ALERT_FRACTION | 0.2 | Per una chiave OpenRouter, invia un'email a MAIL_OPERATOR_EMAIL una volta per ciclo di azzeramento quando rimane meno di questa quota rispetto al limite della chiave. Superiore a 0 e inferiore a 1. | Il proxy AI |
AI_MAX_REQUEST_BYTES | 8000000 | La richiesta più grande accettata dal proxy, in byte. | |
AI_MAX_IMAGE_PARTS | 1 | Numero massimo di immagini per richiesta. Le richieste che superano questo limite restituiscono 400 ai-request-too-large prima ancora di iniziare il conteggio. | |
AI_MAX_TEXT_BYTES | 49152 | Dimensione massima in byte del testo per richiesta, sommando il testo del messaggio e response_format. Le richieste che la superano restituiscono lo stesso 400. | |
AI_MAX_MESSAGES | 4 | Numero massimo di messaggi per richiesta. Le richieste che superano questo limite restituiscono lo stesso 400. | |
AI_UNIT_INPUT_TOKENS | 8192 | Stima dei token di input per unità IA. Ogni richiesta costa un'unità, più un'unità per ogni AI_UNIT_INPUT_TOKENS aggiuntivo. I limiti giornalieri conteggiano queste unità. | Il proxy AI |
AI_IMAGE_INPUT_TOKENS | 1500 | Stima dei token di input per una singola immagine. Il testo viene conteggiato dividendo i suoi byte complessivi per 4. | |
Consenso
| Variabile | Predefinito | Cosa fa | Altro |
|---|
HEALTH_CONSENT_VERSION | non impostato, nessun consenso richiesto | La versione del consenso per i dati sanitari che ogni account deve accettare, come 2026-09-28. Usa da 1 a 32 lettere, cifre, ., _ o -. Se modifichi la versione, viene richiesto di nuovo a tutti. | Consenso esplicito |
Push
| Variabile | Predefinito | Cosa fa | Altro |
|---|
VAPID_PUBLIC_KEY | non impostato, nessuna notifica | La chiave pubblica per il web push. Impostale tutte e tre oppure nessuna. Genera una coppia con pnpm core-api push keygen. | |
VAPID_PRIVATE_KEY | non impostato | La chiave privata per il web push. | |
VAPID_SUBJECT | non impostato | Il modo in cui un servizio push ti raggiunge: un indirizzo mailto: o un indirizzo https://. | |
PUSH_ENDPOINT_HOSTS | non impostato | Host di push aggiuntivi, separati da virgole, che un dispositivo può registrare. *.example.org include ogni host sotto example.org. I servizi di push predefiniti dei browser sono sempre consentiti. Impostalo solo per host personalizzati. Una voce non valida blocca l'avvio. | |
Piani
| Variabile | Predefinito | Cosa fa | Altro |
|---|
PLANS_UPSTREAM_URL | non impostato, nessun piano | L'indirizzo interno del servizio di fatturazione che riceve /v1/plans/*. Impostalo insieme a PLANS_UPSTREAM_SECRET. | Piani a pagamento |
PLANS_UPSTREAM_SECRET | non impostato | Il segreto condiviso verificato dal servizio di fatturazione. | Piani a pagamento |
BILLING_TOKEN | non impostato | La credenziale specifica del servizio di fatturazione, di almeno 24 caratteri. Raggiunge tre route di amministrazione e nient'altro. | Piani a pagamento |
BILLING_MAX_DAILY_AI_LIMIT | 1000 | Limite massimo giornaliero di IA che BILLING_TOKEN può impostare per un account. Mantieni questo valore uguale o superiore al piano più alto. ADMIN_TOKEN non è vincolato da questa soglia. | Piani a pagamento |
Feedback, condivisione e ricerca
| Variabile | Predefinito | Cosa fa | Altro |
|---|
SYNC_FEEDBACK | false | true accetta le stime segnalate con le relative fotografie, conservate per 30 giorni. Puoi visualizzare queste fotografie. | Stime segnalate |
FEEDBACK_DAILY_LIMIT | 5 | Le segnalazioni che un account può inviare per giorno UTC. | |
FEEDBACK_MAX_REQUEST_BYTES | 8000000 | La segnalazione più grande accettata dal servizio, in byte. | |
SYNC_SHARING | false | true attiva la condivisione di un diario con un medico. | |
SYNC_RESEARCH | false | true attiva i contributi alla ricerca e la console dello studio. | Sincronizzazione |
Registrazione e altro
| Variabile | Predefinito | Cosa fa | Altro |
|---|
LOG_LEVEL | info | debug, info, warn oppure error. Qualsiasi altro valore blocca l'avvio. | |
SYNC_NOTICE | non impostato | Un breve messaggio mostrato da ogni app al momento della connessione, lungo al massimo 280 caratteri. | |
SYNC_NOTICE_URL | non impostato | Un collegamento accanto all'avviso, https:// o http://. Richiede SYNC_NOTICE. | |
SERVICE_VERSION | non impostato, la versione dell'immagine | Sostituisce la versione segnalata da /health. Lascialo non impostato. | |
Il servizio di inferenza (openplate-inference)
Il container di inferenza, ghcr.io/lowcarbcheck/openplate-inference. Esegue il runtime del modello e il servizio in un unico container. Guida alla configurazione di openplate-inference illustra le opzioni in dettaglio.
Servizio e accesso
| Variabile | Predefinito | Cosa fa | Altro |
|---|
PORT | 8300 | La porta su cui ascolta il servizio. È l'unica porta pubblicata dal container. | |
API_KEYS | non impostato, una chiave temporanea | Le chiavi che un chiamante deve inviare, separate da virgole. Se non è impostato, il servizio crea una chiave all'avvio, la stampa una sola volta e la dimentica al riavvio successivo. | Recupera la chiave |
LOG_LEVEL | info | debug, info, warn oppure error. Qualsiasi altro valore blocca l'avvio. | |
PROFILE | impostato da MODEL_PROFILE | Il nome del profilo stampato nel registro di avvio: lite, quality o custom. Il container lo imposta da MODEL_PROFILE e non modifica nient'altro. | |
Modello e pesi
| Variabile | Predefinito | Cosa fa | Altro |
|---|
MODEL_PROFILE | lite | I pesi scaricati ed eseguiti dal container: lite, lite-apache o quality. external non scarica nulla e usa il tuo runtime personale su MODEL_RUNTIME_URL. | Hardware |
MODELS_DIR | /models | La posizione dei pesi nel container, su un volume. Modificala solo se monti i pesi altrove. | |
WEIGHTS_MIRROR_BASE | non impostato | Un mirror da cui scaricare i pesi, con Hugging Face come riserva. Il servizio verifica comunque i checksum. | |
MODEL_RUNTIME_URL | http://127.0.0.1:8080, il runtime integrato | L'indirizzo del tuo runtime personale, senza /v1. MODEL_PROFILE=external lo richiede. Con qualsiasi altro profilo, un indirizzo diverso arresta il container. | Variabili per la modalità esterna |
MODEL_RUNTIME_API_KEY | non impostato | Una chiave inviata dal servizio al tuo runtime, utile se il runtime o un proxy ne richiedono una. | Variabili per la modalità esterna |
MODEL_ID | openplate-plate-1 | Il nome del modello inviato dal servizio al runtime. vLLM richiede esattamente il nome con cui viene servito. | Variabili per la modalità esterna |
RUNTIME_PORT | 8080 | La porta del llama-server integrato, solo sull'indirizzo di loopback del container. | |
CONTEXT_SIZE | 8192 | Il contesto per ogni scansione in corso. Il container lo moltiplica per CONCURRENCY per llama.cpp. | |
LLAMA_THREADS | il numero di core meno due, almeno 1 | I thread della CPU per llama.cpp. | |
LLAMA_EXTRA_ARGS | non impostato | Opzioni aggiuntive per la fine del comando llama-server, separate da spazi. Solo per il runtime integrato. | |
GPU_LAYERS | rilevato: 99 con una GPU, altrimenti 0 | Quanti layer del modello assegnare alla GPU. 0 forza l'uso della CPU. | |
NVIDIA_VISIBLE_DEVICES | impostato dal container runtime di NVIDIA | Lo imposta --gpus all. Qualsiasi valore diverso da void o none fa usare la GPU al container. Non devi impostarlo tu. | |
Limiti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
CONCURRENCY | 2 | Le scansioni in corso contemporaneamente. Imposta anche gli slot di llama.cpp. | |
MAX_QUEUE_DEPTH | 8 | Le scansioni che possono rimanere in attesa. Oltre questo limite, il chiamante riceve un 429. | |
RATE_LIMIT_RPM | 60 | Le richieste al minuto per ciascuna chiave. | |
LATENCY_CEILING_MS | 0, disattivato | Il servizio rifiuta una scansione che non riesce a completare entro questo numero di millisecondi. | Hardware |
RUNTIME_COMPLETION_TIMEOUT_MS | 600000 | La durata massima consentita per una singola chiamata al runtime, in millisecondi. 0 disattiva il limite. | |
MAX_IMAGE_BYTES | 8388608 | La dimensione massima della foto accettata dal servizio dopo la decodifica, in byte (8 MiB). | |
IMAGE_MAX_LONG_EDGE | 896 | Il lato lungo a cui il servizio ridimensiona ciascuna foto, in pixel, almeno 112. | |
Dati sugli alimenti
| Variabile | Predefinito | Cosa fa | Altro |
|---|
FOOD_SOURCE | fdc | Da dove provengono i macronutrienti: fdc (l'estratto USDA nell'immagine, senza rete), off (Open Food Facts), lcc (LowCarbCheck) o none. | Dati sugli alimenti |
FDC_DATASET_PATH | ./data/fdc-foods.json | L'estratto USDA, relativo alla directory di lavoro. | |
OFF_API_URL | https://world.openfoodfacts.org | L'indirizzo di Open Food Facts, letto con FOOD_SOURCE=off. | |
LCC_API_URL | https://lowcarbcheck.org | L'indirizzo di LowCarbCheck, letto con FOOD_SOURCE=lcc. | |
LCC_API_KEY | non impostato, livello anonimo | La tua chiave di LowCarbCheck, letta con FOOD_SOURCE=lcc. | |
EMBEDDING_RUNTIME_URL | non impostato | Un runtime compatibile con OpenAI che serve /v1/embeddings, per abbinare meglio gli alimenti. | |
EMBEDDING_RUNTIME_API_KEY | non impostato | La chiave per quel runtime. | |
Impostazioni che bloccano l'avvio
Un container che non si avvia si nota subito, e costa solo un riavvio. Un'impostazione ignorata in silenzio ti fa credere che qualcosa funzioni quando invece non è così. Quindi ciascuna regola qui sotto blocca l'avvio, e il registro indica il nome della variabile.
Nomi rifiutati
Questi nomi un tempo erano impostazioni. Ora il servizio rifiuta di avviarsi se uno di essi è impostato, e indica cosa usare al suo posto. Il server centrale li rifiuta anche con un valore vuoto, quindi elimina la riga. L'app rifiuta GATEWAY_URL solo quando contiene un valore.
| Variabile | Rifiutato da | Usa invece |
|---|
GATEWAY_URL | l'app | INSTANCE_MODE=managed. Il server centrale ha assunto la funzione di proxy IA. |
SIGNUP_MODE | il server centrale | Niente. Gli account derivano dagli inviti, e OPEN_SIGNUP=true permette alle persone di richiederne uno. |
SIGNUPS_OPEN | il server centrale | Niente, per lo stesso motivo. |
REQUIRE_EMAIL_VERIFICATION | il server centrale | Niente. L'invito funge da verifica dell'indirizzo. |
EMAIL_FROM | il server centrale | MAIL_API_FROM, oppure SMTP_FROM. |
SMTP_SECURE | il server centrale | Niente. SMTP_PORT definisce la cifratura. |
PIGEON_API_KEY | il server centrale | MAIL_API_KEY, oppure SMTP_USER e SMTP_PASSWORD. |
PIGEON_BASE_URL | il server centrale | MAIL_API_URL, oppure SMTP_HOST. |
Regole tra variabili
L'app.
MATOMO_URL e MATOMO_SITE_ID: impostali entrambi o nessuno dei due. MATOMO_EVENT_LEVEL richiede entrambi.
NEWSLETTER_SUBSCRIBE_URL e NEWSLETTER_TURNSTILE_SITE_KEY: impostali entrambi o nessuno dei due.
INSTANCE_MODE=managed richiede CORE_URL.
CORE_URL e il valore deprecato SYNC_SERVER_URL: impostane uno. Se entrambi sono impostati su indirizzi diversi, SYNC_SERVER_URL ha la precedenza per questa versione e l'avvio registra un avviso.
APP_URL è obbligatorio quando NODE_ENV=production.
MOVED_TO_URL deve essere un indirizzo https:// su un host diverso da APP_URL, privo di nome utente o password.
Un valore non compreso nell'elenco blocca l'avvio: DEFAULT_UI_LANGUAGE, NUTRIENT_REFERENCE_BASIS, INSTANCE_MODE, MATOMO_EVENT_LEVEL e FOOD_DB_BACKFILL. Lo stesso accade se FOOD_DB_DAILY_CALL_LIMIT non è un numero intero positivo. Anche indirizzi non validi in CORE_URL, DEFAULT_INFERENCE_BASE_URL, MATOMO_URL o NEWSLETTER_SUBSCRIBE_URL bloccano l'avvio. L'avvio si blocca inoltre se MATOMO_SITE_ID non è un numero intero positivo o se CONTENT_DIR non è una cartella.
Il server centrale.
DATABASE_URL e SERVER_SECRET sono obbligatori.
Lunghezze minime: 32 caratteri per SERVER_SECRET e TRIAL_ADDRESS_PEPPER, 24 per ADMIN_TOKEN e BILLING_TOKEN.
L'invio delle email usa un solo trasporto. L'API email via HTTP richiede MAIL_API_URL, MAIL_API_KEY, MAIL_API_FROM e MAIL_OPERATOR_EMAIL, tutti e quattro. SMTP richiede SMTP_HOST, SMTP_FROM e MAIL_OPERATOR_EMAIL, mentre SMTP_USER e SMTP_PASSWORD vanno insieme. Le variabili di entrambi i trasporti impostate contemporaneamente bloccano l'avvio, e lo stesso fa MAIL_OPERATOR_EMAIL in assenza di un trasporto.
La posta richiede SERVER_PUBLIC_URL e CLIENT_BASE_URL. Con NODE_ENV=production, entrambi devono essere indirizzi https:// su un altro host, non localhost.
Impostali entrambi o nessuno dei due: UPSTREAM_BASE_URL e UPSTREAM_API_KEY; PLANS_UPSTREAM_URL e PLANS_UPSTREAM_SECRET; TURNSTILE_SECRET_KEY e TURNSTILE_SITE_KEY; MEMBER_INVITE_DAILY_AI_LIMIT e MEMBER_INVITE_ALLOWANCE_DAYS; TRIAL_SCANS e TRIAL_DAILY_AI_LIMIT.
Impostali tutti e tre o nessuno: VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY e VAPID_SUBJECT.
X richiede Y: OPEN_SIGNUP=true richiede la posta. La coppia Turnstile richiede OPEN_SIGNUP=true. MEMBER_INVITE_LIFETIME_CAP richiede la coppia per l'invito dei membri oppure MEMBER_INVITE_TRIAL=true. MEMBER_INVITE_TRIAL=true richiede la coppia di prova e rifiuta la coppia per l'invito dei membri. La coppia di prova richiede TRIAL_ADDRESS_PEPPER. TRIAL_DAYS e AI_TRIAL_INSTANCE_DAILY_LIMIT richiedono la coppia di prova. AI_TRIAL_NETWORK_DAILY_LIMIT richiede AI_TRIAL_INSTANCE_DAILY_LIMIT. TRIAL_TIME_ZONE richiede TRIAL_DAYS. SYNC_NOTICE_URL richiede SYNC_NOTICE.
Lo zero viene rifiutato dove verrebbe interpretato come "disattivato" ma significherebbe l'opposto: AI_INSTANCE_DAILY_LIMIT, AI_TRIAL_INSTANCE_DAILY_LIMIT, AI_TRIAL_NETWORK_DAILY_LIMIT, TRIAL_SCANS, TRIAL_DAILY_AI_LIMIT, TRIAL_DAYS, MEMBER_INVITE_DAILY_AI_LIMIT e MEMBER_INVITE_ALLOWANCE_DAYS. Anche ogni altro numero deve essere positivo, tranne due che accettano 0: TRUST_PROXY, e MEMBER_INVITE_LIFETIME_CAP, dove 0 non lascia nulla da inviare ai membri.
Limiti superiori: TRIAL_SCANS 100, TRIAL_DAYS 90, TRIAL_DAILY_AI_LIMIT e MEMBER_INVITE_DAILY_AI_LIMIT 10000, SYNC_NOTICE 280 caratteri, INSTANCE_NAME 64 caratteri.
SYNC_SHARING, SYNC_RESEARCH, SYNC_FEEDBACK, DATABASE_SSL e MEMBER_INVITE_TRIAL accettano true, false, 1 o 0. OPEN_SIGNUP accetta solo true.
Un valore non compreso nell'elenco blocca l'avvio: INSTANCE_LANGUAGE, NUTRIENT_REFERENCE_BASIS, LOG_LEVEL, TRIAL_TIME_ZONE e HEALTH_CONSENT_VERSION. Un valore di VAPID_SUBJECT diverso da mailto: o https: blocca l'avvio. Lo stesso vale per un valore di SMTP_HOST con schema, porta o percorso. Anche indirizzi non validi in SERVER_PUBLIC_URL, CLIENT_BASE_URL, UPSTREAM_BASE_URL, PLANS_UPSTREAM_URL o SYNC_NOTICE_URL bloccano l'avvio.
Il servizio di inferenza.
MODEL_PROFILE=external richiede MODEL_RUNTIME_URL. Con qualsiasi altro profilo, un valore di MODEL_RUNTIME_URL diverso dall'indirizzo incluso blocca il container.
Un valore di MODEL_PROFILE, FOOD_SOURCE, PROFILE o LOG_LEVEL non compreso nell'elenco blocca l'avvio. Anche un valore di MODEL_RUNTIME_URL o EMBEDDING_RUNTIME_URL che non sia un indirizzo http:// o https:// blocca l'avvio.
I conteggi e le dimensioni devono essere numeri interi positivi. LATENCY_CEILING_MS e RUNTIME_COMPLETION_TIMEOUT_MS accettano anche 0. IMAGE_MAX_LONG_EDGE deve essere almeno 112, e PORT al massimo 65535.
Registrazione con Turnstile
Per impostazione predefinita un account proviene solo da un invito. Imposta OPEN_SIGNUP=true sul server centrale, e chiunque potrà richiedere un account con il proprio indirizzo. Il servizio invia quindi un invito via email a quell'indirizzo, e il messaggio dimostra che l'indirizzo è valido. La registrazione aperta richiede quindi la posta, e il servizio non si avvia senza di essa. L'app mostra il modulo di registrazione solo quando il server centrale indica che l'accesso è aperto.
Un captcha impedisce agli script di inondare il servizio di richieste. Il server centrale verifica un captcha Cloudflare Turnstile quando configuri due chiavi:
- 01
Accedi alla dashboard di Cloudflare, apri Turnstile e scegli Add widget. Un account gratuito è sufficiente. Non è necessario che il tuo dominio usi Cloudflare.
- 02
Assegna un nome al widget, aggiungi il nome host della tua app, come openplate.example.com, e mantieni la modalità Gestita. Scegli Crea.
- 03
Imposta la chiave del sito in TURNSTILE_SITE_KEY e la chiave segreta in TURNSTILE_SECRET_KEY sul server centrale. Imposta entrambe le chiavi oppure nessuna.
- 04
Ricrea il server centrale, per esempio con docker compose -f <your file> up -d.
/health pubblica quindi la chiave del sito. La pagina di registrazione dell'app mostra il captcha. Il pulsante di invio rimane inattivo finché l'utente non lo risolve. La chiave segreta non lascia mai il server centrale. Il servizio invia a Cloudflare la risposta del captcha e la chiave segreta, non l'indirizzo del visitatore.
Il servizio controlla solo la richiesta di registrazione, POST /v1/auth/signup-request. L'accesso, l'apertura di un invito e tutte le altre route non prevedono captcha. Quando il servizio non riesce a raggiungere Cloudflare, restituisce 503, e la persona può riprovare più tardi. Il controllo fallisce bloccando l'accesso, quindi una richiesta senza risposta non passa mai.
La Content-Security-Policy dell'app consente il captcha di Cloudflare solo su un'istanza gestita (INSTANCE_MODE=managed), oppure quando il modulo della newsletter è attivo. Sulle altre istanze, il browser blocca il captcha e nessuno può inviare il modulo. Imposta l'app come gestita prima di attivare il captcha.
Senza le due chiavi, la registrazione aperta funziona comunque. Gli altri suoi limiti restano validi. Il servizio consente cinque richieste all'ora da un singolo indirizzo, e una lettera al giorno per una casella di posta. Blocca gli indirizzi dei servizi di posta usa e getta noti. All'avvio, il servizio registra un avviso nei log.
NEWSLETTER_TURNSTILE_SITE_KEY è un'impostazione separata. Appartiene all'app e protegge il modulo della newsletter sulla pagina di destinazione. La sua secret key resta nel servizio che riceve quel modulo, non in openplate. Iscrizione alla newsletter ne spiega i dettagli.
Compilare un'immagine in autonomia
I Dockerfile accettano diversi argomenti di build. Non sono impostazioni per un container in esecuzione. OPENPLATE_BUILD_SHA inserisce l'impronta del commit nel bundle dell'app. L'immagine di inferenza accetta BASE_IMAGE, l'immagine del server llama.cpp su cui basare la build. Accetta anche NODE_IMAGE, l'immagine Node.js per la build. VITE_ALLOWED_HOSTS si applica solo al server di sviluppo dell'app e non ha host predefiniti.