Guide de déploiement

Déployer une application Nuxt sur un VPS

Déployer sur un VPS Cloud →

Tutoriel

Déployer une application Nuxt sur un VPS

Développement7 min de lecture7 étapes

Nuxt 3 et son moteur Nitro produisent un artefact Node.js autonome, parfaitement adapté à l'autohébergement sur VPS. Cette approche vous libère des quotas de fonctions cloud et vous donne le contrôle total sur le cache, les en-têtes HTTP et les stratégies de rendu page par page. Ce guide couvre l'installation complète : configuration du projet, build, supervision avec PM2, reverse proxy Nginx et HTTPS, jusqu'au dépannage des erreurs qui bloquent en production.

Sommaire· Pourquoi self-héberger Nuxt sur un VPS ?1/8
  1. 01Pourquoi self-héberger Nuxt sur un VPS ?
  2. 02Bénéfices concrets d'un Nuxt autohébergé
  3. 03Prérequis matériels et logiciels
  4. 04Déployer Nuxt étape par étape
  5. 05Optimiser le rendu avec routeRules
  6. 06Nitro server vs Docker vs Vercel/Netlify pour héberger Nuxt
  7. 07Dépannage : erreurs courantes en production
  8. 08Supervision et métriques avec PM2

Pourquoi self-héberger Nuxt sur un VPS ?

Avec Nitro, Nuxt 3 génère un build portable (preset: node-server) qui démarre comme un simple serveur Node écoutant sur un port. Cette portabilité est idéale pour un VPS : vous bénéficiez du rendu côté serveur, des routes server/api et du cache de route sans dépendre d'un runtime edge propriétaire.

L'autohébergement supprime les quotas de fonctions et vous laisse régler la mise en cache, la compression et le nombre d'instances Node. Pour une application Vue 3 en production avec authentification, appels API serveur et SEO soigné, le VPS offre la stabilité d'un serveur persistant et un coût fixe, sans surprise de facturation à l'invocation.

Bénéfices concrets d'un Nuxt autohébergé

  • Routes serveur server/api sans facturation par appel.
  • SSR et hydratation Vue 3 servis depuis un serveur Node persistant et stable.
  • Build Nitro portable (node-server) facile à conteneuriser et à reproduire.
  • Cache de route et règles routeRules (SSR, SSG, ISR, SWR) maîtrisés côté serveur.
  • Mutualisation de plusieurs apps Nuxt sur un même VPS derrière Nginx.
  • Variables d'environnement runtime (runtimeConfig) gérées en clair sur votre serveur.
  • Contrôle total sur les en-têtes HTTP (CSP, HSTS, cache-control) via le middleware Nitro.

Prérequis matériels et logiciels

Comme pour tout framework moderne, le build Nuxt consomme de la mémoire : visez 2 Go de RAM minimum (le build peut être réalisé en CI si votre VPS est plus modeste). Au runtime, 1 vCPU et 1 Go suffisent pour le serveur Nitro sous charge légère ; montez à 2 vCPU / 2 Go pour des applications avec de nombreuses routes server/api simultanées.

Installez Node.js 20 LTS via nvm ou une image node:20-alpine, ainsi que PM2 pour la supervision de processus. Configurez nitro: { preset: 'node-server' } dans nuxt.config.ts. Un domaine pointé vers votre VPS est requis pour le certificat TLS. Ubuntu 22.04 ou 24.04 LTS reste la base recommandée.

Déployer Nuxt étape par étape

  1. Configurer le projet pour Node

    Définissez le preset Nitro dans nuxt.config.ts :

    export default defineNuxtConfig({
      nitro: { preset: 'node-server' }
    })

    Déclarez vos secrets dans runtimeConfig côté serveur uniquement — jamais dans runtimeConfig.public. Sur le VPS, installez Node.js 20 LTS via nvm install 20 && nvm use 20 && nvm alias default 20, puis PM2 globalement : npm install -g pm2.

  2. Builder l'application

    Clonez le dépôt et installez les dépendances :

    git clone https://git.votredomaine.com/votre-org/votre-app.git /srv/nuxt-app
    cd /srv/nuxt-app
    npm ci
    npm run build

    Nitro produit un dossier .output autonome contenant server/index.mjs et les assets statiques dans .output/public. Ce dossier est tout ce dont le VPS a besoin pour servir l'application en production — vous pouvez aussi l'assembler en CI et le transférer par rsync pour éviter le build sur le serveur.

  3. Créer le fichier d'environnement

    Créez /srv/nuxt-app/.env avec vos variables runtime. Toutes les variables préfixées NUXT_ écrasent les clés correspondantes de runtimeConfig au démarrage :

    NUXT_MY_SECRET_KEY=valeur-en-prod
    NITRO_HOST=0.0.0.0
    NITRO_PORT=3000

    Ne commitez jamais ce fichier. Assurez-vous qu'il appartient à l'utilisateur qui fait tourner PM2 et qu'il est lisible uniquement par cet utilisateur (chmod 600).

  4. Lancer le serveur Nitro avec PM2

    Démarrez l'application et configurez le démarrage automatique :

    pm2 start /srv/nuxt-app/.output/server/index.mjs \
      --name nuxt-app \
      --env-file /srv/nuxt-app/.env
    pm2 save
    pm2 startup

    La commande pm2 startup affiche une ligne à copier-coller pour créer le service systemd. Exécutez-la avec les droits administrateur. Vérifiez que l'application est bien en ligne : pm2 status doit afficher l'état online.

  5. Configurer Nginx en reverse proxy

    Créez /etc/nginx/sites-available/nuxt-app :

    server {
        listen 80;
        server_name votredomaine.com www.votredomaine.com;
    
        # Assets hashés : cache long, servis directement
        location /_nuxt/ {
            root /srv/nuxt-app/.output/public;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    
        # Fichiers statiques publics
        location /favicon.ico {
            root /srv/nuxt-app/.output/public;
        }
    
        # Tout le reste → Nitro
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_cache_bypass $http_upgrade;
        }
    }

    Activez le site et testez la configuration : ln -s /etc/nginx/sites-available/nuxt-app /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx.

  6. Activer le HTTPS avec Let's Encrypt

    Installez Certbot et le plugin Nginx, puis générez le certificat :

    apt install certbot python3-certbot-nginx
    certbot --nginx -d votredomaine.com -d www.votredomaine.com

    Certbot modifie automatiquement le bloc Nginx pour écouter sur le port 443 et forcer la redirection HTTP → HTTPS. Vérifiez que X-Forwarded-Proto est bien transmis à Nitro — sans cela, useRequestHeaders() côté serveur et les redirections basées sur le protocole peuvent se tromper. Le renouvellement automatique est géré par le timer systemd de Certbot, vérifiable avec systemctl status certbot.timer.

  7. Mettre à jour sans interruption de service

    Pour une mise à jour, le rechargement PM2 (pas le redémarrage) garantit la continuité :

    cd /srv/nuxt-app
    git pull
    npm ci
    npm run build
    pm2 reload nuxt-app

    PM2 lance la nouvelle version, attend qu'elle réponde, puis coupe l'ancienne : zéro downtime. Pour un rollback, revenez sur le commit précédent, rebuil et rechargez. Si le build se fait en CI, transférez uniquement le dossier .output par rsync et rechargez sans reconstruire sur le serveur.

Optimiser le rendu avec routeRules

L'une des forces de Nuxt sur VPS est la granularité des stratégies de rendu page par page, sans changer d'infrastructure. Dans nuxt.config.ts, les routeRules permettent de mélanger SSR, SSG, ISR et SWR sur un seul déploiement Nitro.

Les pages statiques (blog, mentions légales, landing pages) peuvent être prégénérées au build avec prerender: true : Nitro les sert depuis le disque, sans Node. Les pages semi-dynamiques (listes de produits, tableaux de bord publics) profitent de swr: 60 pour un cache d'une minute invalidé en arrière-plan. Le SSR complet reste réservé aux pages personnalisées qui dépendent de la session ou du profil utilisateur.

Cette approche réduit la charge sur Node sans nécessiter un CDN payant ou un layer de cache externe — votre Nginx met en cache ce que Nitro prégénère.

Nitro server vs Docker vs Vercel/Netlify pour héberger Nuxt

Faites défiler le tableau

ApprocheAvantagesContraintes
Nitro `node-server` + PM2Simple, léger, rechargement sans downtime, coût fixe VPSSupervision à gérer, un seul serveur sans haute dispo native
Docker sur VPSIsolation, reproductibilité, rollback par image, compose multi-appsImage à bâtir et stocker, mémoire supplémentaire par conteneur
Vercel / NetlifyZéro configuration, edge CDN mondial, preview par PRQuotas de fonctions, coût variable, pas de contrôle sur l'infra
Kamal (déploiement zero-downtime)Orchestre Docker + proxy Traefik, git push suffitRuby requis, config initiale plus longue, adapté aux équipes

Dépannage : erreurs courantes en production

Error: listen EADDRINUSE: address already in use :::3000
Un processus tient déjà le port 3000. Identifiez-le avec ss -tlnp | grep 3000 et arrêtez l'instance PM2 orpheline : pm2 delete nuxt-app suivi d'un redémarrage propre. Évitez de lancer plusieurs instances sans load balancer — configurez plutôt le cluster_mode de PM2.

502 Bad Gateway dans Nginx
Nitro n'est pas démarré ou écoute sur le mauvais port. Vérifiez pm2 status et consultez les logs : pm2 logs nuxt-app --lines 50. Vérifiez aussi que la directive proxy_pass dans Nginx pointe bien sur http://127.0.0.1:3000 (et non localhost qui peut résoudre en IPv6 si le process écoute uniquement en IPv4).

useRuntimeConfig() retourne undefined côté serveur
Les variables NUXT_* ne sont lues qu'au démarrage du processus Nitro. Si vous modifiez .env après le lancement, rechargez : pm2 reload nuxt-app. Assurez-vous d'utiliser --env-file au démarrage et non d'exporter les variables dans le shell courant.

Les routes server/api répondent 404 en production
Vérifiez que votre build inclut bien le dossier server/ dans .output. Un nitro.preset mal configuré (par exemple static au lieu de node-server) génère un site statique sans serveur. Reconstruisez avec npm run build après avoir vérifié nuxt.config.ts.

X-Forwarded-Proto ignoré, redirections en boucle
Si Nuxt redirige HTTP → HTTPS en boucle, c'est que le middleware de redirection voit http malgré le HTTPS côté client. Assurez-vous que Nginx transmet bien proxy_set_header X-Forwarded-Proto $scheme et que votre nuxt.config.ts ne force pas la redirection HTTPS en doublon avec Certbot.

Supervision et métriques avec PM2

Au-delà du simple pm2 status, PM2 expose un tableau de bord temps réel avec pm2 monit : CPU, mémoire, relances et logs des processus. Pour une application Nuxt sous charge, activez le mode cluster pour utiliser tous les vCPU disponibles :

pm2 start .output/server/index.mjs --name nuxt-app -i max

PM2 distribue automatiquement les requêtes entre les workers. Associez PM2 à un outil comme Grafana via pm2-prometheus pour des alertes sur les redémarrages intempestifs — signe d'un bug ou d'une fuite mémoire à corriger avant qu'il n'affecte les utilisateurs.

Déployez votre Nuxt en toute autonomie

Le VPS Cloud ServOrbit fournit un template avec Node.js, PM2, Nginx et SSL automatique, idéal pour héberger vos applications Nuxt 3 avec SSR et routes serveur.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet