Aller au contenu

Aller au sommaire de la doc

Ce que votre appli doit respecter

Quelques règles suffisent pour qu’une appli tourne sur while. Votre agent les connaît et les applique : cette page les dit aussi pour vous.

Mis à jour le 9 novembre 2026.

Voir en Markdown

Écouter sur le port PORT

Votre appli écoute en HTTP sur le port de la variable PORT : celui de while.yaml, 8080 par défaut. Elle écoute sur toutes les interfaces (0.0.0.0), pas seulement sur localhost.

Répondre sur le chemin de santé

Votre appli répond 2xx ou 3xx sur son chemin de santé (health.path, /health par défaut) dès qu’elle peut servir.

  • while l’appelle chaque seconde.
  • Une version qui ne répond pas ne reçoit jamais de trafic : while la retire d’elle-même, et la version d’avant reste en ligne.
  • Une nouvelle version a 120 secondes pour répondre ; une appli qui migre sa base au démarrage (Metabase, Keycloak) en demande plus avec health.startup_timeout_seconds, jusqu’à 900.

Passer ses tests à la construction

Les tests du projet tournent pendant la construction (npm test, pytest, go test).

  • S’ils échouent, rien n’est mis en ligne.
  • Un script de test vide ou absent est sauté.
  • Quand plusieurs services partagent les mêmes sources, les tests tournent une fois, et build: { skip_tests: true } les coupe pour un service.
  • Avec votre propre Dockerfile, while ne joue que son étage « test ».

Tourner sans privilèges

Votre appli tourne sans privilèges, jamais en root. Un USER numérique qui n’est pas root est respecté, par exemple USER 1001:1001. Un USER nommé (USER node), root ou absent devient 1000:1000, l’utilisateur que déclarent les Dockerfiles générés par while.

Écrire ses journaux sur la sortie standard

Votre appli écrit ses journaux sur la sortie standard et la sortie d’erreur. while les garde, et votre agent les lit avec l’outil get_logs.

Garder ses fichiers au bon endroit

Un worker et une tâche ont un /tmp de 1 Gio, qui ne prend rien sur leur mémoire, et resources.disk le porte jusqu’à 8 Gio. Le /tmp d’un service web, lui, prend sur sa mémoire : ses gros fichiers vont dans un worker, une base ou un bucket. Un /tmp se vide à chaque redémarrage, donc ce qui doit durer va dans une base ou un bucket.

Lire un secret posé en fichier

Un secret posé en fichier se lit dans /run/secrets/<NOM>, jamais dans une variable.

  • Il se pose avec set_env et file: true, ou avec { secret: …, file: true } dans while.yaml.
  • En Node : (await readFile('/run/secrets/CLE_API', 'utf8')).trim().
  • En Python : Path('/run/secrets/CLE_API').read_text().strip().
  • En Go : os.ReadFile("/run/secrets/CLE_API"), puis strings.TrimSpace.
  • Dans un projet lié à une connexion fédérée qui fait valider chaque mise en production, c’est la seule façon de recevoir un secret : les variables y sont montrées en clair à qui valide.

Appeler Internet par une connexion

Internet est fermé à l’appli par défaut : elle ne joint que ses autres services, ses bases, ses caches et while.

  • Il l’est aussi avec egress: none, ou avec une liste allow, qui n’ouvre rien en direct.
  • Pour appeler une API externe, passez par une connexion : avec connections: [meteo], l’adresse arrive dans METEO_URL, la clé reste dans while, et chaque appel est tracé.
  • Une API sans IPv6 passe alors par la sortie IPv4 de while.
  • network: { egress: all } ouvre Internet en direct, en IPv6 comme en IPv4, si les règles de l’organisation le permettent, sauf les réseaux internes de la plateforme et le port 25 (SMTP).

Choisir qui ouvre l’appli

Un service est public par défaut.

  • access: internal le met derrière la connexion de while, et l’appli n’a rien à coder pour l’authentification.
  • Elle lit l’identité dans X-While-Email, X-While-Name et X-While-Groups (encodés en pourcentage), ou dans X-While-Identity, un JWT.
  • while retire tout en-tête X-While-* venu du client.

Tenir dans ses ressources

Par défaut, un service web a 200 mCPU et 192 Mio de mémoire, et un worker 100 mCPU et 128 Mio ; resources les change.

  • Un conteneur demande 8 Gio de mémoire au plus, et jusqu’à 16 Gio si le quota de mémoire de l’organisation le permet.
  • Une organisation demande au plus 4 vCPU et 8 Gio de mémoire par défaut, tous ses projets et environnements ensemble ; l’outil get_usage (vue quotas) donne les siens.
  • Chaque service y compte pour son nombre maximal d’instances : scale.max (10 sans réglage), sans dépasser la limite « instances » (3 par défaut).
  • Un service web sans scale.max compte donc 3 fois ses ressources, puisqu’il monte jusque-là avec le trafic.
  • Les tâches, les caches et les bases comptent aussi, une base pour 100 mCPU et 256 Mio par instance.

Sortir avec le code 0

Une tâche planifiée (crons) sort avec le code 0 quand tout va bien. Tout autre code est un échec : l’agent le reçoit avec l’erreur résumée et les dernières lignes du journal (outils list_tasks et run_task).

Essayer contre une vraie base

Pour essayer contre une vraie base, inutile d’en monter une sur votre poste.

  • Mettez en ligne : la base naît avec l’environnement, et les versions suivantes se construisent en une minute environ.
  • Lancez ensuite la tâche (run_task, avec wait), puis lisez le résultat (query_database).
  • Un échec donne l’erreur et quoi faire.
  • Une prévisualisation permet d’essayer sans toucher la production.

Les variables toujours présentes

Votre appli reçoit toujours ces variables, en plus de celles de ses briques :

VariablesCe qu’elles disent
PORT, HOSToù écouter
WHILE_PROJECT, WHILE_ENVIRONMENT, WHILE_SERVICE, WHILE_RELEASEle projet, l’environnement, le service et la version
WHILE_CRON, WHILE_TRIGGERdans une tâche : laquelle, et comment ce passage a été lancé (scheduled, manual ou catch_up)
WHILE_CATCH_UP_START, WHILE_CATCH_UP_ENDla période d’un rattrapage
NODE_ENVproduction en production, development ailleurs
OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAMEla télémétrie OpenTelemetry
SENTRY_DSNles erreurs, avec n’importe quel SDK Sentry côté serveur (une adresse interne, joignable sans ouvrir les sorties réseau)
SENTRY_DSN_PUBLICles erreurs, avec un SDK Sentry dans le navigateur
DATABASE_URL, REDIS_URL…celles des briques déclarées, et celles posées avec set_env

Branchez votre agent, il s’occupe du reste

À coller dans votre agent

Lis while.sh/agents, puis mets mon appli en ligne avec while.

Copier les instructions

Pas besoin de compte pour essayer : votre appli est en ligne tout de suite. Pour la garder, connectez-vous.

Un projet pour votre entreprise ? Parlez à l’équipe : hello@while.sh