Aller au contenu principal

Mettre son projet en ligne : nom de domaine, VPS, HTTPS, déploiement

Un projet qui tourne sur localhost n'existe pour personne d'autre. Cet article décrit la chaîne complète entre le code et l'URL publique : acheter un nom de domaine, le faire pointer vers un serveur, y lancer l'application comme un service, obtenir un certificat HTTPS et redéployer sans casser. Avec les commandes, les fichiers de configuration et les pièges.

Projets & portfolio ·
Adel LATIBI
Adel LATIBI

Le Briefing Dev - les ressources et actus de la semaine, droit dans ta boîte chaque vendredi gratuitement.

En vous inscrivant, vous acceptez de recevoir notre newsletter. Désinscription possible à tout moment.

Des milliers de tutoriels apprennent React, Django ou Symfony. Une petite minorité va jusqu'à l'URL publique. Le dernier chapitre s'arrête sur un serveur de développement qui écoute le port 3000, avec une phrase du type « le déploiement fera l'objet d'un prochain article ». Ce prochain article n'arrive jamais.

Résultat : beaucoup de gens savent écrire une application web complète et n'ont jamais vu la leur répondre à une adresse que quelqu'un d'autre peut taper. La mise en ligne est rangée du côté « ops », comme si elle demandait un métier séparé. Elle repose sur quatre briques, dont trois se configurent en une soirée, et la quatrième une fois pour toutes.

Voici ces quatre briques, dans l'ordre où elles s'assemblent, avec le stack précis utilisé pour les exemples : Ubuntu Server 26.04 LTS, Caddy 2.11 et Node.js 24 LTS, état d'août 2026.

Le trou entre « ça marche » et « c'est en ligne »

La situation type est facile à décrire. Une application tourne en local. Elle répond sur http://localhost:3000, la base de données est peuplée, les tests passent. Le code est sur GitHub. Et au moment de la mettre sur un CV, dans un portfolio ou dans un mail à un client, il n'y a rien à donner d'autre qu'un lien vers un dépôt.

Un lien GitHub demande à l'interlocuteur de cloner, d'installer des dépendances, de créer une base et de lancer un serveur avant de voir quoi que ce soit. Personne ne le fait. Une URL cliquable qui affiche l'écran d'accueil en deux secondes change la nature de la conversation, et c'est précisément ce que décrit l'article sur la construction d'un portfolio quand on n'a pas encore de client.

Le blocage tient à ce que les quatre morceaux sont documentés séparément. Le registrar explique comment acheter un domaine sans parler de serveur. L'hébergeur explique comment créer une machine sans parler de DNS. La documentation TLS parle de certificats sans dire quel processus doit écouter derrière. Chaque page est correcte, aucune ne montre l'assemblage.

Le principe : une requête, cinq étapes

Tout devient plus simple une fois qu'on suit une requête du navigateur jusqu'au code. Il y a cinq étapes, et chaque brique à installer correspond à l'une d'elles.

Navigateur monprojet.fr DNS nom vers IP Pare-feu 80 et 443 ouverts Caddy TLS + proxy Ton code 127.0.0.1:3000 registrar VPS Let's Encrypt systemd Chaque case correspond à une chose à configurer une fois. Le service en dessous est celui qui s'en occupe.
Trajet d'une requête HTTPS vers une application auto-hébergée sur un VPS, avec l'outil responsable de chaque étape.

Le nom de domaine ne fait qu'une chose : il traduit un nom lisible en adresse IP. C'est une ligne dans un annuaire mondial. Il n'héberge rien, ne stocke rien et ne sait pas ce que fait ton application.

Le VPS est une machine allumée en permanence, avec une adresse IP publique fixe. Serveur privé virtuel : une part d'une machine physique, avec son propre système, sa propre RAM et ses propres processus.

Le serveur web reçoit sur les ports 80 et 443, présente le certificat, puis transmet la requête à ton application sur une adresse locale. Ce rôle d'intermédiaire s'appelle un reverse proxy. Si les numéros de port et les codes de statut restent flous, l'article sur ce qui se passe entre le navigateur et le serveur couvre cette partie en détail.

Le certificat prouve le lien entre le nom et le serveur. Une autorité vérifie que la machine qui répond à monprojet.fr contrôle bien ce nom, puis signe un certificat que le navigateur accepte. Let's Encrypt fait ça gratuitement et automatiquement.

L'ordre compte. Le certificat s'obtient en prouvant le contrôle du domaine, ce qui suppose que le DNS pointe déjà vers le bon serveur. Acheter le domaine et poser les enregistrements en premier évite une série d'échecs qui ont un coût réel, détaillé plus bas.

Étape 1 : le domaine et les enregistrements DNS

Un domaine se loue à l'année auprès d'un bureau d'enregistrement. Pour un projet personnel, l'extension importe peu tant qu'elle est lisible et courte. Un point à connaître pour le .fr : selon les règles rappelées par service-public.fr, le titulaire doit être établi dans un État membre de l'Union européenne, en Norvège, en Islande, au Liechtenstein ou en Suisse, et cette condition vaut pendant toute la durée de détention.

Une fois le domaine acheté, tout se joue dans sa zone DNS. Deux types d'enregistrements suffisent pour démarrer, avec l'adresse IP de ton serveur en valeur :

Type   Nom    Valeur              TTL
A      @      203.0.113.42        3600
A      www    203.0.113.42        3600
AAAA   @      2001:db8::42        3600

Le @ désigne le domaine nu, A pointe vers une adresse IPv4 et AAAA vers une IPv6. Le TTL indique combien de secondes les résolveurs ont le droit de garder la réponse en cache : une valeur basse pendant la mise en place, quitte à la remonter ensuite, évite d'attendre une heure après chaque correction.

Pour vérifier que la zone est bien publiée, dig +short monprojet.fr depuis n'importe quelle machine doit renvoyer l'IP du serveur. Tant que cette commande ne répond rien, inutile de passer à la suite.

Étape 2 : le VPS, et les dix minutes qui le rendent habitable

Hetzner, OVHcloud, Scaleway, DigitalOcean, Infomaniak : les offres se ressemblent beaucoup sur l'entrée de gamme, autour de 2 vCPU et 4 Go de RAM, ce qui tient largement une application avec sa base de données et quelques centaines de visiteurs par jour. Les tarifs bougent plus souvent qu'on ne le croit, Hetzner ayant par exemple publié un ajustement entré en vigueur le 15 juin 2026 : regarde la grille du jour plutôt qu'un chiffre lu dans un tutoriel de l'an dernier.

À la création, choisis une image Ubuntu Server 26.04 LTS, maintenue jusqu'en avril 2031, et colle ta clé publique SSH dans le formulaire. Si tu n'en as pas encore :

ssh-keygen -t ed25519 -C "deploy@monprojet"
cat ~/.ssh/id_ed25519.pub

Première connexion, création d'un utilisateur non privilégié, transfert de la clé :

ssh root@203.0.113.42
 
adduser deploy
usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

Ensuite, un fichier déposé dans /etc/ssh/sshd_config.d/ coupe l'accès par mot de passe et la connexion directe en root :

# /etc/ssh/sshd_config.d/99-durcissement.conf
PasswordAuthentication no
PermitRootLogin no

Garde ta session root ouverte, ouvre un second terminal, vérifie que ssh deploy@203.0.113.42 fonctionne après systemctl restart ssh, et seulement là ferme la première. Cette précaution évite le classique enfermement dehors, qui oblige à passer par la console de secours de l'hébergeur.

Reste le pare-feu :

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443
sudo ufw enable
sudo ufw status

La ligne 443 sans suffixe ouvre le TCP et l'UDP. Ce détail a son importance : Caddy sert HTTP/3 par défaut depuis la version 2.6, et HTTP/3 passe par UDP. Une règle limitée au TCP fait silencieusement retomber tous les clients sur HTTP/2, sans message d'erreur nulle part. Le port de ton application, lui, n'apparaît pas dans cette liste, et c'est voulu.

Étape 3 : faire tourner l'application comme un service

Lancer npm start dans une session SSH marche jusqu'à la fermeture du terminal. Un tmux repousse le problème jusqu'au premier redémarrage de la machine. La réponse propre sur une distribution moderne s'appelle systemd, le gestionnaire de services déjà présent sur Ubuntu : il démarre le processus au boot, le relance s'il plante, et centralise ses logs.

Le code va dans /srv/monprojet, les secrets dans un fichier séparé lisible du seul utilisateur de service, comme le recommande le principe de configuration par variables d'environnement des 12 facteurs :

# /etc/systemd/system/monprojet.service
[Unit]
Description=Application monprojet
After=network-online.target
Wants=network-online.target
 
[Service]
Type=exec
User=deploy
WorkingDirectory=/srv/monprojet
EnvironmentFile=/etc/monprojet.env
ExecStart=/usr/bin/node /srv/monprojet/server.js
Restart=on-failure
RestartSec=5
 
[Install]
WantedBy=multi-user.target

Puis :

sudo systemctl daemon-reload
sudo systemctl enable --now monprojet
sudo systemctl status monprojet
journalctl -u monprojet -f

Un détail qui change tout : ton application doit écouter sur 127.0.0.1:3000 et pas sur 0.0.0.0:3000. En écoutant sur 127.0.0.1, le processus n'est joignable que depuis la machine elle-même, donc uniquement par le reverse proxy. En écoutant sur 0.0.0.0, il est exposé à l'Internet entier, en clair et sans certificat, dès qu'une règle de pare-feu est mal posée.

Étape 4 : Caddy devant, HTTPS compris

Pour un premier déploiement, je conseille Caddy plutôt que le couple Nginx et Certbot. Nginx reste la référence en production et il faudra savoir le lire tôt ou tard. Mais Caddy demande une configuration de trois lignes là où l'autre en demande trente, et il obtient le certificat sans commande supplémentaire. Sur un premier projet, ça retire la moitié des occasions de se tromper.

Installation, avec les commandes du dépôt officiel :

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
  | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
  | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Le fichier /etc/caddy/Caddyfile tient en quelques lignes :

{
	email contact@monprojet.fr
}
 
monprojet.fr {
	encode zstd gzip
	reverse_proxy 127.0.0.1:3000
}
 
www.monprojet.fr {
	redir https://monprojet.fr{uri} permanent
}
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
journalctl -u caddy -f

Le fait d'écrire un nom de domaine en tête de bloc suffit à déclencher la demande de certificat auprès de Let's Encrypt, la redirection HTTP vers HTTPS et le renouvellement automatique. Les logs montrent l'échange en direct, ce qui rend le diagnostic simple quand ça coince.

Une fois cette étape franchie, une URL en https répond, avec un cadenas et aucun avertissement. C'est le moment où le projet devient montrable.

Étape 5 : déployer une nouvelle version

Reste la question qui revient dès le lendemain : comment mettre en ligne le correctif écrit ce matin. Le premier niveau est un script de quatre lignes, posé sur le serveur, que tu lances après avoir poussé sur ta branche principale.

#!/usr/bin/env bash
set -euo pipefail
 
cd /srv/monprojet
git fetch --prune
git reset --hard origin/main
npm ci --omit=dev
npm run build
sudo systemctl restart monprojet

Le set -euo pipefail en tête arrête le script à la première commande qui échoue, au lieu de redémarrer un service avec des dépendances à moitié installées. Le git reset --hard garantit que l'état du serveur correspond exactement à celui du dépôt, sans fichier modifié à la main resté en travers.

Le niveau suivant consiste à faire exécuter ce script par une action déclenchée au push, plutôt que par toi en SSH. C'est le principe d'un pipeline, détaillé dans l'article sur l'intégration et le déploiement continus, et travaillé en pratique dans la formation CI/CD avec GitHub Actions. Passer au pipeline avant d'avoir réussi un déploiement manuel complique inutilement le diagnostic : quand rien ne marche, il faut pouvoir distinguer un problème d'application d'un problème de pipeline.

Les pièges qui coûtent une soirée

Relancer la demande de certificat en boucle. Let's Encrypt tolère 5 échecs de validation par identifiant et par compte et par heure, avec un rechargement d'un échec toutes les 12 minutes. Cinq tentatives ratées parce que le DNS n'est pas encore propagé, et l'attente commence. L'environnement de test de l'autorité, disponible à une adresse dédiée, existe précisément pour ces essais.

Oublier l'enregistrement www. Un certificat couvre les noms demandés, pas leurs variantes. Sans enregistrement DNS ni bloc de configuration pour www, la moitié des visiteurs qui tapent l'adresse de mémoire tombent sur une erreur.

Commiter le fichier .env. Le dépôt part sur GitHub avec les identifiants de base de données et les clés d'API dedans. Les robots qui scannent les dépôts publics trouvent ces clés en quelques minutes, et l'article sur ce que coûte une application non sécurisée détaille la suite.

Tout faire tourner en root. Un processus applicatif n'a aucune raison d'avoir les droits d'administration de la machine. Le service tourne sous un utilisateur dédié, avec accès en écriture aux seuls dossiers dont il a besoin, dans l'esprit du principe de moindre privilège.

Ne jamais sauvegarder la base. Un VPS peut disparaître, un DROP TABLE peut partir sur la mauvaise connexion. Un dump quotidien envoyé ailleurs que sur la machine elle-même prend dix minutes à mettre en place et vaut plus que toute autre optimisation.

Laisser le renouvellement du domaine au hasard. Un domaine expiré rend le site injoignable et le certificat impossible à renouveler. Active le renouvellement automatique, et méfie-toi des courriels qui annoncent une expiration imminente avec une date que tu ne reconnais pas : c'est un grand classique du hameçonnage sur les titulaires de noms de domaine.

Déployer sans savoir lire les logs. Quand une page renvoie 502, l'information est dans journalctl -u monprojet et journalctl -u caddy, presque jamais ailleurs. La formation Linux et ligne de commande pour développeurs couvre cette lecture, et l'article sur la méthode de debug s'applique telle quelle à un serveur.

Après le premier déploiement

Une fois cette chaîne en place, elle se reproduit en une demi-heure pour le projet suivant, et l'essentiel du travail se déplace vers ce qui vient après : surveiller que le site répond, gérer les montées de version du système, séparer un environnement de test de la production. La suite logique passe par les conteneurs et l'automatisation, sujets traités dans la roadmap DevOps et dans les formations DevOps et déploiement du catalogue.

Il reste que la première fois demande une soirée, pas un semestre. Le reste, c'est de la répétition.

Questions fréquentes

Un VPS est-il obligatoire, ou une plateforme gérée suffit-elle ?

Une plateforme comme Vercel, Netlify, Railway ou Render met un projet en ligne en quelques clics, avec HTTPS et déploiement au push inclus. Pour publier vite, c'est le chemin le plus court, et il n'y a aucune honte à le prendre. Le VPS apporte deux choses que ces plateformes n'apportent pas : la compréhension de ce qui se passe sous le capot, et l'indépendance vis-à-vis d'un modèle tarifaire qui peut changer. Beaucoup de gens font les deux, un projet vitrine sur plateforme gérée et un serveur perso pour apprendre.

Faut-il utiliser Docker pour un premier déploiement ?

Mon avis : pas pour le premier. Ajouter la conteneurisation en même temps que le DNS, le pare-feu, le reverse proxy et les certificats revient à débugger quatre inconnues simultanément. Une fois qu'un déploiement classique a fonctionné, Docker devient une amélioration lisible plutôt qu'une couche de mystère, et l'article sur Docker pour les développeurs explique ce qu'il apporte à ce moment-là.

Combien de temps met un changement DNS à être visible ?

Pour un domaine neuf, souvent quelques minutes. Pour une modification, le délai dépend du TTL de l'ancien enregistrement, puisque les résolveurs ont le droit de conserver la réponse en cache pendant cette durée. Un TTL à 3600 signifie jusqu'à une heure d'attente. Baisser le TTL quelques heures avant un changement prévu réduit d'autant la fenêtre d'incertitude.

Que faire quand le site renvoie 502 Bad Gateway ?

Ce code signifie que le reverse proxy a bien reçu la requête mais n'a obtenu aucune réponse valide de l'application derrière. Trois vérifications couvrent la quasi-totalité des cas : le service applicatif tourne-t-il (systemctl status), écoute-t-il sur le port attendu (ss -tlnp), et l'adresse du reverse_proxy correspond-elle à ce port. Le 502 vient presque toujours d'une application arrêtée au démarrage, avec la cause exacte dans ses propres logs.

Peut-on héberger plusieurs projets sur le même VPS ?

Oui, et c'est l'intérêt principal du reverse proxy. Chaque projet tourne sur son propre port local avec son propre service systemd, et chaque domaine reçoit son bloc dans le Caddyfile. La machine d'entrée de gamme encaisse sans difficulté trois ou quatre petites applications. La limite arrive côté mémoire bien avant le processeur, surtout si chaque projet embarque sa propre base de données.

Faut-il savoir déployer pour décrocher un poste de développeur junior ?

Personne n'attend d'un junior qu'il administre une infrastructure. En revanche, un candidat qui présente un projet en ligne, sait expliquer où tourne son code et pourquoi il y a un certificat démontre une compréhension du cycle complet que beaucoup de profils n'ont pas. En entretien technique, la question « comment tu l'as mis en ligne » sépare rapidement les projets terminés des projets de tutoriel.
Crédits images : rawpixel-com sur Magnific Tous les crédits

Articles similaires

20 projets frontend originaux, loin des todo lists et des calculatrices

20 projets frontend originaux, loin des todo lists et des calculatrices

Les listes de projets frontend proposent les mêmes exercices d'une langue à l'autre. Cet article en propose vingt autres, sans serveur, faisables en un week-end ou deux : simulations à états, interfaces à forte interaction, données rendues lisibles, algorithmes visibles à l'écran, outils réutilisables. Avec les deux critères de sélection et les pièges à éviter.

19/08/2026

20 idées de projets backend pour débutants : construisez plutôt que regarder

20 idées de projets backend pour débutants : construisez plutôt que regarder

Regarder des tutoriels, c'est rassurant. Construire quelque chose seul, c'est là que ça devient sérieux. Si vous débutez en backend et que vous cherchez des projets concrets pour progresser vraiment, cette liste est faite pour vous. Vingt idées classées par niveau, avec pour chacune les technologies conseillées, ce que vous allez apprendre, et les pièges à éviter. Du premier CRUD jusqu'à votre première file d'attente Redis, de quoi construire un portfolio solide et des compétences qui valent quelque chose sur le marché

05/04/2026

JWT ou session : révocation, refresh tokens et stockage du token

JWT ou session : révocation, refresh tokens et stockage du token

Deux modèles d'authentification, deux endroits où vit l'état de connexion. Cet article compare le JWT et la session serveur sur les points qui coincent en production : la révocation immédiate, le rôle exact des refresh tokens, les situations où le JWT complique le travail, et l'endroit où ranger le token côté navigateur selon l'OWASP et la RFC 10017.

26/08/2026

Vous êtes expert ?

Partagez votre expertise sur notre blog

Tutoriel, retour d'expérience, analyse - publiez un article invité et gagnez en visibilité.

Écrire pour nous