Aller au contenu
quest'n'click

Clever CloudGuidePour adminsS'applique de 4.2.3

Configuration

This page in EnglishCette page sur le wiki GitHub

Le Studio Server lit une configuration JSON, qui ne contient aucun secret, et quelques secrets, chacun depuis une variable ou un fichier. Cette page pose les deux sur les deux applications Clever Cloud, et sert de référence de STUDIO_CONFIG_JSON, champ par champ.

Ce que vous obtenez

L’application studio et l’application worker portent chaque variable dont elles ont besoin pour se construire et démarrer : les commandes de lancement, les hooks de build, la configuration sur une ligne, et les secrets, posés depuis des fichiers pour qu’aucune valeur ne soit tapée ni affichée.

Contexte et versions

  • Un Studio hébergé sur Clever Cloud, déployé depuis le dépôt du moteur, à partir de la 4.2.3 (STUDIO_METRICS_TOKEN, STUDIO_BACKUP_CRON et git sont arrivés en 4.2.3).
  • Vérifié sur : 19 octobre 2026, par le déploiement de référence (moteur au commit 52e68932, puis c66fbf56, package.json 4.2.2 avant le tag 4.2.3) : ces variables, avec STUDIO_METRICS_TOKEN et STUDIO_BACKUP_CRON=1 posés, et trois noms en *.cleverapps.io. Les commandes exactes de cette page ne sont pas vérifiées sur une installation réelle.

Prérequis

Où lancer les commandes

Sur votre machine, dans le dépôt du moteur où les deux applications sont liées sous leur alias (Applications et add-ons).

Étapes

  1. Créez les clés des jobs. Le worker n’exécute que les jobs que le Studio signe de sa clé privée :

    # sur votre machine, dans le dépôt du moteur
    mkdir -p ~/secrets/my-game && npm run studio-server -- worker-keys --out ~/secrets/my-game

    studio-worker.key (0600) est celle du Studio, studio-worker.pub celle du worker. La commande refuse de les écraser, et ne les affiche jamais.

  1. Créez la clé de session et, si vous voulez /metrics, son jeton :

    # sur votre machine
    openssl rand -base64 48 > ~/secrets/my-game/session-key && chmod 600 ~/secrets/my-game/session-key
    openssl rand -base64 32 > ~/secrets/my-game/metrics-token && chmod 600 ~/secrets/my-game/metrics-token
  1. Posez les variables ordinaires de l’application studio :

    # sur votre machine, dans le dépôt du moteur
    clever env set --alias my-game-studio CC_NODE_DEV_DEPENDENCIES install
    clever env set --alias my-game-studio CC_POST_BUILD_HOOK "npm run studio-client"
    clever env set --alias my-game-studio CC_RUN_COMMAND "npm run studio-server -- serve"
    clever env set --alias my-game-studio CC_HEALTH_CHECK_PATH /startz
    clever env set --alias my-game-studio STUDIO_BACKUP_CRON 1
  1. Posez ses secrets depuis leurs fichiers. Le texte d’une clé commence par -----BEGIN, que clever env set lit comme une option si -- ne le précède pas :

    # sur votre machine, dans le dépôt du moteur
    clever env set --alias my-game-studio -- STUDIO_WORKER_KEY "$(cat ~/secrets/my-game/studio-worker.key)"
    clever env set --alias my-game-studio -- STUDIO_SESSION_KEY "$(cat ~/secrets/my-game/session-key)"
    clever env set --alias my-game-studio -- STUDIO_METRICS_TOKEN "$(cat ~/secrets/my-game/metrics-token)"

    STUDIO_OIDC_CLIENT_SECRET a été posé avec le fournisseur (Keycloak). Les identifiants de la base et de Cellar viennent des add-ons (POSTGRESQL_ADDON_URI, CELLAR_ADDON_KEY_ID, CELLAR_ADDON_KEY_SECRET) : ne posez rien pour eux.

  1. Écrivez la configuration dans un fichier, vérifiez-la, et posez-la sur une ligne dans STUDIO_CONFIG_JSON :

    {
      "publicUrl": "https://studio.example.fr",
      "playUrl": "https://play.example.fr",
      "game": "my-game",
      "workDir": "/home/bas/work",
      "host": "0.0.0.0",
      "trustProxy": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
      "store": { "kind": "postgres" },
      "blobs": { "kind": "s3", "host": "cellar-c2.services.clever-cloud.com", "bucket": "my-game-studio" },
      "oidc": { "issuer": "https://keycloak.example.fr/realms/web-scumm", "clientId": "studio", "audience": "studio-api", "cliClientId": "web-scumm-cli" },
      "worker": { "url": "https://worker.example.fr", "instance": "my-game-studio" }
    }
    # sur votre machine, dans le dépôt du moteur, le fichier ci-dessus enregistré sous ~/secrets/my-game/studio.config.json
    clever env set --alias my-game-studio STUDIO_CONFIG_JSON "$(node -p 'JSON.stringify(JSON.parse(require("fs").readFileSync(process.argv[1], "utf8")))' ~/secrets/my-game/studio.config.json)"

    Le ops/studio/studio.config.example.json du dépôt est le même exemple. La configuration ne contient aucun secret.

  1. Posez les variables de l’application worker. WORKER_INSTANCE est le worker.instance de la configuration :

    # sur votre machine, dans le dépôt du moteur
    clever env set --alias my-game-worker CC_NODE_DEV_DEPENDENCIES install
    clever env set --alias my-game-worker CC_RUN_COMMAND "npm run studio-worker"
    clever env set --alias my-game-worker CC_POST_BUILD_HOOK "python3 -m pip install --target .python --require-hashes --only-binary=:all: -r ops/studio/worker-requirements.lock"
    clever env set --alias my-game-worker WORKER_INSTANCE my-game-studio
    clever env set --alias my-game-worker -- WORKER_PUBLIC_KEY "$(cat ~/secrets/my-game/studio-worker.pub)"

    Le hook installe les paquets Python des outils d’assets (Pillow, NumPy, SciPy), chaque hash vérifié, des roues seulement.

Résultat attendu, et comment le vérifier

Les noms, jamais les valeurs :

# sur votre machine, dans le dépôt du moteur
clever env --alias my-game-studio | grep -oE '^[A-Z][A-Z0-9_]*='
clever env --alias my-game-worker | grep -oE '^[A-Z][A-Z0-9_]*='

Le studio liste les variables des étapes 3 à 5, STUDIO_OIDC_CLIENT_SECRET et celles des add-ons ; le worker liste celles de l’étape 6 et aucune variable d’add-on. La configuration est vérifiée pour de bon au démarrage du serveur : une configuration refusée l’arrête avec une ligne qui nomme le champ (Premier déploiement).

Erreurs fréquentes

SymptômeCauseCorrection
clever env set dit qu’une option est inconnueUne valeur PEM sans -- avant le nomLa forme de l’étape 4
<NAME>: the secret is empty or too short (8 characters at least)Un fichier vide, ou un mauvais chemin dans $(cat …)Vérifiez le fichier
a session key is 32 characters or moreUn STUDIO_SESSION_KEY trop courtopenssl rand -base64 48
STUDIO_METRICS_TOKEN: 32 characters at least (openssl rand -base64 32)Un jeton trop courtÉtape 2
STUDIO_CONFIG_JSON: unknown key "…"Une coquille, ou un champ d’une version plus récenteLa liste des champs plus bas
trustProxy is required when the server is reachable beyond the loopbacktrustProxy omis avec OIDCGardez-le
<NAME>_FILE (…) is readable by others: chmod 600Un fichier de secret aux droits trop larges (hors de Clever)chmod 600

Fichiers ou données modifiés

  • ~/secrets/my-game/ : les clés et jetons (0600), le fichier de configuration.
  • Les variables des deux applications chez Clever Cloud. Un changement de variable s’applique au déploiement ou au redémarrage suivant.

Reprise ou retour arrière

clever env rm <NAME> --alias <application> retire une variable. Changer un secret plus tard, c’est Renouveler les clés.

Référence : comment les secrets sont lus

  • Les secrets sont STUDIO_DATABASE_URL, STUDIO_S3_KEY_ID, STUDIO_S3_KEY_SECRET, STUDIO_OIDC_CLIENT_SECRET, STUDIO_SESSION_KEY, STUDIO_WORKER_KEY, STUDIO_METRICS_TOKEN et STUDIO_GIT_KEY.
  • Chacun vient de <NAME>_FILE (un fichier en mode 0600, préféré hors de Clever ; des droits plus larges sont refusés), sinon de <NAME>, sinon, pour les trois premiers, de la variable de l’add-on (POSTGRESQL_ADDON_URI, CELLAR_ADDON_KEY_ID, CELLAR_ADDON_KEY_SECRET).
  • Au démarrage, le serveur lit chacun une fois, puis retire de son environnement chaque variable qui le contenait : aucun processus enfant n’en hérite, et il n’est jamais consigné. Une valeur de moins de 8 caractères est refusée.
  • STUDIO_WORKER_KEY peut avoir ses retours à la ligne écrits \n. STUDIO_SESSION_KEY peut contenir plusieurs clés, séparées par des virgules, pour les renouveler (Renouveler les clés).
  • Le worker lit WORKER_PUBLIC_KEY (ou WORKER_PUBLIC_KEY_FILE), WORKER_INSTANCE et PORT, et WORKER_PYTHON_PATH quand les paquets Python ne sont pas dans .python.

Chaque variable a son entrée dans Variables d’environnement.

Référence : d’où vient la configuration

Dans l’ordre : --config <fichier> sur la ligne de commande ; sinon le fichier que nomme STUDIO_CONFIG ; sinon STUDIO_CONFIG_JSON, le JSON lui-même (ce qu’utilise une plateforme sans fichiers comme Clever Cloud). Sans aucun des trois, une commande dit usage: studio-server <serve|import <dir>|export <dir>> --config <file> (or STUDIO_CONFIG_JSON). Dans clever ssh, le shell a les variables de l’application : aucune commande n’a besoin de --config.

Référence : STUDIO_CONFIG_JSON, champ par champ

Une clé inconnue au premier niveau est refusée au démarrage (unknown key "…"). Dans un champ, une sous-clé inconnue est ignorée.

ChampRequisValeurDéfaut
publicUrlouil’origine du Studio, http(s) ; la seule Origin qu’une mutation par cookie peut porter—
playUrlouil’origine du jeu, http(s) ; différente de celle de publicUrl—
gameouil’identifiant du jeu (lettres, chiffres, _, -) ; un jeu par instance—
workDirouile dossier de travail de l’instance (le jeu matérialisé, le brouillon), éphémère sur Clever Cloud : /home/bas/work—
portnonle port ; ne le mettez pas sur Clever Cloud, qui donne PORT (un port ici l’emporterait)PORT, sinon 8080
hostnonl’adresse d’écoute ; sans oidc, seule la boucle locale est acceptée0.0.0.0
trustProxyavec oidc au-delà de la boucle localeles adresses ou réseaux IPv4 dont on croit X-Forwarded-For / X-Forwarded-Proto[]
store.kindouipostgres (hébergé) ou sqlite (local, avec store.file)—
blobs.kindouis3 (avec host, bucket) ou fs (avec dir) ; s3 avec un worker—
oidcpour un Studio partagéle fournisseur (ses champs) ; sans lui, le serveur local sur la boucle localeaucun
sessions.idleHours, sessions.absoluteHoursnonles durées d’inactivité et absolue d’une session du navigateur8 et 24
worker.url, worker.instanceavec oidcl’URL du worker, et un nom de 3 à 64 lettres, chiffres, _ ou - (le WORKER_INSTANCE du worker)—
clientDirnonle Studio construit ; avec oidc, le serveur refuse de démarrer sans lui.cache/studio-client
publicDirnonles images et sons préparés du jeu (npm run assets les écrit, ils sont versionnés) ; le Studio les montre aux membres et chaque prévisualisation les joue ; en lecture seule sur un Studio hébergépublic/ du dépôt déployé
publicBuildsnontrue : les builds publiés (/play/ sur l’origine du jeu) sont ouverts à tous sans session, avec les icônes que leur page nomme (D42, le choix de l’owner)false
gitnonle dépôt Git du jeu : remote (sans identifiants ; la clé de déploiement est STUDIO_GIT_KEY), branch (main), path (un dossier du dépôt), committer {name, email}, knownHosts (sans lui, confiance au premier usage)aucun

trustProxy sur Clever Cloud

Les plages privées de l’exemple (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) sont une hypothèse : les proxys de Clever s’y trouvent, et chaque personne est ainsi distinguée. Elles sont à réduire aux vrais proxys de Clever par la passe studio-hosted. D’ici là, une adresse de ces plages pourrait se prétendre n’importe quel X-Forwarded-For, ce qui compte pour les limites de débit par adresse.

Références