Salta al contenuto
openplate

L'app

Variabili d'ambiente

Tutte le variabili lette dall'app, dal server centrale e dal servizio di inferenza, con i rispettivi valori predefiniti, e le impostazioni che bloccano l'avvio

Questa pagina è tradotta automaticamente dalla documentazione in inglese.

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

  • Docker Compose. Inserisci la riga nel file .env accanto al file compose, ad esempio LOG_LEVEL=debug. Poi esegui di nuovo docker compose -f <your file> up -d. Ogni file compose fornito passa al container ciascuna variabile letta dal rispettivo servizio. docker compose restart non rilegge .env.
  • Quadlet. Inserisci la riga nel file <unit>.env accanto alla unit, ad esempio app.env, core.env o inference.env. Usa i nomi propri del container indicati in questa pagina. Poi riavvia la unit, ad esempio systemctl --user restart core.service. podman.md spiega i file.
  • Senza container. L'app e il server centrale leggono ciascuno un file .env nella cartella in cui sono in esecuzione. Puoi anche impostare la variabile nella shell o nell'unità systemd. Senza Docker mostra la configurazione dell'app.

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 .envCompila
PUBLIC_APP_URLil file APP_URL dell'app, e il file CLIENT_BASE_URL del server centrale
PUBLIC_SYNC_URLil file CORE_URL dell'app, e il file SERVER_PUBLIC_URL del server centrale
PUBLIC_INFERENCE_URLDEFAULT_INFERENCE_BASE_URL dell'app
INFERENCE_API_KEYDEFAULT_INFERENCE_API_KEY dell'app e API_KEYS del servizio di inferenza
POSTGRES_USER, POSTGRES_PASSWORD, SYNC_DB_NAMEil 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

VariabilePredefinitoCosa faAltro
NODE_ENVproduction nell'immagine, altrimenti developmentproduction distribuisce l'app compilata, rende APP_URL obbligatoria e imposta 1 come valore predefinito di TRUST_PROXY. L'immagine la imposta.
APP_URLhttp://localhost:3000, obbligatori in produzioneL'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
PORT3000La porta su cui il server è in ascolto.
HOSTnon impostato, tutte le interfacceL'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_PROXY1 in produzione, altrimenti disattivatoIl 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_EXTRAnon impostatoOrigini 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

VariabilePredefinitoCosa faAltro
DEFAULT_UI_LANGUAGEenLa 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_BASISdgeI valori di riferimento mostrati nella schermata Nutrienti: dge (DGE tedesca), efsa (UE) o us (NASEM). Qualsiasi altro valore blocca l'avvio.
CONTENT_DIRnon impostato, nessuna pagina legaleUna 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

VariabilePredefinitoCosa faAltro
CORE_URLnon impostato, sincronizzazione disattivataL'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_URLnon impostatoDeprecato. 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_MODEopenopen 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

VariabilePredefinitoCosa faAltro
DEFAULT_INFERENCE_BASE_URLnon impostatoUn 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_KEYnon impostatoLa chiave per questo endpoint. È pubblico: la riceve il browser di ogni visitatore.AI fornita dall'istanza
DEFAULT_INFERENCE_MODELopenplate-plate-1Il nome del modello inviato a questo endpoint.AI fornita dall'istanza

Database degli alimenti

VariabilePredefinitoCosa faAltro
FOOD_DB_API_URLhttps://lowcarbcheck.orgIl 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_KEYnon impostato, livello anonimoLa tua chiave LowCarbCheck. La legge solo il server e non raggiunge mai il browser.La chiave del database degli alimenti
FOOD_DB_BACKFILLfalsetrue 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_LIMIT3200Il 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

VariabilePredefinitoCosa faAltro
MATOMO_URLnon impostato, dati di utilizzo disattivatiUn'installazione di Matomo gestita da te. Impostala insieme a MATOMO_SITE_ID.Analisi
MATOMO_SITE_IDnon impostatoL'ID del sito su Matomo, un numero intero positivo. Impostalo insieme a MATOMO_URL.Analisi
MATOMO_EVENT_LEVELproductIl livello di tracciamento dell'istanza: pageviews, product o research. Richiede le due variabili precedenti.Cosa determina un livello
NEWSLETTER_SUBSCRIBE_URLnon impostato, nessun moduloL'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_KEYnon impostatoLa chiave del sito Cloudflare Turnstile di quel modulo. Non è il captcha di registrazione, vedi Registrazione con Turnstile.Iscrizione alla newsletter
UPDATE_CHECKattivoImpostando 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

VariabilePredefinitoCosa faAltro
LOG_LEVELinfoIl livello di dettaglio dei log del server, come livello pino: debug, info, warn o error.

Chiusura di un'istanza

VariabilePredefinitoCosa faAltro
MOVED_TO_URLnon impostatoChiude 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

VariabilePredefinitoCosa faAltro
NODE_ENVproduction nell'immagineSe 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
PORT3000La porta su cui ascolta il servizio.
HOSTnon impostato, tutte le interfacceL'indirizzo su cui ascolta il servizio. Non impostarlo in un container. 127.0.0.1 limita un'istanza di sviluppo alla propria macchina.
TRUST_PROXYfalseQuanti 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_URLnon impostatoL'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_URLnon impostatoL'indirizzo dell'app openplate, l'altra metà di quei link.La posta richiede gli indirizzi pubblici
INSTANCE_NAMEopenplateImposta 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_LANGUAGEenImposta 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_BASISdgeUna 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_DIRnon impostatoUna 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_DAY200Il 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_DAY10Lo stesso limite per una singola rete mittente, ovvero un indirizzo IPv4 o una /64 IPv6. Un riavvio azzera questo conteggio.Testi delle informative

Database

VariabilePredefinitoCosa faAltro
DATABASE_URLnessuno, obbligatoriLa stringa di connessione a Postgres. I file compose la generano automaticamente.
DATABASE_SSLfalseImposta su true se Postgres richiede TLS. Accetta true, false, 1 o 0.
MIGRATIONS_DIRdrizzle/migrationsIndica dove il servizio cerca le migrazioni del database all'avvio. L'immagine le conserva già lì, quindi lascialo non impostato.

Segreti

VariabilePredefinitoCosa faAltro
SERVER_SECRETnessuno, obbligatoriIl 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_TOKENnon impostatoLa 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

VariabilePredefinitoCosa faAltro
OPEN_SIGNUPnon impostato, solo invititrue 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_KEYnon impostato, nessun captchaLa 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_KEYnon impostatoLa 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

VariabilePredefinitoCosa faAltro
MEMBER_INVITE_DAILY_AI_LIMITnon impostato, i membri non possono invitareIl 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_DAYSnon impostatoIl numero di giorni dopo la registrazione durante i quali questa quota resta valida.Inviti dei membri
MEMBER_INVITE_LIFETIME_CAP5Il 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_TRIALfalsetrue 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_SCANSnon impostato, nessun periodo di provaLe 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_LIMITnon impostatoIl numero di richieste IA per giorno UTC durante il periodo di prova, da 1 a 10000.
TRIAL_DAYSnon impostato, nessuna data di fineIl 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_ZONEUTCIl 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_PEPPERnon impostatoIl 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_DAYS365I 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_LIMITnon impostato, nessun limiteL'importo totale che tutti gli account di prova possono spendere complessivamente per giorno UTC. Richiede il periodo di prova.
AI_TRIAL_NETWORK_DAILY_LIMITun decimo di AI_TRIAL_INSTANCE_DAILY_LIMIT, almeno 1La 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_LIMITnon impostato, disattivatoLe 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_CAPABILITIESnon impostato, nessun controlloCosa 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_MAPnon impostato, vuotoCoppie 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

VariabilePredefinitoCosa faAltro
SMTP_HOSTnon impostatoIl nome o l'indirizzo del server SMTP, senza schema, porta o percorso.SMTP
SMTP_PORT587465 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_USERnon impostatoIl nome utente SMTP. Impostalo insieme a SMTP_PASSWORD, oppure lasciali entrambi non impostati se il server non richiede autenticazione.SMTP
SMTP_PASSWORDnon impostatoLa password SMTP.SMTP
SMTP_FROMnon impostatoIl mittente, formattato come address o Name <address>. Obbligatorio per SMTP.SMTP
MAIL_API_URLnon impostatoUn'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_KEYnon impostatoLa chiave API per la posta, inviata come token Bearer.Un'API di posta HTTP
MAIL_API_FROMnon impostatoL'indirizzo del mittente per l'API di posta.Un'API di posta HTTP
MAIL_OPERATOR_EMAILnon impostatoIl tuo indirizzo. Riceve la tua copia di una cancellazione o di un recesso. Entrambi i metodi di trasporto lo richiedono.SMTP
NODE_EXTRA_CA_CERTSnon impostatoIl 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

VariabilePredefinitoCosa faAltro
UPSTREAM_BASE_URLnon impostato, nessuna IAL'indirizzo compatibile con OpenAI del provider, ad esempio https://openrouter.ai/api/v1. Impostalo insieme a UPSTREAM_API_KEY.Istanze gestite
UPSTREAM_API_KEYnon impostatoLa chiave del provider. Non raggiunge mai il browser.Istanze gestite
UPSTREAM_ZDRnon impostatoSolo 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_ONLYnon impostatoSolo 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_MS120000Il 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_FILEnon impostatoDa 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_MODELnon impostatoIl 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_TOKENS8192Il numero massimo di token di output che una richiesta può domandare.
AI_RATE_LIMIT_PER_MINUTE20Il numero massimo di richieste che un account può effettuare in un intervallo di 60 secondi.
AI_INSTANCE_DAILY_LIMITnon impostato, nessun limiteIl 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_FRACTION0.2Per 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_BYTES8000000La richiesta più grande accettata dal proxy, in byte.
AI_MAX_IMAGE_PARTS1Numero 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_BYTES49152Dimensione 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_MESSAGES4Numero massimo di messaggi per richiesta. Le richieste che superano questo limite restituiscono lo stesso 400.
AI_UNIT_INPUT_TOKENS8192Stima 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_TOKENS1500Stima dei token di input per una singola immagine. Il testo viene conteggiato dividendo i suoi byte complessivi per 4.
VariabilePredefinitoCosa faAltro
HEALTH_CONSENT_VERSIONnon impostato, nessun consenso richiestoLa 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

VariabilePredefinitoCosa faAltro
VAPID_PUBLIC_KEYnon impostato, nessuna notificaLa chiave pubblica per il web push. Impostale tutte e tre oppure nessuna. Genera una coppia con pnpm core-api push keygen.
VAPID_PRIVATE_KEYnon impostatoLa chiave privata per il web push.
VAPID_SUBJECTnon impostatoIl modo in cui un servizio push ti raggiunge: un indirizzo mailto: o un indirizzo https://.
PUSH_ENDPOINT_HOSTSnon impostatoHost 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

VariabilePredefinitoCosa faAltro
PLANS_UPSTREAM_URLnon impostato, nessun pianoL'indirizzo interno del servizio di fatturazione che riceve /v1/plans/*. Impostalo insieme a PLANS_UPSTREAM_SECRET.Piani a pagamento
PLANS_UPSTREAM_SECRETnon impostatoIl segreto condiviso verificato dal servizio di fatturazione.Piani a pagamento
BILLING_TOKENnon impostatoLa 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_LIMIT1000Limite 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

VariabilePredefinitoCosa faAltro
SYNC_FEEDBACKfalsetrue accetta le stime segnalate con le relative fotografie, conservate per 30 giorni. Puoi visualizzare queste fotografie.Stime segnalate
FEEDBACK_DAILY_LIMIT5Le segnalazioni che un account può inviare per giorno UTC.
FEEDBACK_MAX_REQUEST_BYTES8000000La segnalazione più grande accettata dal servizio, in byte.
SYNC_SHARINGfalsetrue attiva la condivisione di un diario con un medico.
SYNC_RESEARCHfalsetrue attiva i contributi alla ricerca e la console dello studio.Sincronizzazione

Registrazione e altro

VariabilePredefinitoCosa faAltro
LOG_LEVELinfodebug, info, warn oppure error. Qualsiasi altro valore blocca l'avvio.
SYNC_NOTICEnon impostatoUn breve messaggio mostrato da ogni app al momento della connessione, lungo al massimo 280 caratteri.
SYNC_NOTICE_URLnon impostatoUn collegamento accanto all'avviso, https:// o http://. Richiede SYNC_NOTICE.
SERVICE_VERSIONnon impostato, la versione dell'immagineSostituisce 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

VariabilePredefinitoCosa faAltro
PORT8300La porta su cui ascolta il servizio. È l'unica porta pubblicata dal container.
API_KEYSnon impostato, una chiave temporaneaLe 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_LEVELinfodebug, info, warn oppure error. Qualsiasi altro valore blocca l'avvio.
PROFILEimpostato da MODEL_PROFILEIl 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

VariabilePredefinitoCosa faAltro
MODEL_PROFILEliteI 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/modelsLa posizione dei pesi nel container, su un volume. Modificala solo se monti i pesi altrove.
WEIGHTS_MIRROR_BASEnon impostatoUn mirror da cui scaricare i pesi, con Hugging Face come riserva. Il servizio verifica comunque i checksum.
MODEL_RUNTIME_URLhttp://127.0.0.1:8080, il runtime integratoL'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_KEYnon impostatoUna chiave inviata dal servizio al tuo runtime, utile se il runtime o un proxy ne richiedono una.Variabili per la modalità esterna
MODEL_IDopenplate-plate-1Il nome del modello inviato dal servizio al runtime. vLLM richiede esattamente il nome con cui viene servito.Variabili per la modalità esterna
RUNTIME_PORT8080La porta del llama-server integrato, solo sull'indirizzo di loopback del container.
CONTEXT_SIZE8192Il contesto per ogni scansione in corso. Il container lo moltiplica per CONCURRENCY per llama.cpp.
LLAMA_THREADSil numero di core meno due, almeno 1I thread della CPU per llama.cpp.
LLAMA_EXTRA_ARGSnon impostatoOpzioni aggiuntive per la fine del comando llama-server, separate da spazi. Solo per il runtime integrato.
GPU_LAYERSrilevato: 99 con una GPU, altrimenti 0Quanti layer del modello assegnare alla GPU. 0 forza l'uso della CPU.
NVIDIA_VISIBLE_DEVICESimpostato dal container runtime di NVIDIALo imposta --gpus all. Qualsiasi valore diverso da void o none fa usare la GPU al container. Non devi impostarlo tu.

Limiti

VariabilePredefinitoCosa faAltro
CONCURRENCY2Le scansioni in corso contemporaneamente. Imposta anche gli slot di llama.cpp.
MAX_QUEUE_DEPTH8Le scansioni che possono rimanere in attesa. Oltre questo limite, il chiamante riceve un 429.
RATE_LIMIT_RPM60Le richieste al minuto per ciascuna chiave.
LATENCY_CEILING_MS0, disattivatoIl servizio rifiuta una scansione che non riesce a completare entro questo numero di millisecondi.Hardware
RUNTIME_COMPLETION_TIMEOUT_MS600000La durata massima consentita per una singola chiamata al runtime, in millisecondi. 0 disattiva il limite.
MAX_IMAGE_BYTES8388608La dimensione massima della foto accettata dal servizio dopo la decodifica, in byte (8 MiB).
IMAGE_MAX_LONG_EDGE896Il lato lungo a cui il servizio ridimensiona ciascuna foto, in pixel, almeno 112.

Dati sugli alimenti

VariabilePredefinitoCosa faAltro
FOOD_SOURCEfdcDa 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.jsonL'estratto USDA, relativo alla directory di lavoro.
OFF_API_URLhttps://world.openfoodfacts.orgL'indirizzo di Open Food Facts, letto con FOOD_SOURCE=off.
LCC_API_URLhttps://lowcarbcheck.orgL'indirizzo di LowCarbCheck, letto con FOOD_SOURCE=lcc.
LCC_API_KEYnon impostato, livello anonimoLa tua chiave di LowCarbCheck, letta con FOOD_SOURCE=lcc.
EMBEDDING_RUNTIME_URLnon impostatoUn runtime compatibile con OpenAI che serve /v1/embeddings, per abbinare meglio gli alimenti.
EMBEDDING_RUNTIME_API_KEYnon impostatoLa 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.

VariabileRifiutato daUsa invece
GATEWAY_URLl'appINSTANCE_MODE=managed. Il server centrale ha assunto la funzione di proxy IA.
SIGNUP_MODEil server centraleNiente. Gli account derivano dagli inviti, e OPEN_SIGNUP=true permette alle persone di richiederne uno.
SIGNUPS_OPENil server centraleNiente, per lo stesso motivo.
REQUIRE_EMAIL_VERIFICATIONil server centraleNiente. L'invito funge da verifica dell'indirizzo.
EMAIL_FROMil server centraleMAIL_API_FROM, oppure SMTP_FROM.
SMTP_SECUREil server centraleNiente. SMTP_PORT definisce la cifratura.
PIGEON_API_KEYil server centraleMAIL_API_KEY, oppure SMTP_USER e SMTP_PASSWORD.
PIGEON_BASE_URLil server centraleMAIL_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:

  1. Accedi alla dashboard di Cloudflare, apri Turnstile e scegli Add widget. Un account gratuito è sufficiente. Non è necessario che il tuo dominio usi Cloudflare.
  2. Assegna un nome al widget, aggiungi il nome host della tua app, come openplate.example.com, e mantieni la modalità Gestita. Scegli Crea.
  3. 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.
  4. 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.

Modifica questa pagina su GitHub