Nubiecloud Docs
NubiStack

Le manifeste nubicloud.yaml

Référence complète du fichier qui décrit une stack — services, bases de données, ressources, et les cinq formes de variables d'environnement.

Le nubicloud.yaml décrit ce que vous voulez, pas comment le faire. Vous listez vos services et vos bases ; la plateforme se charge du build, du provisionnement, du câblage et de l'ordre de déploiement.

Structure générale

version: "1"          # version du format (actuellement "1")
name: mon-app         # nom de la stack (optionnel)

databases:            # bases de données managées (optionnel)
  - name: db
    type: postgres

services:             # au moins un service (obligatoire)
  - name: api
    type: web
    image: mon-registry/api:1.0
    port: 8000

envGroups:            # variables partagées entre services (optionnel)
  commun:
    LOG_LEVEL: info

ℹ️ Les noms (services, bases, groupes) doivent être en minuscules, composés de lettres, chiffres et tirets, et commencer par une lettre (40 caractères max). Services et bases partagent le même espace de noms : deux briques ne peuvent pas porter le même nom.


services[]

Un service = une application qui tourne.

ChampDéfautRôle
nameObligatoire. Nom unique, référencé par fromService et dependsOn.
typewebweb, private, worker ou cron (voir ci-dessous).
buildLe service est buildé depuis un dépôt (voir build).
imageLe service utilise une image déjà construite.
frameworkgénériqueLe framework de l'app (python-fastapi, nodejs-express, nextjs, react…).
portPort d'écoute du service.
replicas1Nombre d'instances.
commandCommande de démarrage, si l'image n'en définit pas. Liste (["celery", "worker"]) ou chaîne.
exposePublicfalseCrée une URL publique HTTPS. Type web uniquement.
domainDomaine personnalisé (implique exposePublic: true).
healthCheckPathChemin HTTP de contrôle de santé (/health). Vide = simple vérification du port.
preDeployCommandCommande de migration jouée avant le démarrage. Ex. ["alembic", "upgrade", "head"].
dependsOn[]Briques (services ou bases) qui doivent être en ligne avant celle-ci.
resourcesdéfauts plateforme{ cpu, memory, storage } (voir Ressources).
scheduleExpression cron. Type cron uniquement, et obligatoire pour lui.
env{}Variables d'environnement (voir env).

⚠️ build ou image, jamais les deux, jamais aucun des deux. C'est ce choix qui détermine si la brique passe par une phase de build.

Les quatre types de service

TypeSert du HTTPExposable publiquementPour quoi
webAPI, site, front — le cas courant
privateService interne, joignable seulement par les autres briques de l'environnement
workerTâche de fond permanente (consommateur de file, worker Celery…)
cronExécution planifiée ; nécessite schedule
- name: nettoyage
  type: cron
  schedule: "0 2 * * *"        # tous les jours à 2 h
  image: mon-registry/tools:1.0
  command: ["python", "cleanup.py"]

build

À utiliser quand la plateforme doit construire l'image depuis votre dépôt.

ChampDéfautRôle
repodépôt connecté de la stackURL du dépôt
branchmainBranche à builder
rootDir.Sous-dossier source (monorepo)
dockerfileDockerfileChemin du Dockerfile, relatif à rootDir
methodautodockerfile, buildpack ou auto
buildFilterChemins qui déclenchent un rebuild. Ex. ['api/**', 'shared/**']
builderImageImage de build (méthode buildpack)
buildArgs{}Arguments figés dans l'image (≠ variables d'exécution)
- name: front
  type: web
  framework: nextjs
  build:
    repo: https://github.com/vous/votre-repo
    branch: main
    rootDir: apps/web
    buildFilter: ['apps/web/**', 'packages/ui/**']
  port: 3000
  exposePublic: true

💡 Monorepo : déclarez plusieurs services avec des rootDir différents. Chacun devient une brique indépendante avec son propre build.

image

À utiliser pour une image déjà publiée (registre public ou privé).

- name: cache-proxy
  type: private
  image: nginxinc/nginx-unprivileged:stable-alpine
  port: 8080

⚠️ L'image doit tourner sans privilèges root. Beaucoup d'images officielles ont une variante prévue pour ça (par exemple nginx-unprivileged au lieu de nginx). Une image qui exige root ne démarrera pas.


databases[]

Une base ou un courtier de messages managé : la plateforme le provisionne, génère les identifiants et les garde secrets.

ChampDéfautRôle
nameObligatoire. Nom unique, référencé par fromDatabase.
typeObligatoire. postgres, redis, mysql, mongodb ou rabbitmq.
versionversion par défaut du typeVersion à déployer
resourcesdéfauts plateforme{ cpu, memory, storage }
enableBackupsfalseSauvegardes automatiques
additionalDatabasesPostgreSQL uniquement. Bases supplémentaires ({ name, user })
extensionsPostgreSQL uniquement. Ex. [postgis, pgvector]
databases:
  - name: db
    type: postgres
    extensions: [pgvector]
    enableBackups: true
    additionalDatabases:
      - name: analytics
        user: analytics_user
    resources: { cpu: 0.5, memory: 1, storage: 5 }

  - name: cache
    type: redis
    resources: { cpu: 0.25, memory: 0.5 }

ℹ️ Vous n'écrivez jamais les identifiants. Ils sont générés au provisionnement et injectés dans vos services via fromDatabase. Voir Services managés.


Ressources

resources s'exprime toujours de la même façon, pour un service comme pour une base :

CléUnitéExemple
cpucœurs0.5
memoryGo1
storageGo10

Omettre resources applique les valeurs par défaut de la plateforme. Le total de la stack est confronté au quota du projet lors du plan.


env — les cinq formes

C'est le cœur de NubiStack : les variables d'environnement ne se recopient pas, elles se référencent. Chaque variable utilise exactement une forme.

1. Valeur littérale

env:
  LOG_LEVEL: info                              # forme courte
  API_TOKEN: { value: "abc123", secret: true } # chiffrée au repos

secret: true n'est valide qu'avec value.

2. Depuis une base — fromDatabase

env:
  DATABASE_URL: { fromDatabase: { name: db, property: connectionString } }
  DB_HOST:      { fromDatabase: { name: db, property: host } }
propertyValeur injectée
connectionString (défaut)L'URL de connexion complète, mot de passe inclus
host / portAdresse interne et port
user / passwordIdentifiants
databaseNom de la base

Option scheme : force le préfixe de l'URL selon votre pilote (par exemple postgresql+asyncpg pour SQLAlchemy asynchrone).

DATABASE_URL: { fromDatabase: { name: db, property: connectionString, scheme: postgresql+asyncpg } }

3. Depuis un service voisin — fromService

env:
  API_URL: { fromService: { name: api, property: url } }
propertyValeur injectée
url (défaut)http://hôte-interne:port
host / portAdresse interne du service et son port

Référencer un service crée automatiquement une dépendance de déploiement : le service référencé sera déployé d'abord.

4. Générée par la plateforme — generateValue

env:
  SECRET_KEY: { generateValue: true }
  JWT_SECRET: { generateValue: { length: 64, charset: hex } }

La valeur est générée une fois, puis reste stable entre les mises à jour. charset accepte alnum (défaut), hex ou base64 ; length va de 8 à 256.

5. Demandée au premier déploiement — sync: false

env:
  STRIPE_KEY: { sync: false }

La variable vous est demandée une seule fois, lors de l'application de la stack (section Secrets à fournir du plan), et n'est jamais écrasée ensuite. C'est la forme à utiliser pour les clés d'API tierces, qu'on ne veut pas écrire dans un fichier versionné.

Bonus — héritée d'un groupe : fromGroup

envGroups:
  commun:
    LOG_LEVEL: info
    REGION: eu-west

services:
  - name: api
    # ...
    env:
      LOG_LEVEL: { fromGroup: commun }

Ordre de déploiement et dépendances

La plateforme calcule l'ordre toute seule à partir de :

  • les dependsOn que vous déclarez explicitement,
  • les références fromService (dépendance implicite),
  • les bases de données, toujours provisionnées avant les services qui les utilisent.
- name: front
  dependsOn: [api]

Une brique en attente affiche Déploiement bloqué avec le nom de ce qu'elle attend, puis démarre d'elle-même dès que la dépendance est en ligne.

⚠️ Les dépendances circulaires sont refusées au moment du plan (api dépend de front qui dépend de api). Le message d'erreur indique le cycle.


Erreurs de validation fréquentes

Le plan valide le manifeste avant toute création. Les refus les plus courants :

MessageCause
renseigner exactement un de build ou imageLe service n'a aucune source, ou les deux
seul un service web peut être exposéexposePublic ou domain sur un worker, cron ou private
service cron : schedule requisType cron sans schedule
fromDatabase 'x' n'existe pas dans databases[]Référence vers une base non déclarée
nom dupliqué dans le manifesteDeux briques (services ou bases) avec le même nom
env var ambiguë : formes multiplesDeux formes dans la même variable (ex. value et generateValue)
cycle de dépendances détectéBoucle dans dependsOn / fromService
extensions n'est valide que pour postgresextensions ou additionalDatabases sur une base non PostgreSQL

Voir aussi

Sur cette page