Docker pour développeurs : images, conteneurs et Compose
Vous avez écrit du code qui fonctionne sur votre machine, mais lorsqu'un collègue essaie de l'exécuter, il rencontre des dépendances manquantes, des conflits de versions ou des erreurs obscures. Docker résout ce problème en empaquetant votre application et son environnement dans une unité portable unique. Dans ce guide, vous apprendrez les fondamentaux de Docker : images, conteneurs et Compose, avec des étapes pratiques pour conteneuriser une application web simple.
Qu'est-ce que Docker ?
Docker est une plateforme pour construire, exécuter et partager des applications dans des conteneurs. Un conteneur est un paquet exécutable léger et autonome qui inclut tout ce qui est nécessaire pour exécuter un logiciel : code, runtime, outils système, bibliothèques et paramètres. Les conteneurs isolent les applications les unes des autres et du système hôte, garantissant une cohérence entre le développement, les tests et la production.
Images vs conteneurs : le plan et l'instance en cours d'exécution
Une image est un modèle en lecture seule qui définit un conteneur. C'est comme une classe en programmation orientée objet. Un conteneur est une instance exécutable d'une image, comme un objet. Vous pouvez créer de nombreux conteneurs à partir de la même image.
Les images sont construites à partir d'un Dockerfile, un fichier texte contenant des instructions. Les conteneurs sont démarrés avec docker run.
Différences clés
| Image | Conteneur |
|---|---|
| Modèle en lecture seule | Instance exécutable |
Construite avec docker build | Démarré avec docker run |
| Stockée dans un registre (ex. Docker Hub) | S'exécute sur l'hôte |
| Système de fichiers en couches | Couche inscriptible au-dessus |
Construire votre première image
Conteneurisons une application Node.js simple. Créez un fichier nommé Dockerfile :
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the rest of the application
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Define the command to run the app
CMD ["node", "server.js"]
Construisez l'image avec un tag :
docker build -t my-node-app .
L'option -t nomme et tague l'image. Le . à la fin spécifie le contexte de build (répertoire courant).
Exécuter des conteneurs
Démarrez un conteneur à partir de votre image :
docker run -p 3000:3000 -d --name my-app my-node-app
-p 3000:3000: Mappe le port 3000 de l'hôte au port 3000 du conteneur.-d: Exécute le conteneur en mode détaché (en arrière-plan).--name my-app: Attribue un nom au conteneur pour le référencer facilement.
Vérifiez les conteneurs en cours d'exécution avec docker ps. Arrêtez le conteneur avec docker stop my-app.
Gérer les données avec les volumes
Les conteneurs sont éphémères ; les données qu'ils contiennent sont perdues lorsque le conteneur est supprimé. Pour persister les données, utilisez des volumes. Par exemple, pour persister les données d'une base de données :
docker run -v my-db-data:/var/lib/mysql -d mysql:8
Cela crée un volume nommé my-db-data qui survit aux redémarrages et suppressions du conteneur.
Simplifier les applications multi-conteneurs avec Docker Compose
Les applications réelles ont souvent besoin de plusieurs services : un serveur web, une base de données, un cache, etc. Docker Compose vous permet de définir et d'exécuter des applications multi-conteneurs avec un seul fichier YAML.
Créez un docker-compose.yml :
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
postgres_data:
Exécutez le tout avec :
docker compose up -d
Compose construit l'image web, démarre la base de données et les connecte sur un réseau partagé. Le depends_on garantit que la base de données démarre avant le service web.
Commandes Docker essentielles
docker ps -a: Liste tous les conteneurs (y compris arrêtés).docker images: Liste les images.docker logs my-app: Affiche les logs du conteneur.docker exec -it my-app sh: Ouvre un shell dans un conteneur en cours d'exécution.docker compose down: Arrête et supprime les conteneurs, réseaux et volumes définis dans le fichier Compose.
Bonnes pratiques pour le développement
- Utilisez .dockerignore pour exclure des fichiers (ex. node_modules) du contexte de build, accélérant ainsi les builds.
- Profitez des builds multi-étapes pour garder les images de production petites. Par exemple, construisez votre application dans une étape et copiez uniquement les artefacts nécessaires dans une image d'exécution légère.
- Épinglez les versions dans votre Dockerfile (ex.
node:18-alpineau lieu denode:latest) pour la reproductibilité. - Exécutez en tant qu'utilisateur non-root pour la sécurité. Ajoutez
USER nodeaprès avoir copié les fichiers.
FAQ
Quelle est la différence entre une image Docker et un conteneur ?
Une image est un modèle en lecture seule qui définit l'application et son environnement. Un conteneur est une instance en cours d'exécution de cette image. Vous pouvez créer plusieurs conteneurs à partir de la même image.
Comment persister des données dans Docker ?
Utilisez des volumes. Les volumes nommés (ex. docker run -v my-vol:/data) sont stockés en dehors du système de fichiers du conteneur et persistent à travers les redémarrages et suppressions du conteneur.
Quand dois-je utiliser Docker Compose ?
Utilisez Compose lorsque votre application est composée de plusieurs services (ex. web + base de données) qui doivent s'exécuter ensemble. Cela simplifie l'orchestration pour le développement et les tests.
Prêt à conteneuriser votre prochain projet ? Commencez par écrire un Dockerfile simple et exécuter votre premier conteneur. Pour plus d'outils de développement, découvrez le JSON Formatter de TryQuickToolBox pour valider les réponses d'API lors du test de vos services conteneurisés.