Aller au contenu

Paramètres des cookies

Choisissez, par catégorie, les cookies que vous autorisez. Vous pouvez modifier votre choix à tout moment via Paramètres des cookies, en bas de chaque page. Politique de confidentialité

Nécessaires

Toujours activés

Indispensables pour vous connecter, conserver votre panier et mémoriser vos choix. Ils sont toujours activés.

Quels cookies ?
  • weboke_sessie, weboke_klant, weboke_remember: votre session et le maintien de la connexion
  • weboke_basket: votre panier
  • wkBtwIncl: l'affichage des prix TTC ou HT
  • wok_cookies: votre choix concernant les cookies, 12 mois

Mesure quelle publicité mène à une visite ou à une commande, pour que nous ne payions pas des publicités inefficaces.

Quels cookies ?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), jusqu'à 90 jours
  • OpenAI Ads, publicités dans ChatGPT
  • wok_aff: le partenaire qui vous a orienté vers nous (programme d'affiliation), 60 jours

4,6

Pays et langue

Chaque pays a son propre site, avec les prix et la TVA de ce pays.

Afficher

Module 9 · 9.3

Docker compose et le pare-feu

Module 9: Docker et docker compose · Temps de lecture : 12 minutes

Objectif pédagogique : À l'issue de cette leçon, vous saurez décrire des services dans un fichier compose, les démarrer, les mettre à jour et les arrêter, et vous pourrez expliquer pourquoi les ports publiés par Docker contournent ufw et comment l'éviter.

Notions clés : compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, version: obsolète, Docker et ufw, DOCKER-USER, publication sur 127.0.0.1, secrets, docker.sock

Pourquoi compose ?

Avec docker run (leçon 9.2), vous démarrez un seul conteneur avec une longue ligne d'options. Une vraie application se compose souvent de plusieurs conteneurs : un programme, une base de données, un reverse proxy. Retenir ces lignes et les retaper après un redémarrage ou une mise à jour finit tôt ou tard par mal tourner.

Docker Compose décrit tous les conteneurs d'une application dans un seul fichier : compose.yaml. Vous placez ce fichier dans un dossier dédié, par exemple /srv/status/compose.yaml, et vous gérez tout avec docker compose. Le fichier sert en même temps de documentation : ce qui tourne, quelle image, quels ports, où se trouvent les données. Incluez ce dossier dans votre sauvegarde (leçon 8.1), et vous pourrez restaurer l'application sur un nouveau serveur en quelques minutes.

Le plug-in s'appelle docker compose (avec une espace, version 2). L'ancien programme séparé docker-compose (avec un trait d'union) a été remplacé ; vous le rencontrerez encore dans d'anciens tutoriels. Le champ version: "3.8" en haut des anciens fichiers est lui aussi obsolète : Compose utilise toujours le schéma le plus récent et se contente d'afficher un avertissement en présence de version:.

Lire un fichier compose

Un exemple avec un programme et une base de données PostgreSQL :

# /srv/notities/compose.yaml
services:
  app:
    image: ghcr.io/example/notities:1.4
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:8080"
    environment:
      DB_HOST: db
      DB_USER: notities
      DB_PASSWORD: ${DB_PASSWORD}
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_USER: notities
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U notities"]
      interval: 10s
      retries: 5

volumes:
  db-data:

Étape par étape :

  • services : chaque service devient un conteneur. Le nom (app, db) est aussi le nom d'hôte grâce auquel les conteneurs se trouvent entre eux. Compose crée un réseau propre à l'application, donc app se connecte à la base de données sur db:5432.
  • image : toujours avec un tag de version (leçon 9.1).
  • restart : ce que fait Docker lorsque le conteneur s'arrête ou que le serveur redémarre. unless-stopped le relance, sauf si vous l'avez arrêté volontairement. Sans politique de redémarrage, votre application ne revient pas après un redémarrage (leçon 4.2).
  • ports : seule l'application publie un port, et uniquement sur 127.0.0.1. La base de données ne publie rien : l'application l'atteint via le réseau interne. Une base de données avec ports: - "5432:5432" est l'une des erreurs les plus fréquentes (voir plus bas).
  • environment : les paramètres du programme. Le mot de passe n'y figure pas en clair, mais sous la forme ${DB_PASSWORD}.
  • volumes : le volume nommé db-data conserve la base de données lorsque le conteneur est remplacé.
  • depends_on avec healthcheck : l'application ne démarre que lorsque la base de données est réellement prête, pas seulement démarrée.

Les secrets dans un fichier .env

Compose lit les variables comme ${DB_PASSWORD} dans un fichier .env situé dans le même dossier :

# /srv/notities/.env
DB_PASSWORD=Kies-hier-een-lang-willekeurig-wachtwoord
anna@web1:/srv/notities$ sudo chmod 600 .env

Ainsi, le mot de passe ne figure pas dans le fichier compose que vous conservez peut-être dans Git ou que vous collez sur un forum pour demander de l'aide. Ajoutez .env à .gitignore. Générez le mot de passe avec un gestionnaire de mots de passe ou avec openssl rand -base64 24.

Utilisation au quotidien

Toutes les commandes s'exécutent dans le dossier qui contient le fichier compose :

anna@web1:/srv/notities$ sudo docker compose config     # vérifier le fichier, variables remplacées
anna@web1:/srv/notities$ sudo docker compose up -d      # tout démarrer (ou mettre à jour selon le fichier)
anna@web1:/srv/notities$ sudo docker compose ps         # état par service
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull       # récupérer les nouvelles images
anna@web1:/srv/notities$ sudo docker compose up -d      # remplacer les conteneurs par les nouvelles images
anna@web1:/srv/notities$ sudo docker compose down       # arrêter et supprimer les conteneurs

down conserve vos volumes. down -v supprime aussi les volumes de l'application, et donc votre base de données. Ne tapez cette commande que si vous voulez vraiment repartir de zéro.

docker compose config est l'équivalent de nginx -t et sshd -t : elle montre comment Compose interprète votre fichier, avec toutes les variables remplacées, avant que vous ne démarriez quoi que ce soit. Veillez à ne pas coller cette sortie n'importe où, car les mots de passe y apparaissent.

Docker contourne ufw

Voici le point de sécurité le plus important de ce module. Dans la leçon 5.2, vous avez configuré ufw sur « tout refuser, sauf SSH, 80 et 443 ». Vous pourriez donc penser qu'un conteneur avec ports: - "5432:5432" n'est pas accessible. Ce n'est pas le cas.

La documentation de Docker le dit explicitement : Docker et ufw utilisent les règles de pare-feu d'une manière incompatible. Lorsque vous publiez un port, Docker ajoute lui-même des règles dans le pare-feu du noyau. Ces règles redirigent le trafic vers le conteneur (traduction d'adresse, DNAT) avant que les règles d'ufw ne s'appliquent. Le paquet contourne donc ufw. ufw status n'affiche rien de particulier, alors que le port est accessible depuis tout Internet. Il en va de même pour firewalld.

De plus, sans adresse précisée, Docker publie sur 0.0.0.0 et [::], donc en IPv4 et en IPv6 (leçon 9.1).

Trois façons de bien faire, de la plus simple à la plus complexe :

  1. Ne publiez rien qui n'ait pas besoin d'être public. Les bases de données, les caches et les services internes ne reçoivent pas de ports:. Les conteneurs d'une même application compose se joignent via le réseau interne.
  2. Publiez sur l'interface loopback. "127.0.0.1:8081:8080". Seul le serveur lui-même peut alors y accéder, et vous placez devant un reverse proxy (nginx ou Caddy, module 7) qui écoute sur le port 443. Vous pouvez aussi en faire le comportement par défaut de Docker : un paramètre du démon fait atterrir sur 127.0.0.1 tous les ports publiés sans adresse.
  3. Des règles dans la chaîne DOCKER-USER. Docker crée une chaîne vide DOCKER-USER, parcourue avant ses propres règles. Vous pouvez y ajouter vos propres règles, par exemple « seule cette adresse IP peut accéder aux ports publiés ». C'est un travail avancé avec iptables ou nftables, où l'erreur est facile. Pour la plupart des petits serveurs, les options 1 et 2 suffisent.

Vérifiez toujours depuis l'extérieur, comme dans la leçon 5.1 : nc -vz -w 3 <ip> 5432 depuis votre ordinateur portable, ou la vérification de la formation des exercices Z5.1 et Z10.4.

Deux autres choses à ne pas faire

  • Ne montez pas /var/run/docker.sock dans un conteneur, sauf si vous savez exactement pourquoi. Un conteneur ayant accès au socket Docker peut lui-même démarrer des conteneurs, y compris un conteneur avec tout le disque de l'hôte (leçon 9.2). Certains outils (tableaux de bord, outils de mise à jour automatique) le demandent ; cela revient en pratique à donner les droits root à ce programme.
  • N'utilisez pas privileged: true ou network_mode: host simplement parce qu'un tutoriel le dit. Les deux suppriment en grande partie l'isolation du conteneur. Ne les utilisez que si l'éditeur explique pourquoi c'est nécessaire.

Résumé

  • Un fichier compose (compose.yaml) décrit tous les conteneurs d'une application ; il sert aussi de documentation et doit figurer dans votre sauvegarde.
  • Utilisez des tags de version, une politique de redémarrage, des volumes nommés, un healthcheck lorsque c'est possible, et placez les secrets dans un .env avec les droits 600.
  • docker compose config, up -d, ps, logs, pull, down ; down -v supprime aussi les volumes.
  • Les ports publiés contournent ufw et firewalld. Ne publiez que ce qui doit être public, et sinon sur 127.0.0.1 avec un reverse proxy devant.
  • Pas de docker.sock, de privileged ni de network_mode: host sans bonne raison.

Quiz

1. ufw est configuré sur « tout refuser sauf 22, 80 et 443 ». Votre fichier compose contient ports: - "5432:5432" pour la base de données. La base de données est-elle accessible depuis Internet ?



2. Comment le conteneur app atteint-il la base de données de la même application compose, si celle-ci ne publie aucun port ?



3. Après un redémarrage du serveur, vos conteneurs ne tournent plus. Que manque-t-il probablement dans le fichier compose ?



4. Quelle est la différence entre docker compose down et docker compose down -v ?



5. Le manuel d'un tableau de bord demande - /var/run/docker.sock:/var/run/docker.sock. Qu'est-ce que cela implique pour la sécurité ?



Exercice

Exercice Z9.3: Vérifier un fichier compose. Le fichier d'exemple compose-nakijken.txt contient (sous forme de fichier texte) le fichier compose d'une petite boutique en ligne avec une application, une base de données, un cache et un outil d'administration. Il comporte six erreurs abordées dans cette leçon ou dans les leçons 9.1 et 9.2. Indiquez pour chaque bloc de lignes numéroté s'il est correct ou erroné, et choisissez pour chaque erreur la bonne correction. Le programme compare vos réponses à la clé de correction. Si vous avez votre propre fichier compose, passez-le ensuite en revue selon les mêmes points.

Exercice Z9.3: Vérifier un fichier compose

Fichier pour cet exercice : compose-nakijken.txt





















Nous ne conservons pas ce que vous saisissez ni ce que nous trouvons. Votre navigateur mémorise vos réponses et si l'exercice est réussi. Si vous êtes connecté, nous enregistrons uniquement dans Mes formations que l'exercice était (presque) correct ; vous pouvez aussi le supprimer à cet endroit.

Pour aller plus loin

Un instant…

Configurez vos domaines

Pour chaque domaine, réglez les serveurs de noms, l'association à votre hébergement et le futur titulaire.

Chargement de vos domaines…