Aller au contenu

Exercice 4 — Un serveur web en une commande

Durée : ~30 min · Individuel · Théorie associée : Les commandes de base de Docker

Objectif

Un serveur web nginx tourne dans un conteneur et répond depuis le navigateur de votre poste. Vous savez le suivre, l'arrêter, le relancer, et en faire tourner plusieurs côte à côte.

Prérequis

  • L'exercice 3 terminé.
  • Votre poste de la classe, branché sur le réseau du laboratoire. Le Wi-Fi eduroam ne permet pas d'accéder au réseau 10.70.0.0/16.

Dans les adresses, remplacez # par votre numéro de serveur, comme à l'exercice 2 : 10.70.#.31 est l'adresse de votre VM docker.

Étape 1 — Lancer nginx en arrière-plan

Bash
docker run -d --name web nginx
Texte
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
...
Status: Downloaded newer image for nginx:latest
197ac5e25f5707d6480d75b442ad24eeaf82907122013aad2498c5e7fa1bf6c2

Après le téléchargement, Docker affiche une longue suite de caractères, puis vous rend la main. Cette suite est l'identifiant complet du nouveau conteneur. L'option -d l'a lancé en arrière-plan.

Étape 2 — Vérifier qu'il tourne

Bash
docker ps
Texte
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
197ac5e25f57   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    80/tcp    web

Cette fois, le conteneur apparaît dans docker ps sans -a : son statut est Up. Contrairement à hello-world, nginx est un serveur qui attend des visiteurs, et qui ne se termine jamais tout seul.

La colonne PORTS affiche 80/tcp : nginx écoute sur le port 80 du conteneur. Il n'y a pas de flèche -> : ce port n'est relié à rien dans la VM.

La console : docker run -d télécharge nginx, puis docker ps affiche web avec 80/tcp, sans flèche

Étape 3 — Essayer de le joindre

Dans le navigateur de votre poste, ouvrez http://10.70.#.31.

La page ne se charge pas. Le port 80 du conteneur est sur le réseau privé que Docker a créé à l'intérieur de la VM. Votre poste ne le voit pas, et rien n'écoute sur le port 80 de la VM elle-même.

Le navigateur sur http://10.70.4.31 : Ce site est inaccessible, ERR_CONNECTION_REFUSED

Ce conteneur ne sert à rien tel quel. Supprimez-le :

Bash
docker rm -f web

Étape 4 — Relancer nginx en publiant un port

Bash
docker run -d --name web -p 8080:80 nginx

Cette fois, pas de téléchargement : l'image nginx est déjà sur le disque.

Bash
docker ps
Texte
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
5e0d1a7b92c3   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web

La colonne PORTS montre maintenant une flèche : 0.0.0.0:8080->80/tcp. Tout ce qui arrive sur le port 8080 de la VM est transmis au port 80 du conteneur. La deuxième moitié, :::8080->80/tcp, dit la même chose pour IPv6.

La console : docker ps affiche web avec 0.0.0.0:8080->80/tcp

Étape 5 — Ouvrir le site

Dans le navigateur de votre poste, ouvrez http://10.70.#.31:8080.

La page Welcome to nginx! s'affiche. La requête a suivi le chemin du schéma de la note : port 8080 de la VM, redirection par Docker vers le bridge docker0, port 80 du conteneur.

Le navigateur sur http://10.70.4.31:8080 affiche Welcome to nginx!

Étape 6 — Lire les journaux

Bash
docker logs web

Les premières lignes viennent du démarrage de nginx. Les dernières ressemblent à ceci :

Texte
10.70.80.101 - - [04/Nov/2026:11:34:08 +0000] "GET / HTTP/1.1" 200 896 "-" "Mozilla/5.0 ..."
10.70.80.101 - - [04/Nov/2026:11:34:08 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://10.70.#.31:8080/" "Mozilla/5.0 ..."

Chaque ligne est une visite. Vous y trouvez l'adresse de votre poste, l'heure, la page demandée (GET /) et la réponse (200 veut dire « trouvée », 404 « introuvable »). Le navigateur a aussi demandé une icône, favicon.ico, que nginx n'a pas. Sur les captures, l'adresse du poste est masquée par une bande grise : sur votre écran, vous verrez la vôtre.

La console : docker logs web affiche le démarrage de nginx, puis la visite GET / avec le code 200

Étape 7 — Suivre les journaux en direct

Bash
docker logs -f web

La commande ne rend pas la main. Rafraîchissez la page dans le navigateur quelques fois : une nouvelle ligne apparaît à chaque visite.

Tapez Ctrl+C. Le suivi s'arrête, mais pas le conteneur : vérifiez avec docker ps.

La console : docker logs -f web affiche chaque nouvelle visite au moment où elle arrive

Étape 8 — Arrêter et relancer

Bash
docker stop web

La commande peut prendre une dizaine de secondes avant d'afficher web. Rafraîchissez la page : elle ne répond plus. docker ps est vide, et docker ps -a montre web en Exited.

Bash
docker start web

Rafraîchissez la page : elle répond de nouveau. docker start a relancé le même conteneur, avec la même publication de port. Vous n'avez pas eu à retaper -p 8080:80 : le réglage fait partie du conteneur depuis sa création.

La console : docker stop web, docker ps vide, docker start web, docker ps affiche web de nouveau Up

Étape 9 — Faire tourner un deuxième site

Lancez un deuxième conteneur nginx, en gardant le même port :

Bash
docker run -d --name web2 -p 8080:80 nginx
Texte
d49394dcbc5fbd732bdca9bf88fe2115ff49e61f796d378af687396cdc05fc22
docker: Error response from daemon: driver failed programming external connectivity on endpoint web2 (...): Bind for 0.0.0.0:8080 failed: port is already allocated.

Le port 8080 de la VM est déjà pris par web. Deux conteneurs ne peuvent pas recevoir les visiteurs du même port de la VM : Docker ne saurait pas auquel les envoyer.

Docker affiche d'abord un identifiant, puis l'erreur. Regardez docker ps -a : web2 existe quand même, en Created. Docker a créé le conteneur avant d'échouer à le démarrer. Son nom est pris, et un nouveau docker run --name web2 échouerait aussi. Supprimez-le :

Bash
docker rm web2

Relancez-le avec un autre port de la VM :

Bash
docker run -d --name web2 -p 8081:80 nginx

Ouvrez http://10.70.#.31:8081. La même page s'affiche. Vous avez maintenant deux serveurs web indépendants dans la même VM, issus de la même image. Les deux écoutent sur leur port 80, sans conflit : chacun a sa propre carte réseau.

La console : web2 sur le port 8080 est refusé, port is already allocated, puis web2 démarre sur le port 8081

Le navigateur sur http://10.70.4.31:8081 affiche Welcome to nginx!

Étape 10 — Voir les deux sites dans les journaux

Rafraîchissez la page du port 8080, puis celle du port 8081. Affichez les trois dernières lignes du journal de chaque conteneur :

Bash
docker logs --tail 3 web
docker logs --tail 3 web2

Une visite écrit trois lignes : la page (GET /), l'icône (GET /favicon.ico, code 404) et l'erreur de nginx qui ne trouve pas l'icône. Regardez le champ host: dans la ligne d'erreur. Le journal de web ne contient que 10.70.#.31:8080, celui de web2 que 10.70.#.31:8081. Chaque conteneur n'a enregistré que ses propres visites. Ils ne partagent rien.

La console : docker logs --tail 3 web montre une visite avec host 10.70.4.31:8080, docker logs --tail 3 web2 une visite avec host 10.70.4.31:8081

Étape 11 — Faire le ménage

Bash
docker rm -f web web2

Ouvrez http://10.70.#.31:8080 : plus rien ne répond.

La console : docker rm -f web web2, puis docker ps -a est vide

Le navigateur sur http://10.70.4.31:8080 : Ce site est inaccessible

Vérification finale

  • http://10.70.#.31:8080 a affiché Welcome to nginx! depuis votre poste
  • Vous avez vu vos propres visites dans docker logs
  • Deux conteneurs nginx ont tourné en même temps, sur les ports 8080 et 8081
  • docker ps -a est vide

Question 1

À l'étape 3, le conteneur tournait, mais la page ne s'affichait pas. Pourquoi ?

Voir la réponse Le conteneur avait été lancé sans `-p`. nginx écoutait sur le port 80 du conteneur, mais ce port est sur un réseau privé, à l'intérieur de la VM. Aucun port de la VM n'était relié au conteneur, et votre poste n'avait donc aucun moyen de l'atteindre. La colonne `PORTS` le montrait : `80/tcp`, sans flèche.

Question 2

Vous voulez un troisième nginx, accessible sur le port 80 de la VM, à l'adresse http://10.70.#.31. Quelle commande tapez-vous ?

Voir la réponse
Bash
docker run -d --name web3 -p 80:80 nginx
Le premier `80` est le port de la VM, celui que le navigateur utilise quand on n'écrit pas de port dans l'adresse. Le deuxième `80` est le port du conteneur, où nginx écoute toujours. Les deux nombres sont pareils, mais ils ne désignent pas la même chose.

Question 3

Après docker stop web, puis docker start web, pourquoi le site répond-il encore sur le port 8080 sans que vous ayez retapé -p 8080:80 ?

Voir la réponse Les options de `docker run` (le nom, les ports, les variables) sont enregistrées dans le conteneur au moment de sa création. `docker start` relance le même conteneur, avec tous ses réglages. Pour changer un réglage, comme le port, il faut supprimer le conteneur et en créer un nouveau avec `docker run`. On ne modifie pas un conteneur : on le remplace.

En cas de problème

Symptôme Cause probable Correction
port is already allocated Un autre conteneur utilise déjà ce port de la VM docker ps pour le trouver. Choisir un autre port, ou supprimer l'autre conteneur
The container name "/web" is already in use Un conteneur web existe déjà, même arrêté docker ps -a, puis docker rm -f web
La page ne se charge pas, et la colonne PORTS affiche 80/tcp sans flèche Le conteneur a été lancé sans -p docker rm -f web, puis relancer avec -p 8080:80
La page ne se charge pas, alors que PORTS montre 0.0.0.0:8080->80/tcp Mauvaise adresse, ou poste sur eduroam Vérifier l'adresse de la VM avec ip -br a. Utiliser un poste de la classe
La page ne se charge pas avec -p 80:8080 Ports inversés : rien n'écoute sur le port 8080 du conteneur La VM à gauche, le conteneur à droite : -p 8080:80