Déployer Next.js sur un VPS : du build au HTTPS

Votre application fonctionne en local. Sur le VPS, il reste à la maintenir disponible après une déconnexion SSH, à servir ses fichiers et à faire fonctionner les formulaires derrière votre domaine. Ce guide suit ce chemin, du build de production à la vérification publique.

Les exemples visent une application Next.js avec des scripts build et start classiques, sur un Linux utilisant systemd et un reverse proxy Nginx déjà installé. Adaptez les chemins, le compte de service et le domaine à votre environnement. Un export statique et une application avec rendu à la demande ont des besoins différents.

Préparer une version identifiable

Partez d’un commit connu, avec son fichier de verrouillage et une version Node compatible avec le Next.js installé. Pour npm, npm ci réinstalle les dépendances du lockfile. Un projet pnpm ou Yarn conserve son gestionnaire et son propre mode d’installation reproductible.

Compilez dans un répertoire de release ou en CI plutôt que dans le dossier d’un serveur actif. Le build peut exécuter du code applicatif et contacter des services. Donnez-lui les variables nécessaires sans déposer de secrets dans public. Les valeurs NEXT_PUBLIC_ sont destinées au navigateur et sont intégrées au build.

Terminal
node --version
npm ci
npm run build

Démarrer le serveur de production en local

Vérifiez que le script start appelle next start. Le serveur de développement n’est pas le processus à laisser en production. L’adresse 127.0.0.1 réserve l’accès direct au serveur et au proxy local ; elle évite d’exposer inutilement le port applicatif.

Ouvrez un second terminal et contrôlez une vraie page avec curl -i http://127.0.0.1:3000/. Vérifiez son contenu et ses assets. Si vous avez choisi output: standalone, utilisez le server.js généré et son arborescence, avec les fichiers public et .next/static à leur emplacement attendu. Ce mode possède son propre point d’entrée.

Terminal
npm run start -- --hostname 127.0.0.1 --port 3000

Confier le processus à systemd

Une unité systemd permet au service de démarrer indépendamment de votre session. Voici un exemple pour un compte webapp existant et une release placée sous /srv/my-next-app. Vérifiez le chemin Node avec command -v node, puis adaptez ExecStart. Le compte doit pouvoir lire la release et écrire uniquement dans les emplacements applicatifs nécessaires.

Le fichier d’environnement contient les variables serveur, avec des permissions adaptées au compte de service. Après installation de l’unité dans votre environnement, validez sa syntaxe avec systemd-analyze verify, rechargez systemd et démarrez le service. Consultez son journal en cas d’échec. Le redémarrage automatique ne remplace pas le diagnostic d’un arrêt mémoire.

my-next-app.service
[Unit]
Description=My Next.js application
After=network.target

[Service]
Type=simple
User=webapp
WorkingDirectory=/srv/my-next-app
Environment=NODE_ENV=production
EnvironmentFile=/etc/my-next-app.env
ExecStart=/usr/bin/node /srv/my-next-app/node_modules/next/dist/bin/next start --hostname 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Acheminer le domaine vers l’application

Dans le bloc server du domaine, une location peut transmettre les requêtes à l’application locale. Le fragment ci-dessous concerne HTTP et le streaming ; intégrez-le dans la configuration existante, puis vérifiez celle-ci avec nginx -t avant un rechargement. Il ne constitue pas une configuration TLS complète.

Le domaine doit pointer vers le VPS et disposer d’un certificat valide, avec un renouvellement opérationnel. Le proxy doit préserver l’hôte et le protocole vus par l’application. Commencez sans cache partagé sur les réponses dynamiques : les pages privées, les cookies et les variantes de navigation demandent une politique explicite. Si l’application utilise WebSocket, ajoutez séparément la gestion des en-têtes Upgrade adaptée à Nginx.

nginx.conf
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;
}

Vérifier le site depuis son URL publique

Un HTTP 200 sur la page d’accueil ne vérifie pas toute l’application. Parcourez une route dynamique, une page inexistante, une connexion, une déconnexion et un formulaire. Contrôlez les redirections, les cookies sécurisés, les images et la navigation dans un navigateur.

Testez aussi une page avec streaming. Si le contenu arrive d’un seul coup derrière le domaine alors qu’il arrive progressivement en local, examinez le buffering de chaque intermédiaire. Avant de basculer le trafic, conservez la release précédente et sa configuration. Le retour au code précédent doit rester compatible avec les éventuelles migrations de données.

Dimensionner et faire évoluer le déploiement

Mesurez la mémoire au repos, sous trafic et pendant un déploiement. Deux versions peuvent cohabiter quelques instants ; un build sur le VPS ajoute son propre pic. La base de données et le proxy font partie du budget total.

Si vous souhaitez comparer PRNext, gardez la référence Next.js disponible et construisez un candidat dans un autre répertoire. L’essai doit couvrir les fonctionnalités et les performances de votre application avant tout changement de moteur.

Dimensionner la RAM d’un VPS pour Next.js

Vérifier la compatibilité PRNext avant migration

Sources et lectures complémentaires

Retour au blog