Chaque réglage des trois conteneurs openplate est une variable d'environnement. Cette page les liste tous, pour l'application, le serveur central (openplate-core) et le service d'inférence. La plupart sont facultatifs. Quand tu en laisses un non défini, la valeur par défaut de sa ligne s'applique.
Certains paramètres bloquent volontairement le démarrage. Une valeur que le service ne peut pas utiliser, ou une seule valeur sur une paire requise, provoque l'arrêt du conteneur. Le message d'arrêt indique la variable en cause. Le conteneur ne démarre pas avec une valeur devinée. Paramètres qui bloquent le démarrage détaille chacune de ces règles.
Comment définir une variable
La colonne Par défaut indique ce que fait le service quand la variable n'est pas définie. Un fichier compose peut transmettre sa propre valeur, par exemple MODEL_PROFILE: lite. Le fichier compose affiche cette valeur à côté du nom.
Noms renseignés par les fichiers compose
Les trois fichiers de topologie, compose.core.yml, compose.inference.yml et compose.full.yml, renseignent certaines variables de conteneur à partir de noms partagés dans .env. Définis le nom partagé à cet endroit. La variable de conteneur seule n'a aucun effet dans ces fichiers.
Dans .env | Renseigne |
|---|
PUBLIC_APP_URL | APP_URL de l'application, et CLIENT_BASE_URL du serveur central |
PUBLIC_SYNC_URL | CORE_URL de l'application, et SERVER_PUBLIC_URL du serveur central |
PUBLIC_INFERENCE_URL | DEFAULT_INFERENCE_BASE_URL de l'application |
INFERENCE_API_KEY | DEFAULT_INFERENCE_API_KEY de l'application, et API_KEYS du service d'inférence |
POSTGRES_USER, POSTGRES_PASSWORD, SYNC_DB_NAME | la base de données, et DATABASE_URL du serveur central |
docker/compose.yml, l'application seule, prend APP_URL sous son propre nom. Le fichier de démarrage rapide du serveur central est apps/core/docker/compose.yml. Il prend SERVER_PUBLIC_URL et CLIENT_BASE_URL sous leurs propres noms. Il construit DATABASE_URL à partir de POSTGRES_USER, POSTGRES_PASSWORD et POSTGRES_DB.
L'application
Le conteneur de l'application, ghcr.io/lowcarbcheck/openplate. Il démarre sans aucune variable définie. configuration.md détaille ses fonctionnalités principales.
Serveur et adresses
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
NODE_ENV | production dans l'image, sinon development | production sert l'application compilée, rend APP_URL obligatoire, et fait de 1 la valeur par défaut pour TRUST_PROXY. L'image le définit. | |
APP_URL | http://localhost:3000, requis en production | L'adresse publique que les personnes ouvrent, par exemple https://openplate.example.com. La page d'accueil l'utilise dans ses liens de partage. En production, le serveur ne démarre pas sans elle. | Caddy |
PORT | 3000 | Le port sur lequel le serveur écoute. | |
HOST | non définie, toutes les interfaces | L'adresse sur laquelle le serveur écoute. Ne la définis pas dans un conteneur. Sans conteneur, 127.0.0.1 restreint le serveur à cette machine, pour un proxy situé sur le même hôte. | Sans Docker |
TRUST_PROXY | 1 en production, désactivé sinon | Le nombre de reverse proxies devant l'application : un nombre, true, false, ou un préréglage Express ou une plage d'adresses comme loopback ou 10.0.0.0/8. La vérification bloquant les soumissions de formulaires cross-site requiert la valeur exacte derrière un proxy. Utilise 0 s'il n'y a aucun proxy. | L'application seule |
CSP_CONNECT_EXTRA | non définie | Origines supplémentaires pour la directive connect-src de la Content-Security-Policy, séparées par des espaces. Requis si ton propre point de terminaison d'IA se trouve sur un autre hôte. | Points de terminaison d'IA personnalisés |
Langue et contenu
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
DEFAULT_UI_LANGUAGE | en | La langue affichée à un visiteur avant qu'il n'en choisisse une : en, de, fr, it, es ou tr. Le choix de l'utilisateur prévaut toujours. Toute autre valeur empêche le démarrage. | |
NUTRIENT_REFERENCE_BASIS | dge | Les valeurs de référence affichées sur l'écran Nutriments : dge (DGE allemande), efsa (UE) ou us (NASEM). Toute autre valeur empêche le démarrage. | |
CONTENT_DIR | non définie, aucune page légale | Un dossier de fichiers markdown pour les pages légales, monté en lecture seule. Indiquer un dossier inexistant empêche le démarrage. | Pages de contenu |
Synchronisation et type d'instance
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
CORE_URL | non définie, synchronisation désactivée | L'adresse de ton serveur central, telle qu'un navigateur la joint. Son origine va dans la Content-Security-Policy. Sur une instance gérée, le serveur applicatif la joint aussi, pour vérifier le compte de chaque recherche d'aliment. Une valeur mal formée interrompt le démarrage. | Synchronisation |
SYNC_SERVER_URL | non définie | Obsolète. L'ancien nom de CORE_URL. Il fonctionne encore pendant une version, et le démarrage consigne un avertissement quand il est le seul défini. Si les deux sont définis avec des adresses différentes, l'ancien nom l'emporte pour cette version et le démarrage consigne un avertissement qui nomme les deux. Supprime l'ancienne ligne avant la version qui retirera l'ancien nom. | Synchronisation |
INSTANCE_MODE | open | open ou managed. Sur une instance gérée, un administrateur invite des personnes, et le serveur central fournit l'IA. managed a besoin de CORE_URL. Toute autre valeur interrompt le démarrage. | Instances gérées |
IA fournie par l'instance
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
DEFAULT_INFERENCE_BASE_URL | non définie | Un point de terminaison compatible OpenAI que cette instance met à disposition de chaque visiteur, tel qu'un navigateur le joint. Une valeur mal formée empêche le démarrage. | IA fournie par l'instance |
DEFAULT_INFERENCE_API_KEY | non définie | La clé pour ce point de terminaison. Elle est publique : le navigateur de chaque visiteur la reçoit. | IA fournie par l'instance |
DEFAULT_INFERENCE_MODEL | openplate-plate-1 | Le nom du modèle transmis à ce point de terminaison. | IA fournie par l'instance |
Base de données d'aliments
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
FOOD_DB_API_URL | https://lowcarbcheck.org | La base de données d'aliments LowCarbCheck dans laquelle le serveur recherche les noms d'aliments. Une valeur vide désactive la recherche. | La clé de la base de données alimentaire |
FOOD_DB_API_KEY | non définie, niveau anonyme | Ta clé LowCarbCheck. Seul le serveur la lit, et elle n'atteint jamais un navigateur. | La clé de la base de données alimentaire |
FOOD_DB_BACKFILL | false | true transmet à LowCarbCheck sous forme de propositions les aliments enregistrés à partir d'une réponse de l'IA. Elle requiert FOOD_DB_API_KEY et reste désactivée sans cela. Toute valeur autre que true ou false empêche le démarrage. | Propositions pour la base de données d'aliments |
FOOD_DB_DAILY_CALL_LIMIT | 3200 | Le nombre maximal d'appels à LowCarbCheck que ce serveur effectue en un jour UTC. Une fois ce plafond dépassé, les recherches d'aliments s'interrompent jusqu'à minuit UTC et l'application le signale. La valeur par défaut préserve les 100 000 appels mensuels d'une clé gratuite. Tout autre élément qu'un entier positif bloque le démarrage. | La clé de la base de données alimentaire |
Mesures d'audience, lettre d'information et mises à jour
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
MATOMO_URL | non définie, mesures d'audience désactivées | Une instance Matomo que tu héberges toi-même. Définis-la conjointement avec MATOMO_SITE_ID. | Mesure d'audience |
MATOMO_SITE_ID | non définie | L'identifiant de site Matomo, un entier strictement positif. Définis-le conjointement avec MATOMO_URL. | Mesure d'audience |
MATOMO_EVENT_LEVEL | product | Ce que l'instance comptabilise : pageviews, product ou research. Requiert les deux réglages ci-dessus. | Ce que détermine un niveau |
NEWSLETTER_SUBSCRIBE_URL | non définie, aucun formulaire | L'adresse à laquelle le serveur relaie le formulaire d'inscription à la lettre d'information de la page d'accueil. Définis-la conjointement avec NEWSLETTER_TURNSTILE_SITE_KEY. | Inscription à la newsletter |
NEWSLETTER_TURNSTILE_SITE_KEY | non définie | La clé de site Cloudflare Turnstile de ce formulaire. Ce n'est pas le captcha d'inscription, voir Inscription avec Turnstile. | Inscription à la newsletter |
UPDATE_CHECK | activé | Définir cette valeur sur off ou false empêche le serveur de récupérer openplate.de/latest.json pour chercher de nouvelles versions. Cela interrompt aussi le décompte quotidien des requêtes par le projet. | La vérification des versions |
Journalisation
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
LOG_LEVEL | info | Le niveau de détail des journaux du serveur, selon un niveau pino : debug, info, warn ou error. | |
Fermer une instance
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
MOVED_TO_URL | non définie | Ferme cette instance et redirige les utilisateurs vers une autre, par exemple https://app.openplate.de. Chaque requête de page sert une page qui indique la nouvelle adresse, le service worker installé sur les téléphones vide ses caches et se désinscrit, et l'API renvoie 410. La valeur doit être une adresse https:// sur un hôte différent de APP_URL ; toute autre valeur interrompt le démarrage. | Transférer des personnes vers une autre instance |
Le serveur central (openplate-core)
Le conteneur du serveur central, ghcr.io/lowcarbcheck/openplate-core. Il a besoin de deux valeurs : DATABASE_URL, que les fichiers compose remplissent pour toi, et SERVER_SECRET. Tout le reste est facultatif et désactivé tant que tu ne le définis pas. README d'openplate-core explique les fonctionnalités.
Serveur et adresses
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
NODE_ENV | production dans l'image | Quand le courriel est configuré, production exige que les deux adresses de lien ci-dessous soient des adresses https:// sur un autre hôte. | Le courrier nécessite les adresses publiques |
PORT | 3000 | Le port d'écoute du service. | |
HOST | non définie, toutes les interfaces | L'adresse d'écoute du service. Ne la définis pas dans un conteneur. 127.0.0.1 restreint une instance de développement à sa propre machine. | |
TRUST_PROXY | false | Le nombre de reverse proxies intermédiaires : un nombre, true ou false. Si cette valeur est incorrecte derrière un proxy, chaque requête semble provenir du proxy. Une seule personne peut alors saturer la limite pour tout le monde. | Trois paramètres importants |
SERVER_PUBLIC_URL | non définie | L'adresse publique propre à ce service. Elle est insérée dans les liens des courriels d'invitation et de réinitialisation de mot de passe. Définis-la conjointement avec CLIENT_BASE_URL. | Le courrier nécessite les adresses publiques |
CLIENT_BASE_URL | non définie | L'adresse de l'application openplate, soit l'autre moitié de ces liens. | Le courrier nécessite les adresses publiques |
INSTANCE_NAME | openplate | Définit le nom de l'instance pour la négociation /health (instance.name) et le journal de démarrage. Les courriels ne l'utilisent pas. 64 caractères au maximum. | |
INSTANCE_LANGUAGE | en | Définit la langue des courriels lorsqu'une requête n'en précise aucune. Les valeurs acceptées sont en, de, fr, it, es ou tr. Toute autre valeur bloque le démarrage. | |
NUTRIENT_REFERENCE_BASIS | dge | Une nouvelle instance démarre avec l'une de ces valeurs de référence : dge, efsa ou us. Un administrateur peut modifier ce paramètre en production par la suite via l'API d'administration. Toute autre valeur bloque le démarrage. | |
CONTENT_DIR | non définie | Un dossier, monté en lecture seule, contenant le texte des lettres de déclaration. L'application peut lire ses pages de mentions légales depuis ce dossier. Le service ne le vérifie jamais au démarrage. | Lettres de déclaration |
LEGAL_DECLARATION_RECEIPTS_PER_DAY | 200 | Le nombre maximal d'accusés de réception de déclaration que l'instance envoie par e-mail sur une période de 24 heures, toutes adresses confondues. Au-delà, une déclaration reste enregistrée et t'est transmise, mais son accusé de réception n'est pas envoyé. | Lettres de déclaration |
LEGAL_DECLARATION_RECEIPTS_PER_NETWORK_PER_DAY | 10 | La même limite pour un réseau émetteur donné, qu'il s'agisse d'une adresse IPv4 ou d'un /64 IPv6. Un redémarrage réinitialise ce compteur. | Lettres de déclaration |
Base de données
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
DATABASE_URL | aucun, requis | La chaîne de connexion Postgres. Les fichiers compose la génèrent pour toi. | |
DATABASE_SSL | false | Définis à true si Postgres exige TLS. Accepte true, false, 1 ou 0. | |
MIGRATIONS_DIR | drizzle/migrations | Définit l'emplacement où le service trouve ses migrations de base de données au démarrage. L'image les conserve à cet endroit, laisse donc cette variable non définie. | |
Secrets
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
SERVER_SECRET | aucun, requis | Le secret racine doit comporter au moins 32 caractères. Génère-le avec openssl rand -hex 32 et sauvegarde-le avec la base de données. Modifier ce secret bloque définitivement l'accès à tous les comptes. | Trois paramètres importants |
ADMIN_TOKEN | non définie | L'identifiant d'administration de l'opérateur doit comporter au moins 24 caractères. Tu en as besoin pour créer le premier compte. Sans jeton ni compte administrateur, l'API d'administration renvoie 404. | Créer le premier compte |
Comptes et inscription
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
OPEN_SIGNUP | non défini, invitations uniquement | true permet à chacun de demander un compte avec sa propre adresse. Cela nécessite l'envoi d'e-mails. Le serveur n'accepte que true. Toute autre valeur, y compris false, bloque le démarrage. | Inscription avec Turnstile |
TURNSTILE_SECRET_KEY | non défini, aucun captcha | La clé secrète Cloudflare Turnstile qui valide le captcha d'inscription. Définis-la avec TURNSTILE_SITE_KEY, et seulement avec OPEN_SIGNUP=true. | Inscription avec Turnstile |
TURNSTILE_SITE_KEY | non définie | La clé de site publique Turnstile. /health la publie, et l'application l'utilise pour afficher le captcha. | Inscription avec Turnstile |
Invitations et périodes d'essai
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
MEMBER_INVITE_DAILY_AI_LIMIT | non défini, les membres ne peuvent pas inviter | Le nombre de requêtes IA par jour UTC qu'un compte reçoit lorsqu'un membre l'a invité, de 1 à 10000. Définis-le avec MEMBER_INVITE_ALLOWANCE_DAYS. | Invitations de membres |
MEMBER_INVITE_ALLOWANCE_DAYS | non définie | Le nombre de jours après l'inscription pendant lesquels ce quota reste actif. | Invitations de membres |
MEMBER_INVITE_LIFETIME_CAP | 5 | Le nombre total d'invitations qu'un membre peut envoyer au cours de sa vie : 0 ou plus. Cela nécessite le binôme ci-dessus, ou MEMBER_INVITE_TRIAL=true. | Invitations de membres |
MEMBER_INVITE_TRIAL | false | true permet à une invitation de membre d'accorder la période d'essai d'analyses ci-dessous à la place du quota quotidien. Cela nécessite la période d'essai et ne peut pas être combiné avec le binôme ci-dessus. | |
TRIAL_SCANS | non défini, aucune période d'essai | Le nombre d'analyses IA gratuites qu'un nouveau compte reçoit, de 1 à 100. Définis-le avec TRIAL_DAILY_AI_LIMIT, et renseigne TRIAL_ADDRESS_PEPPER avec eux. | |
TRIAL_DAILY_AI_LIMIT | non définie | Le nombre de requêtes IA par jour UTC pendant la période d'essai, de 1 à 10000. | |
TRIAL_DAYS | non défini, aucune date de fin | La période d'essai se termine aussi à minuit après ce nombre de jours, de 1 à 90, selon la première limite atteinte. Cela nécessite le binôme de la période d'essai. | |
TRIAL_TIME_ZONE | UTC | Le fuseau horaire de ce minuit, sous forme d'identifiant IANA comme Europe/Berlin. Cela nécessite TRIAL_DAYS. Un fuseau inconnu interrompt le démarrage. | |
TRIAL_ADDRESS_PEPPER | non définie | Le secret qui garantit une seule période d'essai par boîte aux lettres. Il doit comporter au moins 32 caractères. Requis avec le binôme de la période d'essai. Modifier cette valeur efface la mémoire des boîtes aux lettres ayant déjà bénéficié d'un essai. | |
TRIAL_HASH_RETENTION_DAYS | 365 | Le nombre de jours pendant lesquels le condensat de l'adresse d'un compte supprimé est conservé, de 1 à 3650, à compter de la suppression. Ensuite, un nettoyage horaire le supprime, et cette même boîte peut à nouveau obtenir un essai. Une instance sans essai de numérisation ne conserve aucun condensat. | |
AI_TRIAL_INSTANCE_DAILY_LIMIT | non défini, aucune limite | Le montant total que l'ensemble des comptes à l'essai peuvent dépenser par jour UTC. Nécessite la période d'essai. | |
AI_TRIAL_NETWORK_DAILY_LIMIT | un dixième de AI_TRIAL_INSTANCE_DAILY_LIMIT, au moins 1 | La part du plafond d'essai qu'un réseau donné (un /64 IPv6 ou une seule adresse IPv4) peut consommer par jour UTC pour les requêtes d'essai. Cette limite est désactivée sans AI_TRIAL_INSTANCE_DAILY_LIMIT, et ne doit pas le dépasser. Les personnes situées derrière un même NAT opérateur IPv4 la partagent. | |
DEFAULT_FREE_DAILY_AI_LIMIT | non défini, désactivé | Le nombre de requêtes d'IA par jour UTC accordées à chaque compte sans limite gratuite propre, de 0 à 10000. Il n'expire jamais et ne comporte pas de décompte de numérisations. Si le jour est épuisé, la réponse est 429 avec Retry-After. Il remplace l'essai de numérisation, donc le définir en même temps que la paire d'essai bloque le démarrage. Un compte bénéficiant encore d'un essai est soumis à cette limite. | |
DEFAULT_CAPABILITIES | non défini, aucune vérification | Ce qu'un compte sans liste de fonctionnalités propre peut utiliser, des étiquettes séparées par des virgules comme scan,recipes, ou none pour rien. Non défini ou vide signifie que le proxy d'IA ne vérifie aucune fonctionnalité et que chaque requête passe. Une requête demandant une fonctionnalité dont le compte est dépourvu reçoit 403 capability-required. | |
CAPABILITY_SCHEMA_MAP | non défini, vide | Paires de schemaName:label séparées par des virgules. Une requête qui demande le schéma de sortie structurée que tu indiques a besoin de cette étiquette, peu importe ce qu'indique son en-tête X-Openplate-Feature. | |
Courriel
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
SMTP_HOST | non définie | Le nom ou l'adresse du serveur SMTP, sans protocole, sans port et sans chemin. | SMTP |
SMTP_PORT | 587 | 465 utilise TLS dès le premier octet. Tout autre port doit basculer avec STARTTLS, sauf s'il s'agit d'un intercepteur de courriels sur cette machine. | SMTP |
SMTP_USER | non définie | L'identifiant SMTP. Renseigne-le avec SMTP_PASSWORD, ou laisse les deux non définis pour un serveur sans authentification. | SMTP |
SMTP_PASSWORD | non définie | Le mot de passe SMTP. | SMTP |
SMTP_FROM | non définie | L'expéditeur, au format address ou Name <address>. Requis pour SMTP. | SMTP |
MAIL_API_URL | non définie | Une API HTTP de courriels compatible avec Resend. Définis-la avec MAIL_API_KEY, MAIL_API_FROM et MAIL_OPERATOR_EMAIL. | Une API HTTP pour le courrier |
MAIL_API_KEY | non définie | La clé d'API de courriels, envoyée sous la forme d'un jeton Bearer. | Une API HTTP pour le courrier |
MAIL_API_FROM | non définie | L'adresse d'expédition pour l'API de courriels. | Une API HTTP pour le courrier |
MAIL_OPERATOR_EMAIL | non définie | Ta propre adresse. Elle reçoit ta copie de chaque résiliation ou rétractation. Les deux modes de transport l'exigent. | SMTP |
NODE_EXTRA_CA_CERTS | non définie | Le chemin dans le conteneur vers un fichier PEM contenant des autorités de certification supplémentaires. Node.js le lit au démarrage. Monte ce fichier pour un relais de messagerie dont le certificat est signé par une autorité privée. | Un relais avec une autorité de certification privée |
Proxy IA et limites
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
UPSTREAM_BASE_URL | non défini, pas d'IA | L'adresse compatible OpenAI du fournisseur, par exemple https://openrouter.ai/api/v1. Définis-la en même temps que UPSTREAM_API_KEY. | Instances gérées |
UPSTREAM_API_KEY | non définie | La clé du fournisseur. Elle n'atteint jamais un navigateur. | Instances gérées |
UPSTREAM_ZDR | non définie | OpenRouter uniquement. Si tu le définis sur true, le proxy demande à OpenRouter d'acheminer une requête uniquement vers des points de terminaison sans rétention de données. Tout autre hôte l'ignore. Une autre valeur que true, false ou vide bloque le démarrage. | Le proxy d'IA |
UPSTREAM_PROVIDER_ONLY | non définie | OpenRouter uniquement. Une liste d'identifiants de fournisseurs séparés par des virgules, par exemple google-vertex. Une requête est envoyée à l'un d'eux ou échoue, sans jamais basculer vers un autre fournisseur. Tout autre hôte l'ignore. | Le proxy d'IA |
UPSTREAM_TIMEOUT_MS | 120000 | La durée en millisecondes pendant laquelle le proxy attend la première réponse du fournisseur, puis entre chaque fragment. | |
AI_TIERS_FILE | non définie | D'où provient le modèle de chaque type de requête. Non défini, le modèle est AI_ADVERTISED_MODEL, avec le routage issu de UPSTREAM_ZDR et UPSTREAM_PROVIDER_ONLY, exactement comme avant l'existence de ce fichier. bundled utilise le fichier présent dans l'image du serveur central, ai-tiers.json, qui contient le modèle, son routage et son prix. Un chemin absolu utilise un fichier que tu montes. Une valeur invalide ou un fichier corrompu interrompt le démarrage. | Le proxy d'IA |
AI_ADVERTISED_MODEL | non définie | Le modèle utilisé par chaque analyse en l'absence de fichier de niveaux. /health le nomme, et le proxy l'injecte dans chaque requête. L'application n'analyse rien sans modèle. Avec un fichier de niveaux, il ne sert qu'à remplacer en urgence le modèle du niveau par défaut, et le serveur central consigne un avertissement à chaque démarrage. | Instances gérées |
AI_MAX_OUTPUT_TOKENS | 8192 | Le nombre maximal de jetons de sortie qu'une requête peut demander. | |
AI_RATE_LIMIT_PER_MINUTE | 20 | Le nombre maximal de requêtes qu'un compte peut effectuer sur une période de 60 secondes. | |
AI_INSTANCE_DAILY_LIMIT | non défini, aucune limite | La limite quotidienne de l'instance en unités d'IA par jour UTC. L'analyse d'une photo d'assiette coûte une unité. | Le proxy d'IA |
AI_BUDGET_ALERT_FRACTION | 0.2 | Sur une clé OpenRouter, envoyer un e-mail à MAIL_OPERATOR_EMAIL une fois par période de réinitialisation quand il reste moins que cette part du quota de la clé. Au-dessus de 0 et au-dessous de 1. | Le proxy d'IA |
AI_MAX_REQUEST_BYTES | 8000000 | La taille maximale d'une requête acceptée par le proxy, en octets. | |
AI_MAX_IMAGE_PARTS | 1 | Nombre maximal d'images par requête. Les requêtes qui dépassent cette limite renvoient 400 ai-request-too-large avant le début du décompte. | |
AI_MAX_TEXT_BYTES | 49152 | Nombre maximal d'octets de texte par requête, en cumulant le texte du message et response_format. Les requêtes qui en comportent davantage renvoient la même réponse 400. | |
AI_MAX_MESSAGES | 4 | Nombre maximal de messages par requête. Les requêtes qui dépassent cette limite renvoient la même réponse 400. | |
AI_UNIT_INPUT_TOKENS | 8192 | Estimation des jetons d'entrée par unité d'IA. Chaque requête coûte une unité, plus une par tranche de AI_UNIT_INPUT_TOKENS supplémentaire. Les limites quotidiennes comptabilisent ces unités. | Le proxy d'IA |
AI_IMAGE_INPUT_TOKENS | 1500 | Estimation des jetons d'entrée pour une image. Le texte équivaut à son total d'octets divisé par 4. | |
Consentement
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
HEALTH_CONSENT_VERSION | non défini, aucun consentement demandé | La version du consentement relatif aux données de santé que chaque compte doit accepter, par exemple 2026-09-28. Utilise de 1 à 32 lettres, chiffres, ., _ ou -. Modifier la version redemande l'accord de tout le monde. | Consentement explicite |
Notifications push
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
VAPID_PUBLIC_KEY | non défini, aucune notification | La clé publique pour le web push. Définis les trois ou aucune. Génère une paire avec pnpm core-api push keygen. | |
VAPID_PRIVATE_KEY | non définie | La clé privée pour le web push. | |
VAPID_SUBJECT | non définie | Le moyen utilisé par un service push pour te joindre : une adresse mailto: ou une adresse https://. | |
PUSH_ENDPOINT_HOSTS | non définie | Hôtes push supplémentaires, séparés par des virgules, qu'un appareil peut enregistrer. *.example.org couvre tous les hôtes sous example.org. Les services push par défaut des navigateurs sont toujours acceptés. Ne définis ceci que pour des hôtes personnalisés. Une entrée mal formée bloque le démarrage. | |
Formules
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
PLANS_UPSTREAM_URL | non défini, aucune formule | L'adresse interne du service de facturation qui reçoit /v1/plans/*. Définis-la en même temps que PLANS_UPSTREAM_SECRET. | Forfaits payants |
PLANS_UPSTREAM_SECRET | non définie | Le secret partagé vérifié par le service de facturation. | Forfaits payants |
BILLING_TOKEN | non définie | L'identifiant propre au service de facturation, d'au moins 24 caractères. Il n'accède qu'à trois routes d'administration et rien d'autre. | Forfaits payants |
BILLING_MAX_DAILY_AI_LIMIT | 1000 | Plafond quotidien d'IA maximal que BILLING_TOKEN peut allouer à un compte. Maintiens-le à un niveau égal ou supérieur à ton forfait le plus élevé. ADMIN_TOKEN n'est pas limité par celui-ci. | Forfaits payants |
Retours, partage et recherche
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
SYNC_FEEDBACK | false | true accepte les estimations signalées avec leurs photos, conservées pendant 30 jours. Tu peux consulter ces photos. | Estimations signalées |
FEEDBACK_DAILY_LIMIT | 5 | Le nombre de signalements qu'un compte peut envoyer par jour UTC. | |
FEEDBACK_MAX_REQUEST_BYTES | 8000000 | La taille maximale d'un signalement accepté par le service, en octets. | |
SYNC_SHARING | false | true active le partage d'un journal avec un médecin. | |
SYNC_RESEARCH | false | true active les contributions à la recherche et la console d'étude. | Synchronisation |
Journaux d'événements et autres
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
LOG_LEVEL | info | debug, info, warn ou error. Toute autre valeur interrompt le démarrage. | |
SYNC_NOTICE | non définie | Un message court affiché par chaque application lors de sa connexion, 280 caractères au maximum. | |
SYNC_NOTICE_URL | non définie | Un lien à côté de la notification, https:// ou http://. Nécessite SYNC_NOTICE. | |
SERVICE_VERSION | non défini, la version de l'image | Remplace la version renvoyée par /health. Ne le définis pas. | |
Le service d'inférence (openplate-inference)
Le conteneur d'inférence, ghcr.io/lowcarbcheck/openplate-inference. Il exécute le moteur du modèle et le service dans un seul conteneur. Guide de configuration d'openplate-inference détaille les options.
Service et accès
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
PORT | 8300 | Le port d'écoute du service. C'est le seul port exposé par le conteneur. | |
API_KEYS | non défini, une clé temporaire | Les clés que l'appelant doit envoyer, séparées par des virgules. Si la variable n'est pas définie, le service génère une clé au démarrage, l'affiche une fois et l'oublie au redémarrage suivant. | Obtenir la clé |
LOG_LEVEL | info | debug, info, warn ou error. Toute autre valeur interrompt le démarrage. | |
PROFILE | défini à partir de MODEL_PROFILE | Le nom du profil affiché dans le journal de démarrage : lite, quality ou custom. Le conteneur le définit à partir de MODEL_PROFILE et cela ne modifie rien d'autre. | |
Modèle et poids
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
MODEL_PROFILE | lite | Les poids téléchargés et exécutés par le conteneur : lite, lite-apache ou quality. external ne télécharge rien et utilise ton propre moteur sur MODEL_RUNTIME_URL. | Matériel |
MODELS_DIR | /models | L'emplacement des poids dans le conteneur, sur un volume. Ne le modifie que si tu montes les poids ailleurs. | |
WEIGHTS_MIRROR_BASE | non définie | Un miroir pour télécharger les poids, avec Hugging Face en secours. Le service vérifie les sommes de contrôle dans les deux cas. | |
MODEL_RUNTIME_URL | http://127.0.0.1:8080, le moteur d'inférence intégré | L'adresse de ton propre moteur d'inférence, sans /v1. MODEL_PROFILE=external la requiert. Avec tout autre profil, indiquer une adresse différente arrête le conteneur. | Variables du mode externe |
MODEL_RUNTIME_API_KEY | non définie | Une clé envoyée par le service à ton moteur d'inférence, s'il en exige une ou s'il se trouve derrière un proxy qui en requiert une. | Variables du mode externe |
MODEL_ID | openplate-plate-1 | Le nom du modèle envoyé par le service au moteur d'inférence. vLLM exige son nom exact de mise à disposition. | Variables du mode externe |
RUNTIME_PORT | 8080 | Le port du llama-server intégré, sur l'adresse de boucle locale du conteneur uniquement. | |
CONTEXT_SIZE | 8192 | Le contexte pour chaque analyse en cours. Le conteneur le multiplie par CONCURRENCY pour llama.cpp. | |
LLAMA_THREADS | le nombre de cœurs moins deux, au moins 1 | Les threads processeur pour llama.cpp. | |
LLAMA_EXTRA_ARGS | non définie | Options supplémentaires à ajouter à la fin de la commande llama-server, séparées par des espaces. Moteur d'inférence intégré uniquement. | |
GPU_LAYERS | détecté : 99 avec un GPU, sinon 0 | Le nombre de couches du modèle envoyées au GPU. 0 force le processeur. | |
NVIDIA_VISIBLE_DEVICES | défini par le moteur d'exécution de conteneurs NVIDIA | --gpus all le définit. Toute valeur autre que void ou none fait utiliser le GPU au conteneur. Tu ne le définis pas toi-même. | |
Limites
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
CONCURRENCY | 2 | Les analyses en cours en même temps. Définit aussi les créneaux de llama.cpp. | |
MAX_QUEUE_DEPTH | 8 | Les analyses qui peuvent attendre. Au-delà, l'appelant reçoit une erreur 429. | |
RATE_LIMIT_RPM | 60 | Les requêtes par minute pour chaque clé. | |
LATENCY_CEILING_MS | 0, désactivé | Le service refuse toute analyse qu'il ne peut pas terminer dans ce délai en millisecondes. | Matériel |
RUNTIME_COMPLETION_TIMEOUT_MS | 600000 | La durée maximale d'un appel au moteur d'exécution, en millisecondes. 0 désactive la limite. | |
MAX_IMAGE_BYTES | 8388608 | La plus grande photo acceptée par le service après décodage, en octets (8 Mio). | |
IMAGE_MAX_LONG_EDGE | 896 | Le grand côté sur lequel le service réduit chaque photo, en pixels, au moins 112. | |
Données alimentaires
| Variable | Valeur par défaut | Description | En savoir plus |
|---|
FOOD_SOURCE | fdc | D'où proviennent les macros : fdc (l'extrait de l'USDA dans l'image, sans réseau), off (Open Food Facts), lcc (LowCarbCheck) ou none. | Données alimentaires |
FDC_DATASET_PATH | ./data/fdc-foods.json | L'extrait de l'USDA, par rapport au répertoire de travail. | |
OFF_API_URL | https://world.openfoodfacts.org | L'adresse d'Open Food Facts, lue avec FOOD_SOURCE=off. | |
LCC_API_URL | https://lowcarbcheck.org | L'adresse de LowCarbCheck, lue avec FOOD_SOURCE=lcc. | |
LCC_API_KEY | non définie, niveau anonyme | Ta clé LowCarbCheck, lue avec FOOD_SOURCE=lcc. | |
EMBEDDING_RUNTIME_URL | non définie | Un moteur d'exécution compatible OpenAI qui dessert /v1/embeddings, pour une meilleure association des aliments. | |
EMBEDDING_RUNTIME_API_KEY | non définie | La clé pour ce moteur d'exécution. | |
Paramètres qui bloquent le démarrage
Un conteneur qui ne démarre pas se repère facilement, et cela coûte un redémarrage. Un paramètre ignoré en silence te laisse croire que tout fonctionne alors que ce n'est pas le cas. Chaque règle ci-dessous bloque donc le démarrage, et les journaux indiquent le nom de la variable.
Noms refusés
Ces noms ont été des réglages par le passé. À présent, le service refuse de démarrer dès que l'un d'eux est défini, et indique quoi utiliser à la place. Le serveur central les refuse même avec une valeur vide, supprime donc la ligne. L'application refuse GATEWAY_URL seulement lorsqu'il a une valeur.
| Variable | Refusé par | Utiliser à la place |
|---|
GATEWAY_URL | l'application | INSTANCE_MODE=managed. Le serveur central a pris le relais du proxy de l'IA. |
SIGNUP_MODE | le serveur central | Rien. Les comptes proviennent d'invitations, et OPEN_SIGNUP=true permet d'en demander une. |
SIGNUPS_OPEN | le serveur central | Rien, pour la même raison. |
REQUIRE_EMAIL_VERIFICATION | le serveur central | Rien. L'invitation tient lieu de vérification d'adresse. |
EMAIL_FROM | le serveur central | MAIL_API_FROM, ou SMTP_FROM. |
SMTP_SECURE | le serveur central | Rien. SMTP_PORT détermine le chiffrement. |
PIGEON_API_KEY | le serveur central | MAIL_API_KEY, ou SMTP_USER et SMTP_PASSWORD. |
PIGEON_BASE_URL | le serveur central | MAIL_API_URL, ou SMTP_HOST. |
Règles entre variables
L'application.
MATOMO_URL et MATOMO_SITE_ID : définis les deux ou aucun des deux. MATOMO_EVENT_LEVEL nécessite les deux.
NEWSLETTER_SUBSCRIBE_URL et NEWSLETTER_TURNSTILE_SITE_KEY : définis les deux ou aucun des deux.
INSTANCE_MODE=managed nécessite CORE_URL.
CORE_URL et l'obsolète SYNC_SERVER_URL : définis-en un. Si les deux sont définis avec des adresses différentes, SYNC_SERVER_URL l'emporte pour cette version et le démarrage consigne un avertissement.
APP_URL est obligatoire lorsque NODE_ENV=production.
MOVED_TO_URL doit être une adresse https:// sur un hôte différent de APP_URL, sans nom d'utilisateur ni mot de passe.
Une valeur hors liste bloque le démarrage : DEFAULT_UI_LANGUAGE, NUTRIENT_REFERENCE_BASIS, INSTANCE_MODE, MATOMO_EVENT_LEVEL et FOOD_DB_BACKFILL. Il en va de même pour un FOOD_DB_DAILY_CALL_LIMIT qui n'est pas un entier positif. Des adresses mal formées dans CORE_URL, DEFAULT_INFERENCE_BASE_URL, MATOMO_URL ou NEWSLETTER_SUBSCRIBE_URL bloquent aussi le démarrage. Le démarrage s'interrompt également si MATOMO_SITE_ID n'est pas un entier positif, ou si CONTENT_DIR n'est pas un dossier.
Le serveur central.
DATABASE_URL et SERVER_SECRET sont obligatoires.
Longueurs minimales : 32 caractères pour SERVER_SECRET et TRIAL_ADDRESS_PEPPER, 24 pour ADMIN_TOKEN et BILLING_TOKEN.
Le courrier utilise un seul transport. L'API HTTP de courrier nécessite MAIL_API_URL, MAIL_API_KEY, MAIL_API_FROM et MAIL_OPERATOR_EMAIL, tous les quatre. SMTP nécessite SMTP_HOST, SMTP_FROM et MAIL_OPERATOR_EMAIL, tandis que SMTP_USER et SMTP_PASSWORD vont ensemble. Spécifier les variables des deux transports à la fois interrompt le démarrage, tout comme MAIL_OPERATOR_EMAIL sans aucun transport.
Le courrier nécessite SERVER_PUBLIC_URL et CLIENT_BASE_URL. Avec NODE_ENV=production, les deux doivent être des adresses https:// sur un autre hôte, et non localhost.
Définis les deux ou aucun des deux : UPSTREAM_BASE_URL et UPSTREAM_API_KEY ; PLANS_UPSTREAM_URL et PLANS_UPSTREAM_SECRET ; TURNSTILE_SECRET_KEY et TURNSTILE_SITE_KEY ; MEMBER_INVITE_DAILY_AI_LIMIT et MEMBER_INVITE_ALLOWANCE_DAYS ; TRIAL_SCANS et TRIAL_DAILY_AI_LIMIT.
Définis les trois ou aucun : VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY et VAPID_SUBJECT.
X exige Y : OPEN_SIGNUP=true exige la configuration du courrier électronique. La paire Turnstile exige OPEN_SIGNUP=true. MEMBER_INVITE_LIFETIME_CAP exige la paire d'invitation de membre ou MEMBER_INVITE_TRIAL=true. MEMBER_INVITE_TRIAL=true exige la paire d'essai et refuse la paire d'invitation de membre. La paire d'essai exige TRIAL_ADDRESS_PEPPER. TRIAL_DAYS et AI_TRIAL_INSTANCE_DAILY_LIMIT exigent la paire d'essai. AI_TRIAL_NETWORK_DAILY_LIMIT exige AI_TRIAL_INSTANCE_DAILY_LIMIT. TRIAL_TIME_ZONE exige TRIAL_DAYS. SYNC_NOTICE_URL exige SYNC_NOTICE.
Zéro est refusé là où il équivaudrait à « désactivé » tout en signifiant l'inverse : 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 et MEMBER_INVITE_ALLOWANCE_DAYS. Tout autre nombre doit également être positif, sauf deux qui acceptent 0 : TRUST_PROXY, et MEMBER_INVITE_LIFETIME_CAP, où 0 ne laisse rien à envoyer aux membres.
Limites maximales : TRIAL_SCANS 100, TRIAL_DAYS 90, TRIAL_DAILY_AI_LIMIT et MEMBER_INVITE_DAILY_AI_LIMIT 10000, SYNC_NOTICE 280 caractères, INSTANCE_NAME 64 caractères.
SYNC_SHARING, SYNC_RESEARCH, SYNC_FEEDBACK, DATABASE_SSL et MEMBER_INVITE_TRIAL acceptent true, false, 1 ou 0. OPEN_SIGNUP n'accepte que true.
Une valeur hors de sa liste interrompt le démarrage : INSTANCE_LANGUAGE, NUTRIENT_REFERENCE_BASIS, LOG_LEVEL, TRIAL_TIME_ZONE et HEALTH_CONSENT_VERSION. Un VAPID_SUBJECT qui n'est ni mailto: ni https: interrompt le démarrage. Tout comme un SMTP_HOST comportant un schéma, un port ou un chemin. Une adresse malformée dans SERVER_PUBLIC_URL, CLIENT_BASE_URL, UPSTREAM_BASE_URL, PLANS_UPSTREAM_URL ou SYNC_NOTICE_URL interrompt aussi le démarrage.
Le service d'inférence.
MODEL_PROFILE=external nécessite MODEL_RUNTIME_URL. Avec tout autre profil, un MODEL_RUNTIME_URL différent de l'adresse intégrée interrompt le conteneur.
Un MODEL_PROFILE, FOOD_SOURCE, PROFILE ou LOG_LEVEL hors de sa liste interrompt le démarrage. Un MODEL_RUNTIME_URL ou EMBEDDING_RUNTIME_URL qui n'est pas une adresse http:// ou https:// interrompt aussi le démarrage.
Les quantités et les tailles doivent être des entiers strictement positifs. LATENCY_CEILING_MS et RUNTIME_COMPLETION_TIMEOUT_MS acceptent aussi 0. IMAGE_MAX_LONG_EDGE doit valoir au moins 112, et PORT au plus 65535.
Inscription avec Turnstile
Par défaut, un compte ne s'obtient que sur invitation. Définis OPEN_SIGNUP=true sur le serveur central, et n'importe qui peut demander un compte avec sa propre adresse. Le service envoie alors une invitation à cette adresse, et le message prouve que l'adresse fonctionne. L'inscription libre a donc besoin du courrier électronique, et le service ne démarre pas sans lui. L'application n'affiche le formulaire d'inscription que si le serveur central indique que sa porte est ouverte.
Un captcha empêche les scripts d'inonder le service de requêtes. Le serveur central vérifie un captcha Cloudflare Turnstile quand tu configures deux clés :
- 01
Connecte-toi au tableau de bord Cloudflare, ouvre Turnstile, puis choisis Add widget. Un compte gratuit suffit. Ton domaine n'a pas besoin d'utiliser Cloudflare.
- 02
Donne un nom au widget, ajoute le nom d'hôte de ton application, comme openplate.example.com, et garde le mode Géré. Choisis Créer.
- 03
Définis la clé du site dans TURNSTILE_SITE_KEY et la clé secrète dans TURNSTILE_SECRET_KEY sur le serveur central. Renseigne les deux clés ou aucune.
- 04
Recrée le serveur central, par exemple avec docker compose -f <your file> up -d.
/health publie ensuite la clé du site. La page d'inscription de l'application affiche le captcha. Son bouton d'envoi reste inactif tant que l'utilisateur ne l'a pas résolu. La clé secrète ne quitte jamais le serveur central. Le service envoie à Cloudflare la réponse au captcha et la clé secrète, pas l'adresse du visiteur.
Le service vérifie seulement la requête d'inscription, POST /v1/auth/signup-request. La connexion, l'ouverture d'une invitation et toutes les autres routes ne comportent aucun captcha. Quand le service ne peut pas joindre Cloudflare, il renvoie 503, et la personne peut réessayer plus tard. La vérification échoue de manière stricte, une requête sans réponse ne passe donc jamais.
La Content-Security-Policy de l'application autorise le captcha de Cloudflare uniquement sur une instance gérée (INSTANCE_MODE=managed), ou quand le formulaire d'infolettre est activé. Sur les autres instances, le navigateur bloque le captcha et personne ne peut envoyer le formulaire. Passe l'application en mode géré avant d'activer le captcha.
Sans les deux clés, l'inscription libre fonctionne toujours. Ses autres limites restent actives. Le service autorise cinq requêtes par heure depuis une même adresse, et un message par jour pour une boîte aux lettres. Il bloque les adresses issues de services de courriels jetables connus. Le service consigne un avertissement au démarrage.
NEWSLETTER_TURNSTILE_SITE_KEY est un réglage distinct. Il appartient à l'application et protège le formulaire d'infolettre sur la page d'accueil. Sa clé secrète reste sur le service qui reçoit ce formulaire, pas dans openplate. Inscription à la newsletter l'explique.
Construire une image soi-même
Les Dockerfiles acceptent plusieurs arguments de construction. Ce ne sont pas des paramètres pour un conteneur en cours d'exécution. OPENPLATE_BUILD_SHA inscrit le commit dans le bundle de l'application. L'image d'inférence prend BASE_IMAGE, l'image du serveur llama.cpp sur laquelle s'appuyer. Elle prend aussi NODE_IMAGE, l'image Node.js pour la construction. VITE_ALLOWED_HOSTS s'applique uniquement au serveur de développement de l'application et n'a pas d'hôtes par défaut.