Déployer une application Node.js (Express)
Ce guide part d'une application Express qui fonctionne sur votre poste et la publie en HTTPS. Deux voies chez HebergHub :
- l'hébergement applicatif : vous indiquez un dépôt Git dans votre espace client, l'application est construite et publiée sur
nom.apps.heberghub.fravec un certificat HTTPS automatique ; - un VPS : vous installez vous-même Node.js et le service, et votre site est publié sur
nom.vps.heberghub.fr.
Préparer l'application
Écouter sur le bon port et la bonne adresse
Sur un serveur, l'application doit écouter sur toutes les interfaces (0.0.0.0), pas seulement sur localhost, et lire son port dans une variable d'environnement :
// src/server.js
const express = require('express');
const app = express();
const port = Number(process.env.PORT) || 3000;
// Le HTTPS est géré en amont : faire confiance au relais pour req.secure et req.ip
app.set('trust proxy', 1);
app.get('/', (req, res) => res.send('Bonjour depuis HebergHub'));
app.get('/sante', (req, res) => res.json({ ok: true }));
app.listen(port, '0.0.0.0', () => {
console.log(`Application à l'écoute sur le port ${port}`);
});Le certificat HTTPS est géré avant votre application, qui reçoit du HTTP simple. trust proxy lui permet de savoir que la requête d'origine était en HTTPS (en-tête X-Forwarded-Proto), ce qui compte pour les cookies secure et les redirections.
package.json
{
"name": "mon-app",
"version": "1.0.0",
"main": "src/server.js",
"scripts": {
"start": "node src/server.js"
},
"engines": {
"node": ">=20"
},
"dependencies": {
"express": "^4.21.0"
}
}- Le script
startest ce qui est lancé en production. - Validez
package-lock.jsondans Git : le serveur installera exactement les mêmes versions. - Si votre projet a une étape de construction (TypeScript, front-end), déclarez-la dans un script
build.
Les secrets hors du dépôt
Mots de passe de base, clés d'API et secrets de session se lisent dans process.env, jamais dans le code. Ajoutez node_modules/ et .env au .gitignore, et versionnez un .env.example sans valeur. Le détail est dans Variables d'environnement et jetons.
Option 1 : l'hébergement applicatif
- Commandez la formule Application Starter (1,99 € TTC par mois, jusqu'à 2 Go de RAM et 2 vCPU). Le seul champ à remplir est le nom du projet.
- Dans votre espace client, ouvrez le service et cliquez sur « Nouvelle application ». Renseignez :
- le nom de l'application et le sous-domaine souhaité en
.apps.heberghub.fr; - la source : Dépôt public (adresse https) ou Mes dépôts GitHub (privés), et la branche ;
- le type de build : Automatique (détecté dans le dépôt) reconnaît un projet Node.js grâce à
package.json; - le port de l'application : indiquez celui de votre code (3000 dans l'exemple) si la détection ne le trouve pas ;
- les variables d'environnement, une par ligne au format
NOM=valeur(NODE_ENV=production,DATABASE_URL=…) ; - dans Options avancées, les commandes d'installation, de build et de démarrage si vous voulez les imposer (
npm ci,npm run build,npm start).
- le nom de l'application et le sous-domaine souhaité en
- Cliquez sur « Déployer ». Le premier déploiement prend 5 à 15 minutes ; les suivants réutilisent l'environnement mis en cache.
- Cliquez sur « Journaux » : la ligne
Application à l'écoute sur le port …confirme le démarrage. Ouvrez ensuitehttps://nom.apps.heberghub.fr.
Si l'application plante, elle est relancée automatiquement. Les boutons « Redémarrer », « Arrêter » et « Redéployer » sont sur la fiche de l'application, et un encadré « Pourquoi ça a échoué » résume la cause d'un déploiement raté.
Avec un Dockerfile
Pour maîtriser l'image, choisissez le type de build Dockerfile et placez ce fichier à la racine du dépôt :
FROM node:22-slim
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["npm", "start"]Si votre projet a une étape build, installez toutes les dépendances (npm ci), lancez npm run build, puis retirez les dépendances de développement (npm prune --omit=dev).
Mettre à jour
- Dépôt GitHub privé partagé avec HebergHub : chaque push sur la branche suivie redéploie l'application.
- Dépôt public : poussez, puis cliquez sur « Redéployer ».
- Variables modifiées (bouton « Variables », puis « Enregistrer ») : elles s'appliquent au prochain redéploiement.
- Si un redéploiement normal ne suffit pas, « Reconstruire à neuf » reconstruit tout sans le cache.
Base de données
Renseignez l'adresse d'une base existante dans une variable (DATABASE_URL).
Nom de domaine
L'application est publiée sur un sous-domaine en .apps.heberghub.fr, au nom de votre choix. Les domaines personnalisés ne sont pas encore proposés sur l'hébergement applicatif.
Option 2 : sur un VPS
Sur un VPS, le site publié sur nom.vps.heberghub.fr arrive en HTTP sur le port 80 du VPS ; le certificat est géré par le point d'entrée. Le plus simple : l'application écoute en local sur le port 3000, et nginx la relaie sur le port 80.
Installer Node.js et l'application
Debian 13 fournit Node.js 20 par apt (vérifié : Node.js 20.19, npm 9.2 ; l'installation de npm peut prendre plusieurs minutes).
apt install -y git nodejs npm
adduser --system --group --home /opt/mon-app app
git clone https://exemple.org/vous/mon-app.git /opt/mon-app
cd /opt/mon-app && npm ci --omit=dev
chown -R app:app /opt/mon-app
install -m 600 -o root -g root /dev/null /etc/mon-app.env
nano /etc/mon-app.env # PORT=3000, NODE_ENV=production, secrets...Le service systemd
# /etc/systemd/system/mon-app.service
[Unit]
Description=Application Express
After=network-online.target
Wants=network-online.target
[Service]
User=app
WorkingDirectory=/opt/mon-app
EnvironmentFile=/etc/mon-app.env
ExecStart=/usr/bin/node src/server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetsystemctl daemon-reload
systemctl enable --now mon-app
curl -s http://127.0.0.1:3000/santeDans ce cas, faites écouter l'application sur 127.0.0.1 plutôt que 0.0.0.0 : seul nginx doit pouvoir la joindre.
nginx en relais sur le port 80
apt install -y nginx
cat > /etc/nginx/sites-available/mon-app <<'EOF'
server {
listen 80 default_server;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
}
}
EOF
ln -sf /etc/nginx/sites-available/mon-app /etc/nginx/sites-enabled/mon-app
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginxX-Forwarded-Proto est transmis tel que le point d'entrée l'envoie (https), pour que trust proxy fonctionne côté Express.
Si un pare-feu est actif sur le VPS, le port 80 doit être ouvert (voir Configurer un pare-feu). Mise à jour : git pull, npm ci --omit=dev, puis systemctl restart mon-app.
Problèmes fréquents
| Symptôme | Cause probable |
|---|---|
| Erreur 502 ou « L'application ne répond pas » | L'application écoute sur localhost au lieu de 0.0.0.0, ou sur un autre port que celui déclaré. |
| Le déploiement échoue à l'installation | package-lock.json absent ou désynchronisé : lancez npm install en local et validez le fichier. |
Cannot find module au démarrage |
Dépendance placée dans devDependencies alors qu'elle sert en production. |
| Boucle de redirection HTTPS | trust proxy absent : Express croit recevoir du HTTP et redirige à l'infini. |
| Variable modifiée sans effet | Les variables s'appliquent au prochain redéploiement. |
Pour lire et filtrer les messages de votre application, voir Lire les journaux de son application.
Besoin d'aide ?
Ouvrez un ticket depuis votre espace client avec le nom de l'application, l'heure du problème et les dernières lignes des journaux. Ne collez jamais de secret dans un ticket.