Déployer Next.js sur Sevalla
Sevalla est un PaaS (par Kinsta) avec deux produits d'hébergement pour Next.js :
- Application Hosting exécute un vrai serveur Node.js. Requis pour SSR, route handlers (routes API), proxy (anciennement middleware), ISR (
revalidate), actions serveur ou websockets. - Static Site Hosting sert le résultat d'un export statique (
output: 'export'). Pas de code serveur du tout. Limite de 100 sites statiques par entreprise.
Prenez d'abord cette décision. Elle détermine tout ce qui suit.
Étape 0 : Décider quel produit d'hébergement utiliser
Inspectez le dépôt avant toute autre action :
- Lisez
next.config.js/next.config.ts/next.config.mjspouroutput: 'export'ououtput: 'standalone'. - Recherchez dans la base de code :
app/api/,pages/api/,proxy.tsouproxy.js(Next.js 16),middleware.tsoumiddleware.js(Next.js 15 et versions antérieures),"use server",getServerSideProps,revalidate(ISR),NextResponse, ou tout client de base de données ou d'authentification utilisé côté serveur. - Décidez :
- L'un des éléments ci-dessus est présent : Application Hosting (serveur requis). Passez à l'étape 1.
- Aucun présent, contenu purement statique, marketing ou blog : Static Site Hosting est plus simple et moins cher. Lisez
references/static-hosting.md. - Incertain, ou l'utilisateur souhaite des fonctionnalités dynamiques plus tard : par défaut, choisissez Application Hosting. Il peut faire tout ce que l'hébergement statique fait.
Si c'est vraiment ambigu, posez une question à l'utilisateur : "Cette application a-t-elle besoin d'un serveur actif (routes API, ISR, authentification, appels à la base de données) ou est-elle entièrement statique ?" Ne devinez pas en silence, car un mauvais choix implique de refaire tout le déploiement.
Vérifiez également dans le dépôt la présence d'un client de base de données (Prisma, Drizzle, pg, mysql2, Mongoose, redis, ioredis) et d'éventuels uploads de fichiers. Si vous en trouvez un, lisez references/data-services.md avant l'étape 3.
Étape 1 : Choisir une stratégie de build (Application Hosting)
Sevalla construit les applications basées sur Git avec l'une des quatre stratégies suivantes :
- Nixpacks, la valeur par défaut. Zéro configuration pour une application Next.js standard. Utilisez-le sauf s'il y a une raison de ne pas le faire.
- Railpack, le successeur de Nixpacks. Également zéro configuration. Un bon choix pour une nouvelle application. Définissez-le avec le champ API
build_type: "railpack". - Dockerfile, lorsque l'utilisateur souhaite une image petite et reproductible, a un monorepo avec lequel les builders auto-détectés ont du mal, ou demande Docker.
- Buildpacks (
pack). Rarement nécessaire pour Next.js.
Lisez references/app-hosting.md avant d'écrire une configuration. Il contient les scripts exacts de package.json, le Dockerfile recommandé, les surcharges nixpacks.toml et le paramètre Build path pour les monorepos. Ne créez pas un Dockerfile ou nixpacks.toml de toutes pièces à partir de connaissances générales sur Next.js. Sevalla a des contraintes spécifiques (ci-dessous) que les guides génériques ne mentionnent pas.
Étape 2 : Préparer le dépôt (contraintes Sevalla)
Ces points font échouer presque tous les premiers déploiements. Vérifiez-les tous avant de déployer :
- Lisez le port depuis
$PORTet liez à0.0.0.0. Le port par défaut du processus web est 8080, et Sevalla le transmet dansPORT. Seuls les ports 80 et 443 sont ouverts sur Internet, et Sevalla les achemine vers$PORT. Avec Nixpacks ou Railpack, le script de démarrage doit êtrenext start -p ${PORT:-8080} -H 0.0.0.0. Un simplenext startécoute sur 3000. - Les variables
NEXT_PUBLIC_*sont intégrées au moment du build. Créez-les en tant que variables de build (is_buildtime: true) avant que le build ne s'exécute. Une variable ajoutée ultérieurement nécessite un nouveau déploiement, pas un redémarrage. - Le système de fichiers est éphémère. Tout ce que l'application écrit sur le disque au moment de l'exécution (téléchargements, fichiers générés, caches sur disque) est perdu à chaque redéploiement ou redémarrage. Utilisez le stockage d'objets, ou un disque persistant si l'application a vraiment besoin d'écritures sur le disque local (par exemple SQLite ou un CMS auto-hébergé). Voir
references/data-services.md. output: 'standalone'uniquement avec le Dockerfile.next startn'utilise pas le bundle standalone, et Next.js avertit"next start" does not work with "output: standalone" configuration. Donc avec Nixpacks ou Railpack, ne définissez pasoutput. Avec le Dockerfile, définissezoutput: 'standalone'.- Ne commitez pas
node_modulesou.next. Un dossiernode_modulescommité est une cause documentée d'échecs de build sur Sevalla. - Épinglez la version de Node.js. Nixpacks utilise Node 18 par défaut, et Next.js 16 nécessite Node 20.9 ou supérieur. Définissez
"engines": { "node": "22.x" }danspackage.json, ou la variable de buildNIXPACKS_NODE_VERSION=22. - Monorepos : définissez le Build path (champ API
build_path) sur le dossier de l'application Next.js, par exempleapps/web. Avec le Dockerfile, définissez égalementdocker_contextetdockerfile_path. - Nom dans
package.json: n'utilisez pas"node"ou"js"comme nom de package. Il est documenté que cela casse les builds Sevalla. - Les guillemets doubles dans les valeurs de variables doivent être échappés comme
\". Les guillemets non échappés sont supprimés ou font échouer le déploiement. - Secrets (URLs de base de données, clés API) allez dans les variables d'environnement Sevalla. Ne commitez jamais un fichier
.envavec de vrais secrets.
Étape 3 : Déployer
Utilisez la première option disponible, dans cet ordre :
- Le serveur MCP Sevalla (
https://mcp.sevalla.com/mcp). Il propose deux outils :searchtrouve les endpoints API dans la spécification, etexecuteexécute du JavaScript qui appellesevalla.request({ method, path, body }). Utilisez les chemins API dans le tableau ci-dessous. - La CLI
sevalla, avec--jsonsur chaque commande pour pouvoir lire les identifiants. Installez avecnpm install -g @sevalla/cli(Node 22+) oubrew install sevalla-hosting/tap/sevalla. Connectez-vous avecsevalla login(autorisation de l'appareil dans le navigateur) ou définissezSEVALLA_API_TOKEN. - L'API REST à
https://api.sevalla.com/v3avec une clé API bearer.
Si aucune n'est disponible, dites à l'utilisateur comment ajouter le serveur MCP (voir les guides de démarrage rapide pour les agents de codage à https://docs.sevalla.com/quick-starts/coding-agents/overview), ou donnez-lui les étapes du tableau de bord dans references/dashboard.md. Seule la première connexion nécessite l'utilisateur.
Application Hosting
| # | Action | API (MCP execute ou REST) | CLI |
|---|---|---|---|
| 1 | Choisir un emplacement | GET /resources/clusters | sevalla resources clusters --json |
| 2 | Créer l'application | POST /applications avec display_name, cluster_id, source (privateGit pour un dépôt GitHub, GitLab ou Bitbucket connecté, publicGit pour une URL publique), git_type, repo_url, default_branch | sevalla apps create --name <nom> --cluster <id-cluster> --source privateGit --git-type github --repository https://github.com/<propriétaire>/<dépôt> --branch <branche> --json |
| 3 | Définir la stratégie de build et le chemin de build, si pas les valeurs par défaut | PATCH /applications/{id} avec build_type (nixpacks, railpack, dockerfile, pack) et build_path | sevalla apps update <id-app> --build-type railpack --json. La CLI n'a pas de flag pour le chemin de build : sevalla apps update <id-app> --data '{"build_path":"apps/web"}' --json |
| 4 | Ajouter des variables d'environnement | POST /applications/{id}/env-vars avec key et value. is_runtime et is_buildtime sont tous deux true par défaut, ce qui est correct pour NEXT_PUBLIC_*. | sevalla apps env-vars create <id-app> --key <CLÉ> --value "<valeur>" (disponible au moment du build et au moment de l'exécution) |
| 5 | Connecter une base de données, le cas échéant | Voir references/data-services.md | |
| 6 | Déployer | POST /applications/{id}/deployments. La création d'une application ne démarre pas un déploiement. | sevalla apps deployments trigger <id-app> --branch <branche> --json |
Si l'étape 2 échoue avec une erreur HTTP 500 pour un dépôt privateGit, la cause la plus probable est que l'application GitHub de Sevalla ne peut pas voir le dépôt. L'API ne le dit pas. Vérifiez avec sevalla git providers --json: settings_url ouvre l'installation de l'application GitHub. L'utilisateur (ou un propriétaire de l'organisation GitHub) doit donner à l'application l'accès au dépôt. Un dépôt dans une organisation dont l'utilisateur n'est pas propriétaire nécessite qu'un propriétaire l'ajoute. Réessayez ensuite l'étape 2.
Une nouvelle application a le déploiement automatique désactivé. Si l'utilisateur souhaite un déploiement à chaque push, définissez auto_deploy: true avec PATCH /applications/{id} (fonctionne uniquement pour privateGit).
Pour Static Site Hosting, suivez plutôt references/static-hosting.md. La création d'un site statique démarre automatiquement son premier déploiement.
Étape 4 : Vérifier
Un déploiement qui a démarré n'est pas un déploiement qui fonctionne. Faites tout cela avant de dire à l'utilisateur que c'est terminé :
- Attendez la fin du build. Interrogez
GET /applications/{id}/deployments/{deployment_id}(CLI :sevalla apps deployments get <id-déploiement> --app-id <id-app> --json) toutes les 15 à 30 secondes jusqu'à ce que lestatussoitsuccessoufailed. Les autres valeurs sontwaiting,inProgress,cancelledetskipped. - S'il a échoué, lisez le journal de build.
GET /applications/{id}/deployments/{deployment_id}/logs(CLI :sevalla apps deployments logs ...). Faites correspondre l'erreur au tableau de dépannage dansreferences/app-hosting.md, corrigez la cause, et déployez à nouveau. Ne devinez pas deux fois sans lire le journal. Jugez du succès par lestatusdu déploiement, pas par la sévérité du journal : une sortie de build normale écrite sur stderr apparaît avec"severity": "error"dans un build réussi. - Trouvez l'URL en direct.
GET /applications/{id}/domains(CLI :sevalla apps domains list --app-id <id-app> --json). Chaque application reçoit un domaine*.sevalla.appgratuit après son premier déploiement réussi. - Interrogez l'URL. Attendez-vous à une réponse HTTP 200 sur
/et sur un gestionnaire de route, si l'application en a un. Une erreur 502 ou un délai d'attente signifie généralement que le serveur n'écoute pas sur$PORTet0.0.0.0. - Si l'application répond avec une erreur, lisez le journal d'exécution.
GET /applications/{id}/runtime-logs(CLI :sevalla apps logs runtime <id-app>).
Ensuite, dites à l'utilisateur l'URL en direct, ce que vous avez configuré, et tout ce qu'il doit faire lui-même (par exemple, ajouter des enregistrements DNS pour un domaine personnalisé).
Étape 5 : Prochaines étapes optionnelles
- Domaine personnalisé :
sevalla apps domains add <id-app> --name example.com. L'utilisateur doit ajouter les enregistrements DNS que Sevalla renvoie. SSL est inclus. - Mise à l'échelle :
sevalla apps processes update <id-process> --app-id <id-app> --instances <n>. Avec plus d'une instance, n'utilisez pas de disque persistant pour l'état partagé. Utilisez le stockage d'objets ou une base de données. - Rollback :
sevalla apps deployments rollback <id-app> --deployment-id <id>.
Fichiers de référence
references/app-hosting.md: scripts depackage.json, notes sur Nixpacks et Railpack, Dockerfile recommandé, configuration des monorepos, tableau de dépannage.references/static-hosting.md: configuration et déploiement de l'export statique pour Static Site Hosting.references/data-services.md: bases de données, stockage d'objets et disques persistants, et comment leurs détails de connexion parviennent à l'application.references/dashboard.md: les mêmes étapes dans le tableau de bord Sevalla, pour une personne.