Mettre son site en ligne : hébergement, domaine, FTP (guide 2026)
Votre page s'affiche bien sur votre ordinateur. Pour qu'un ami l'ouvre depuis son téléphone, il faut réunir trois choses : un serveur allumé en permanence qui garde vos fichiers, un nom facile à retenir, et un annuaire qui relie ce nom à l'adresse du serveur. Il reste ensuite à y envoyer vos fichiers, de préférence sans y laisser votre mot de passe en clair.
Ce guide part d'un site minimal en HTML et CSS. J'ai rejoué chaque étape le 28 octobre 2026 et je cite les sorties telles qu'elles sont apparues. Si le trajet entre un navigateur et un serveur vous paraît encore flou, commencez par comment fonctionne un site web.
Trois pièces que l'on confond souvent
L'hébergement, c'est la place que vous louez (ou qu'on vous prête) sur un serveur : un ordinateur connecté en permanence, qui répond aux navigateurs en leur envoyant vos fichiers. Le nom de domaine, comme devenezdeveloppeur.fr, est un nom que vous louez pour une durée donnée auprès d'un bureau d'enregistrement. Les deux s'achètent souvent au même endroit, mais ce sont deux contrats distincts : vous pouvez garder votre nom et changer d'hébergeur.
Le DNS fait le lien. Quand un visiteur tape votre nom, son navigateur demande d'abord à un serveur DNS l'adresse IP correspondante, puis contacte le serveur qui se trouve à cette adresse. Enfin, il vous faut un moyen d'envoyer vos fichiers sur le serveur : c'est là qu'interviennent le FTP, le SFTP ou un déploiement automatique.
Vous pouvez observer l'étape DNS vous-même avec nslookup, fourni avec Windows et macOS, et sous Linux par le paquet dnsutils ou bind-utils selon la distribution. Voici la réponse obtenue pour ce site en interrogeant le résolveur public 1.1.1.1 :
> nslookup -type=A devenezdeveloppeur.fr 1.1.1.1
Serveur : one.one.one.one
Address: 1.1.1.1
Réponse ne faisant pas autorité :
Nom : devenezdeveloppeur.fr
Address: 46.202.132.222L'enregistrement de type A associe le nom à une adresse IPv4. Interrogé directement, le serveur DNS du domaine annonce une durée de vie (TTL) de 3 600 secondes pour cet enregistrement : un résolveur peut garder la réponse en mémoire jusqu'à une heure. C'est pour cela qu'un changement de DNS ne se voit pas partout au même moment. Le délai dépend de ce TTL, pas d'une règle fixe de 24 ou 48 heures.
Quel hébergement pour un site en HTML et CSS
Un site fait uniquement de fichiers HTML, CSS, JavaScript et d'images est dit statique : le serveur n'a rien à calculer, il renvoie les fichiers tels quels. C'est le cas le plus simple à héberger, et trois familles d'offres s'y prêtent.
| Type | Ce que vous gérez | Pour qui |
|---|---|---|
| Hébergement statique (GitHub Pages et équivalents) | Vos fichiers, souvent envoyés par Git | Portfolio, projet personnel, documentation |
| Hébergement mutualisé | Vos fichiers dans un espace partagé avec d'autres clients, accès SFTP ou FTP | Site vitrine, besoin d'adresses e-mail ou de PHP |
| Serveur privé virtuel (VPS) | Tout le serveur : système, mises à jour, logiciel web, sécurité | Quand vous voulez apprendre l'administration système |
L'offre gratuite de GitHub Pages a des limites écrites dans sa documentation : un site publié ne dépasse pas 1 Go, la bande passante a une limite souple de 100 Go par mois, et le service n'est pas prévu pour faire tourner une activité commerciale en ligne. Pour un premier portfolio, c'est largement suffisant ; pour une boutique, ce n'est pas le bon outil.
Mon conseil pour débuter : un hébergement statique pour un projet personnel, un mutualisé si vous avez aussi besoin d'adresses e-mail sur votre domaine. Le VPS a de l'intérêt pour apprendre, mais vous devenez responsable de sa sécurité et de ses mises à jour.
Le nom de domaine : ce que vous louez vraiment
Un nom de domaine ne s'achète pas définitivement : vous le louez pour un an ou plus, puis vous le renouvelez. Sans renouvellement, le nom finit par redevenir disponible pour d'autres. Avant de choisir un bureau d'enregistrement, regardez donc le prix du renouvellement et pas seulement celui de la première année, qui peut être différent.
Chaque extension a ses règles. Pour le .fr, géré par l'Afnic, un particulier doit résider dans un État membre de l'Union européenne, en Suisse, en Islande, au Liechtenstein ou en Norvège ; une entreprise ou une association doit y avoir son siège ou son principal établissement.
Le cadenas du navigateur vient d'un certificat TLS, qui permet la connexion en HTTPS. Le certificat de ce site, lu le 28 octobre 2026, est émis par Let's Encrypt, valable du 9 octobre 2026 au 7 janvier 2027, soit 90 jours. Une durée aussi courte suppose un renouvellement automatique : vérifiez que votre hébergeur s'en charge, c'est ce qui évite un site qui s'affiche un matin avec une alerte de sécurité.
Pourquoi le FTP simple n'a plus sa place : l'expérience du faux serveur
Le FTP est le protocole historique pour envoyer des fichiers sur un serveur, et beaucoup de tutoriels le présentent encore. Son défaut se démontre en vingt lignes : le FTP classique envoie l'identifiant et le mot de passe en clair. Ce faux serveur, écrit en Node.js, se contente d'afficher ce que le client lui envoie, puis refuse la connexion.
// Faux serveur FTP : il affiche tout ce que le client lui envoie, puis refuse la connexion.
import net from "node:net";
const serveur = net.createServer((client) => {
client.write("220 Faux serveur FTP de test\r\n");
client.on("data", (octets) => {
for (const ligne of octets.toString().split("\r\n").filter(Boolean)) {
console.log("Reçu :", ligne);
if (ligne.startsWith("USER")) client.write("331 Mot de passe ?\r\n");
else if (ligne.startsWith("PASS")) client.end("530 Connexion refusée (test)\r\n");
}
});
});
serveur.listen(2121, "127.0.0.1", () => console.log("En écoute sur 127.0.0.1:2121"));Enregistrez-le sous faux-serveur-ftp.mjs, lancez node faux-serveur-ftp.mjs, puis connectez-vous depuis un second terminal avec curl, comme le ferait n'importe quel logiciel FTP. Voici les lignes du dialogue extraites de la sortie de -v, sans les lignes de progression :
> curl -v ftp://127.0.0.1:2121/ --user sam:MonMotDePasse2026
< 220 Faux serveur FTP de test
> USER sam
< 331 Mot de passe ?
> PASS MonMotDePasse2026
< 530 Connexion refusée (test)
curl: (67) Access denied: 530Côté serveur, le terminal affiche alors :
En écoute sur 127.0.0.1:2121
Reçu : USER sam
Reçu : PASS MonMotDePasse2026Le serveur a reçu le mot de passe lisible, sans avoir rien eu à déchiffrer. Ici le trajet reste dans votre ordinateur. Sur un vrai réseau, ces mêmes octets traversent votre box, le Wi-Fi d'un café, puis les équipements des opérateurs : quiconque peut lire ce trafic peut lire le mot de passe de votre hébergement. Deux variantes chiffrent la connexion : le FTPS, c'est-à-dire le FTP protégé par TLS, et le SFTP, un protocole différent qui passe par SSH. Quand votre hébergeur propose le SFTP, choisissez-le.
Envoyer ses fichiers en SFTP, puis vérifier qu'ils sont servis
Pour cette démonstration, j'ai joué le rôle de l'hébergeur avec deux conteneurs Docker qui partagent un même dossier : un serveur SFTP (image atmoz/sftp:alpine) qui reçoit les fichiers, et un serveur web nginx 1.29.8 qui les distribue. Si vous voulez refaire l'essai sans louer d'hébergement, voici la mise en place, à lancer dans le dossier qui contient le dossier du site et une clé SSH de test sans phrase de passe. Créez cette clé avec ssh-keygen -t ed25519 -N "" -f cle sous macOS et Linux ; Windows PowerShell 5.1 supprime l'argument vide "", écrivez-y donc ssh-keygen -t ed25519 -N '""' -f cle. Sous Windows, lancez aussi les commandes Docker dans PowerShell, où $PWD donne le chemin du dossier courant :
docker volume create banc-www
docker run --rm -v banc-www:/w alpine:3.22 chown 1001:100 /w
docker run -d --name banc-sftp -p 127.0.0.1:2222:22 -v "$PWD/cle.pub:/home/sam/.ssh/keys/cle.pub:ro" -v banc-www:/home/sam/www atmoz/sftp:alpine sam::1001
docker run -d --name banc-web -p 127.0.0.1:8080:80 -v banc-www:/usr/share/nginx/html:ro,nocopy nginx:1.29-alpineMon site de départ tient en deux fichiers, index.html et style.css, reliés par une balise <link>. Si cette liaison vous pose encore question, voyez comment créer un fichier CSS et le lier à sa page HTML. Avant tout envoi, le serveur web répond déjà, mais avec une erreur :
> curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
403Ce code 403 signifie ici « dossier vide » : nginx ne trouve pas de fichier index.html à servir et refuse de lister le contenu du dossier. Retenez-le : sur un hébergement servi par nginx, c'est aussi ce que l'on obtient quand on a déposé ses fichiers dans le mauvais dossier. Les commandes d'envoi tiennent dans un petit fichier texte, envoi.txt :
cd www
put index.html
put style.css
ls -lLe client sftp d'OpenSSH les exécute depuis le dossier du site ; ssh -V vous dit s'il est présent et en quelle version (sous Windows, il s'agit de la fonctionnalité facultative « Client OpenSSH »). L'option -b lit les commandes dans le fichier et interdit toute question interactive. Or, à la première connexion, OpenSSH demande d'accepter la clé du serveur : sans réponse possible, l'envoi s'arrête sur Host key verification failed.. L'option StrictHostKeyChecking=accept-new enregistre la clé d'un serveur encore inconnu et refusera toujours une clé qui aurait changé. La sortie ci-dessous a été obtenue avec OpenSSH 10.3p1 ; la date affichée sera celle de votre envoi :
> sftp -P 2222 -i ../cle -o StrictHostKeyChecking=accept-new -b ../envoi.txt sam@127.0.0.1
Warning: Permanently added '[127.0.0.1]:2222' (ED25519) to the list of known hosts.
sftp> cd www
sftp> put index.html
sftp> put style.css
sftp> ls -l
-rw-r--r-- ? 1001 100 306 Oct 28 09:11 index.html
-rw-r--r-- ? 1001 100 29 Oct 28 09:11 style.cssSur un vrai hébergement, remplacez 127.0.0.1, le port 2222 et l'utilisateur par ceux de votre espace client ; sans option -P, le port est 22. Enregistrez aussi votre clé publique (cle.pub) chez l'hébergeur selon sa documentation, et adaptez le chemin de la clé privée passé à -i. Le dossier de destination change aussi d'un hébergeur à l'autre, sa documentation l'indique. Vérifiez ensuite que tout est servi (sous Windows PowerShell, tapez curl.exe au lieu de curl et NUL au lieu de /dev/null) :
> curl -s -o /dev/null -w "%{http_code} %{content_type}\n" http://127.0.0.1:8080/
200 text/html
> curl -s -o /dev/null -w "%{http_code} %{content_type}\n" http://127.0.0.1:8080/style.css
200 text/cssLe code 200 et le bon type de contenu pour chaque fichier : la page et sa feuille de style sont en ligne. Sur votre vrai domaine, la même commande avec https://votre-domaine.fr/ fait office de contrôle final.
Le piège qui n'apparaît qu'en ligne : les majuscules dans les noms de fichiers
Voici l'erreur qui fait dire « pourtant, chez moi, ça marche ». J'ai copié la page en casse.html en changeant une seule lettre : la balise appelle Style.css avec une majuscule, alors que le fichier s'appelle style.css.
<link rel="stylesheet" href="Style.css">Servie depuis Windows, avec le petit serveur intégré à Python (python -m http.server 8000, Python 3.11.2), la page s'affiche avec son titre violet : Chrome 155 calcule la couleur rgb(102, 51, 153), celle de rebeccapurple. Une fois envoyée sur le serveur nginx, qui tourne sous Linux, le même titre sort en noir, rgb(0, 0, 0), et la console du navigateur affiche l'erreur :
Failed to load resource: the server responded with a status of 404 (Not Found) @ http://127.0.0.1:8080/Style.cssLa raison tient au système de fichiers. Celui de Windows ignore par défaut la différence entre majuscules et minuscules : Style.css y trouve style.css. Celui du serveur Linux distingue les deux, et pour lui Style.css n'existe pas. La parade est simple : écrivez tous vos noms de fichiers et de dossiers en minuscules, sans espaces ni accents, et écrivez les liens exactement comme les noms.
Avant d'annoncer votre site : la vérification en cinq points
Une fois les fichiers envoyés, testez aussi votre site depuis votre téléphone en données mobiles, pour vérifier l'accès hors de votre réseau habituel. Pour contrôler les fichiers fraîchement déployés, videz d'abord le cache du navigateur. Puis passez cette liste.
- L'adresse en
https://s'ouvre sans alerte, et la version enhttp://redirige vers elle. - La page d'accueil s'appelle
index.htmlet se trouve directement dans le dossier servi, pas dans un sous-dossier. - La console du navigateur (touche F12) n'affiche aucune erreur 404 : feuille de style, images et scripts sont tous trouvés.
- Les liens entre vos pages sont relatifs (
a-propos.html) ou partent de la racine (/a-propos.html), jamais un chemin de votre disque commeC:\Users\.... - La page reste lisible sur un écran de téléphone.
Le dernier point demande souvent un peu de travail en plus. Pour l'aborder, lisez le guide du responsive design et des media queries.
Environnement des essais et références
Relevés du 28 octobre 2026 sous Windows 11 : Node.js 22.23.3, curl 8.19.0, OpenSSH 10.3p1 pour sftp, OpenSSH_for_Windows 9.5p2 pour le ssh-keygen lancé sous Windows PowerShell 5.1, Docker 29.1.3 avec les images nginx:1.29-alpine (nginx 1.29.8) et atmoz/sftp:alpine, Python 3.11.2, Chrome 155 piloté par Playwright. La réponse DNS et le certificat sont ceux du site à cette date : ils changeront avec le temps, la méthode reste la même. Les références ci-dessous ont été consultées le 28 octobre 2026.
- Limites de GitHub Pages : taille de 1 Go, bande passante souple de 100 Go par mois, pas prévu pour une boutique en ligne ni un service commercial.
- FAQ générale de l'Afnic : conditions pour enregistrer un nom en
.fr. - Documentation Microsoft sur la casse : noms insensibles à la casse par défaut sous Windows, sensibles sous Linux.
- Documentation Microsoft d'OpenSSH : la fonctionnalité facultative « Client OpenSSH » de Windows.
- RFC 959, le protocole FTP : commandes
USERetPASSet codes de réponse 220, 331 et 530. - RFC 4217 : le FTP sécurisé par TLS, appelé FTPS.
- Manuel de sftp : le mode batch de l'option
-b. - Manuel de ssh_config :
BatchModeetStrictHostKeyChecking=accept-new, qui ajoute une clé inconnue mais refuse une clé changée. - Module autoindex de nginx : listage des dossiers désactivé par défaut.