GNU/Linux >> Tutoriels Linux >  >> Panels >> Docker

Comment réduire la taille de l'image Docker dans les conteneurs Docker

La création et le déploiement de votre image Docker prennent trop de temps ? L'exportation prend-elle des heures ? Arrêtez de perdre du temps et accélérez ces processus en développant une image plus petite. Dans ce didacticiel, vous apprendrez trois astuces pour réduire la taille de votre image Docker.

Commençons !

Prérequis

Ce tutoriel sera une démonstration pratique. Si vous souhaitez suivre, assurez-vous d'avoir les éléments suivants :

  • Poste de travail ou moteur Docker. Il existe des versions Docker disponibles pour Linux, Windows et macOS. Ce tutoriel utilise Docker version 20.10.8 build 3967b7d sur un ordinateur Ubuntu 18.04 LTS.
  • Node.js. Ce didacticiel utilise la version 10.10.0 de Node.js, mais devrait également fonctionner avec les versions plus récentes.
  • Vous aurez besoin d'un éditeur de code tel que Visual Studio Code, vim et nano . Ce tutoriel utilise nano.

Créer une image Docker

Vous avez probablement déjà une image Docker que vous souhaitez réduire. Ne le faites pas. Dans ce didacticiel, vous allez repartir à zéro en créant une image Docker pour vos tests.

Vous commencerez par créer un conteneur pour une application Node.js. L'application Node.js que vous utiliserez est l'exemple Hello World Express.js qui affiche le texte "Hello World!" dans votre navigateur.

1. Tout d'abord, ouvrez une session de terminal et créez un répertoire dans lequel vous créerez votre image Docker et les fichiers associés. Pour cet exemple, le répertoire de travail sera ~/docker_demo .

# Create the project directory
mdkir ~/docker_demo
# Change the current directory to your working directory
cd ~/docker_demo

Ensuite, créez trois fichiers dans votre répertoire de travail. Ces fichiers sont :

  • index.js – le point de départ de votre exemple d'application.
  • package.json – contient les métadonnées de votre application.
  • Dockerfile – contient les instructions pour créer votre image Docker. Exécutez la commande ci-dessous dans le terminal pour créer tous ces fichiers à la fois.
touch index.js package.json Dockerfile

3. Ouvrez index.js dans votre éditeur de code, remplissez-le avec le code ci-dessous et enregistrez.

const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(3000, () => {
  console.log(`Example app listening on port 3000!`)
})

4. Ensuite, ouvrez le package.json fichier à modifier, copiez et collez le code ci-dessous et enregistrez.

{
  "name": "hello-world",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "express": "^4.16.2"
  },
  "scripts": {
    "start": "node index.js"
  }
}

5. De la même manière, modifiez le Dockerfile pour remplir le code ci-dessous et enregistrer le fichier.

# use the Node.js parent image 
FROM node:8 

# set a directory for the app
WORKDIR /app
# copy all the files to the container
COPY . .
# install dependencies
RUN npm install
# define the port number the container should expose
EXPOSE 3000

# run the application
CMD ["npm", "start"]

6. Exécutez la docker build suivante commande pour créer votre image Docker. Le -t facultatif flag marque votre image avec un nom pour la rendre identifiable. Cet exemple utilise le nom ‘my_app.’

docker build -t my_app .

7. Lorsque Docker a terminé de créer l'image, exécutez la commande suivante pour afficher votre image étiquetée avec 'my_app.'

Le grep La commande n'est disponible que sur Linux, mais pour afficher votre image sur d'autres systèmes d'exploitation, exécutez la commande docker images et recherchez l'image avec la balise "my_app".

docker images | grep my_app

Comme illustré dans l'image suivante, la taille de l'image Docker est de 904 Mo.

8. Vérifiez maintenant que votre image fonctionne correctement. Exécutez la commande docker run suivante. Cette commande utilisera votre image Docker pour créer un conteneur dans lequel votre application s'exécutera.

docker run -p 3000:3000 -ti --rm --init my_app

Si l'application démarre correctement, le message 'Example app listening on port 3000!' sera imprimé dans votre terminal.

9. Pour vérifier que votre application fonctionne, ouvrez votre navigateur et accédez à http://localhost:3000/. Le texte "Hello World !" doit être affiché comme indiqué dans l'image suivante.

10. Pour terminer l'application et revenir à l'invite du terminal, appuyez sur CTRL+C .

Réduire la taille d'une image Docker

Maintenant que vous avez une image Docker, il est temps d'apprendre à réduire la taille de votre image ! Les sections suivantes couvrent trois méthodes pour réduire la taille de votre image Docker.

Méthode 1 :Appliquer des versions en plusieurs étapes

Avoir des fichiers Dockerfile séparés pour le développement et la production était une pratique courante.

Le Dockerfile de développement contenait tout le nécessaire pour créer l'application, tandis que celui de production comprenait ce dont l'application avait besoin pour s'exécuter. Cette méthode produit l'image de production finale avec la taille optimale. Mais gérer deux Dockerfiles est inutilement compliqué.

Depuis l'introduction des builds en plusieurs étapes dans la version 17.05, les développeurs n'ont plus besoin que d'un seul Dockerfile contenant plusieurs FROM instructions pour séparer les étapes de développement et de production. Ainsi, copie sélective des artefacts d'une étape de construction à une autre.

Il est maintenant temps d'utiliser des builds en plusieurs étapes dans votre image !

1. Ouvrez votre Dockerfile dans l'éditeur de code et remplacez son contenu par le code suivant. Ce nouveau code Dockerfile a deux étapes de construction comme indiqué par les deux FROM lignes.

Par défaut, les étapes de construction n'ont pas de nom, et votre code ne peut les référencer qu'en tant qu'entier dans l'ordre dans lequel elles apparaissent (en commençant à zéro) dans le Dockerfile. Vous pouvez ajouter le as <name> au FROM ligne pour attribuer un nom à l'étape de construction pour une meilleure identification .

# the develop build stage using the node parent image
FROM node:8 as develop

# set a directory for the app
WORKDIR /app
# copy all the files to the container
COPY . .
# install dependencies
RUN npm install

# the production build stage using the node parent image
FROM node:8

# Copy only the build artifact from the first (develop) build stage
# Any intermediate artifacts used to build your application are not included in the final image.
COPY --from=develop /app /

# define the port number the container should expose
EXPOSE 3000

# run the application
CMD ["npm", "start"]

2. Créez votre nouvelle image avec le nom my_app_multi_stage_builds en exécutant la commande suivante.

docker build -t my_app_multi_stage_builds .

3. Après la génération, affichez la taille de l'image mise à jour en exécutant la commande suivante.

docker images | grep my_app_multi_stage_builds

L'exemple d'application est petit et ne comporte que quelques artefacts intermédiaires. Mais il y a toujours une réduction de 1 Mo par rapport à la version précédente de l'image Docker.

Méthode 2 :Utilisation d'une image parent légère

Sauf si vous créez une image Docker à partir de zéro (en utilisant le FROM scratch directive), chaque image Docker a une image parent. Le Dockerfile les fichiers des sections précédentes utilisent node:8 comme image parente lors de la construction.

Si votre application ne nécessite pas une version spécifique du système d'exploitation pour s'exécuter, envisagez de remplacer votre image parent par une autre plus légère. Si vous utilisez Linux, l'image la plus légère dans Docker Hub est Alpine.

Il est maintenant temps d'apprendre à remplacer l'image parent par Alpine !

1. Modifiez votre Dockerfile et remplacez le second FROM node:8 ligne avec FROM node:8-alpine . Ce nouveau FROM L'instruction Docker utilisera node-8-alpine comme image parent. Maintenant, votre image finale fonctionnera sur Alpine au lieu de Node.

# the first build stage using the node parent image
FROM node:8 as build

# set a directory for the app
WORKDIR /app
# copy all the files to the container
COPY . .
# install dependencies
RUN npm install

# the second build stage using the node-8-alpine parent image
FROM node:8-alpine

# copy the required artifacts to from the first build stage
COPY --from=build /app /
# define the port number the container should expose
EXPOSE 3000

# run the application
CMD ["npm", "start"]

2. Exécutez la commande ci-dessous pour créer l'image Docker avec le nom my_app_alpine.

docker build -t my_app_alpine .

3. Enfin, affichez la taille de l'image mise à jour en exécutant la commande suivante.

docker images | grep my_app_alpine

La taille finale de l'image Docker n'est plus que de 75,2 Mo. Une réduction significative de 827,8 Mo !

Méthode 3 :Création d'un fichier .dockerignore

Docker est une application client-serveur composée du client Docker ou CLI et du démon Docker, qui gère les images Docker (ainsi que les conteneurs, les réseaux et les volumes).

La CLI compile un contexte de construction constitué des fichiers à inclure dans l'image à construire. La CLI recherche également un fichier .dockerignore qui répertorie les fichiers à ignorer avant d'envoyer le contexte de construction au démon Docker. Par conséquent, copier moins de fichiers réduit la taille de l'image Docker.

Il est maintenant temps d'appliquer un fichier .dockerignore dans votre build !

1. Tout d'abord, créez un nouveau fichier vide appelé .dockerignore .

touch .dockerignore

2. Ensuite, créez un fichier factice que Docker ignorera lors des générations. Dans cet exemple, créez un fichier factice README.md d'une taille de 2 Mo.

Si vous êtes sur un ordinateur Linux, exécutez la commande fallocate ci-dessous pour créer le fichier.

fallocate -l 2MB README.md

Si vous êtes sur un ordinateur Windows, exécutez plutôt la commande fsutil.

fsutil file createnew README.md 2000000

3. Ensuite, créez votre nouvelle image Docker en exécutant la commande suivante. Étant donné que le fichier README.md se trouve dans le même répertoire, attendez-vous à ce que ce fichier factice fasse partie de l'image Docker résultante.

docker build -t my_app_readme .

4. Affichez la taille de l'image mise à jour en exécutant la commande suivante.

docker images | grep my_app_readme

Comme prévu, avec l'inclusion du fichier README.md, la taille finale de l'image Docker a augmenté de 2 Mo.

5. Maintenant, excluez tous les fichiers avec le .md extension de la construction de l'image. Pour ce faire, modifiez le .dockerignore fichier et remplissez-le avec le code suivant.

# ignore markdown files
.md

Les fichiers Markdown (.md) n'affectent généralement pas les fonctionnalités d'une application et peuvent généralement être exclus des builds en toute sécurité. Les autres fichiers que vous pouvez exclure sont les journaux de compilation, les scripts de test, le dossier .git de votre référentiel et tous les fichiers contenant des informations sensibles (comme les mots de passe).

6. Maintenant que vous avez mis à jour le fichier ignoré, réexécutez la commande de création d'image Docker comme indiqué ci-dessous.

docker build -t my_app_dockerignore .

7. Enfin, exécutez la commande ci-dessous pour afficher la nouvelle taille d'image Docker, y compris le fichier README.md.

docker images | grep my_app_dockerignore

Maintenant que le fichier README.md est sorti de la nouvelle version, la taille de l'image Docker est réduite à 75,2 Mo !

Conclusion

Dans ce tutoriel, vous avez appris les différentes méthodes pour réduire la taille de votre image Docker. Vous avez appris à utiliser des compilations en plusieurs étapes, à compiler à partir d'une image parent plus petite et à exclure les fichiers non essentiels.

La prochaine fois que Docker prendra trop de temps à créer et à déployer, ne vous retenez pas et appliquez vos connaissances pour optimiser la taille de votre image Docker. Quelle méthode pensez-vous utiliser le plus ?


Docker
  1. Comment utiliser Docker Compose

  2. Comment connecter des conteneurs Docker

  3. Comment utiliser un Dockerfile pour créer une image Docker

  4. Comment transmettre des variables d'environnement aux conteneurs Docker

  5. Comment modifier les images Docker

Comment exécuter des conteneurs Docker

Comment supprimer les conteneurs Docker

Comment arrêter les conteneurs Docker

Comment nommer ou renommer les conteneurs Docker

Comment gérer les conteneurs Docker

Comment configurer les espaces de noms réseau dans les conteneurs Docker