Comment exécuter un script Python au démarrage d'un conteneur Docker

DockerBeginner
Pratiquer maintenant

Introduction

Docker est un outil puissant pour la conteneurisation des applications, facilitant le développement, le déploiement et la gestion des logiciels. Dans ce tutoriel, nous allons explorer comment exécuter un script Python au démarrage d'un conteneur Docker. Cette approche vous permet d'automatiser le déploiement de votre application et de rationaliser votre flux de travail de développement. À la fin de ce lab, vous serez capable de créer un conteneur Docker qui exécute automatiquement votre script Python au démarrage.

Création d'un script Python simple

Dans cette première étape, nous allons créer un script Python simple qui sera exécuté au démarrage de notre conteneur Docker. Ce script affichera un message ainsi que la date et l'heure actuelles.

Commençons par créer un nouveau répertoire pour notre projet :

mkdir -p ~/project/python-docker
cd ~/project/python-docker

Maintenant, créons un script Python simple appelé app.py en utilisant l'éditeur de texte nano :

nano app.py

Dans l'éditeur nano, ajoutez le code Python suivant :

import datetime
import time

print("Hello from the Docker container!")
print(f"Current date and time: {datetime.datetime.now()}")

## Keep the container running to demonstrate it's working
print("Container is running...")
while True:
    print("Container still running... Press Ctrl+C to stop.")
    time.sleep(10)

Enregistrez le fichier en appuyant sur Ctrl+O, puis sur Entrée, et quittez nano en appuyant sur Ctrl+X.

Ce script va :

  1. Afficher un message de bienvenue
  2. Afficher la date et l'heure actuelles
  3. Maintenir le conteneur en cours d'exécution avec un message toutes les 10 secondes

Testons notre script Python pour nous assurer qu'il fonctionne correctement :

python3 app.py

Vous devriez voir une sortie similaire à :

Hello from the Docker container!
Current date and time: 2023-10-12 14:30:45.123456
Container is running...
Container still running... Press Ctrl+C to stop.

Appuyez sur Ctrl+C pour arrêter le script.

Maintenant que nous avons un script Python fonctionnel, nous pouvons procéder à la création d'un conteneur Docker qui exécutera ce script lorsqu'il démarrera.

Création d'un Dockerfile

Maintenant que notre script Python est prêt, créons un Dockerfile pour définir comment notre conteneur Docker doit être construit.

Un Dockerfile est un fichier texte qui contient toutes les commandes nécessaires pour construire une image Docker. Cette image contiendra notre script Python et toutes les dépendances nécessaires.

Dans le même répertoire (~/project/python-docker), créez un nouveau fichier nommé Dockerfile :

nano Dockerfile

Ajoutez le contenu suivant au Dockerfile :

## Use the official Python image as base
FROM python:3.9-slim

## Set working directory
WORKDIR /app

## Copy the Python script to the container
COPY app.py .

## Command to run when the container starts
CMD ["python", "app.py"]

Enregistrez et quittez nano en appuyant sur Ctrl+O, puis sur Entrée, et enfin sur Ctrl+X.

Comprenons ce que fait chaque ligne du Dockerfile :

  1. FROM python:3.9-slim : Ceci spécifie l'image de base à utiliser. Nous utilisons l'image officielle Python 3.9 avec une variante slim pour maintenir une petite taille.

  2. WORKDIR /app : Ceci définit le répertoire de travail à l'intérieur du conteneur sur /app.

  3. COPY app.py . : Ceci copie notre script Python de la machine hôte vers le répertoire de travail actuel dans le conteneur (qui est /app).

  4. CMD ["python", "app.py"] : Ceci spécifie la commande à exécuter au démarrage du conteneur. Dans ce cas, elle exécutera notre script Python.

Maintenant, construisons notre image Docker en utilisant ce Dockerfile :

docker build -t python-app .

Cette commande construit une image Docker à partir du Dockerfile dans le répertoire courant (.) et la taggue avec le nom python-app (-t signifie tag).

Vous devriez voir une sortie similaire à :

Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM python:3.9-slim
 ---> 1bc6a8a2a52f
Step 2/4 : WORKDIR /app
 ---> Using cache
 ---> 2a3b7a28c9e5
Step 3/4 : COPY app.py .
 ---> Using cache
 ---> 9a0b7a1c8c2d
Step 4/4 : CMD ["python", "app.py"]
 ---> Using cache
 ---> 3b0c7a2d9f1e
Successfully built 3b0c7a2d9f1e
Successfully tagged python-app:latest

La sortie peut varier, mais vous devriez voir les messages "Successfully built" et "Successfully tagged" si tout s'est bien passé.

Vous avez maintenant créé avec succès une image Docker qui contient votre script Python et l'exécutera lorsqu'un conteneur sera démarré à partir de cette image.

Exécution du conteneur Docker

Maintenant que nous avons construit notre image Docker, nous pouvons exécuter un conteneur basé sur cette image. Le conteneur exécutera automatiquement notre script Python lorsqu'il démarrera.

Pour exécuter un conteneur à partir de notre image, utilisez la commande suivante :

docker run --name python-container python-app

Cette commande démarre un nouveau conteneur nommé python-container à partir de l'image python-app que nous avons créée à l'étape précédente.

Vous devriez voir une sortie similaire à :

Hello from the Docker container!
Current date and time: 2023-10-12 15:45:30.123456
Container is running...
Container still running... Press Ctrl+C to stop.
Container still running... Press Ctrl+C to stop.

Le conteneur est maintenant en cours d'exécution et exécute notre script Python. Le script est conçu pour continuer à s'exécuter indéfiniment, en affichant un message toutes les 10 secondes.

Appuyez sur Ctrl+C pour arrêter l'affichage des journaux, mais notez que le conteneur est toujours en cours d'exécution en arrière-plan.

Pour vérifier que le conteneur est en cours d'exécution, utilisez la commande suivante :

docker ps

Vous devriez voir votre conteneur dans la liste des conteneurs en cours d'exécution :

CONTAINER ID   IMAGE        COMMAND           CREATED         STATUS         PORTS     NAMES
1a2b3c4d5e6f   python-app   "python app.py"   1 minute ago    Up 1 minute              python-container

Pour arrêter le conteneur, utilisez la commande suivante :

docker stop python-container

Pour redémarrer le conteneur, utilisez :

docker start python-container

Et pour afficher les journaux du conteneur en cours d'exécution :

docker logs python-container

Cela affichera la sortie de notre script Python. Vous pouvez appuyer sur Ctrl+C pour quitter l'affichage des journaux.

Pour supprimer le conteneur lorsque vous avez terminé, arrêtez-le d'abord s'il est en cours d'exécution, puis supprimez-le :

docker stop python-container
docker rm python-container

Vous avez maintenant créé et exécuté avec succès un conteneur Docker qui exécute un script Python au démarrage.

Utilisation des variables d'environnement avec Python dans Docker

Les variables d'environnement sont un excellent moyen de configurer votre application sans modifier le code. Dans cette étape, nous allons modifier notre script Python pour utiliser les variables d'environnement et mettre à jour notre Dockerfile pour fournir ces variables.

Tout d'abord, mettons à jour notre script Python pour lire une variable d'environnement :

nano app.py

Modifiez le script pour inclure la prise en charge des variables d'environnement :

import datetime
import time
import os

## Get the environment variable with a default value if not set
user_name = os.environ.get('USER_NAME', 'Guest')

print(f"Hello, {user_name}, from the Docker container!")
print(f"Current date and time: {datetime.datetime.now()}")

## Keep the container running to demonstrate it's working
print("Container is running...")
while True:
    print("Container still running... Press Ctrl+C to stop.")
    time.sleep(10)

Enregistrez et quittez nano en appuyant sur Ctrl+O, puis sur Entrée, et enfin sur Ctrl+X.

Maintenant, mettons à jour notre Dockerfile pour inclure une variable d'environnement :

nano Dockerfile

Mettez à jour le Dockerfile pour inclure la variable d'environnement :

## Use the official Python image as base
FROM python:3.9-slim

## Set working directory
WORKDIR /app

## Set environment variable
ENV USER_NAME="Docker User"

## Copy the Python script to the container
COPY app.py .

## Command to run when the container starts
CMD ["python", "app.py"]

Enregistrez et quittez nano, puis reconstruisez l'image Docker :

docker build -t python-app-env .

Maintenant, exécutez un conteneur avec la variable d'environnement par défaut :

docker run --name python-env-container python-app-env

Vous devriez voir une salutation avec "Docker User" dans la sortie :

Hello, Docker User, from the Docker container!
Current date and time: 2023-10-12 16:30:45.123456
Container is running...

Appuyez sur Ctrl+C pour arrêter l'affichage des journaux.

Arrêtez et supprimez le conteneur :

docker stop python-env-container
docker rm python-env-container

Vous pouvez également remplacer la variable d'environnement lors de l'exécution du conteneur :

docker run --name python-env-container -e USER_NAME="LabEx Student" python-app-env

Cette fois, vous devriez voir votre nom personnalisé dans la salutation :

Hello, LabEx Student, from the Docker container!
Current date and time: 2023-10-12 16:35:15.789012
Container is running...

Appuyez sur Ctrl+C pour arrêter l'affichage des journaux.

Arrêtez et supprimez le conteneur :

docker stop python-env-container
docker rm python-env-container

L'utilisation de variables d'environnement est une pratique courante dans Docker pour rendre vos conteneurs plus configurables sans avoir à reconstruire l'image pour de petites modifications.

Utilisation de ENTRYPOINT vs CMD dans Dockerfile

Dans Docker, il existe deux instructions pour spécifier quelle commande doit s'exécuter au démarrage d'un conteneur : CMD et ENTRYPOINT. Elles ont des objectifs et des comportements différents, et comprendre la différence est important pour la gestion des conteneurs.

Comprendre ENTRYPOINT et CMD

  • ENTRYPOINT : Définit l'exécutable qui s'exécutera au démarrage du conteneur. Il est plus difficile de le remplacer au moment de l'exécution.
  • CMD : Fournit des arguments par défaut pour l'ENTRYPOINT ou peut spécifier l'intégralité de la commande si ENTRYPOINT n'est pas utilisé. Il est facile de le remplacer au moment de l'exécution.

Explorons la différence en créant deux Dockerfiles différents.

Tout d'abord, créez un nouveau script Python qui accepte les arguments de ligne de commande :

nano greeting.py

Ajoutez le code suivant :

import sys

print("Script started!")

if len(sys.argv) > 1:
    print(f"Arguments provided: {sys.argv[1:]}")
    for arg in sys.argv[1:]:
        print(f"- {arg}")
else:
    print("No arguments provided.")

print("Script finished!")

Enregistrez et quittez nano.

Maintenant, créons un Dockerfile qui utilise CMD :

nano Dockerfile.cmd

Ajoutez le contenu suivant :

FROM python:3.9-slim

WORKDIR /app

COPY greeting.py .

CMD ["python", "greeting.py", "default", "arguments"]

Enregistrez et quittez nano.

Construisez l'image :

docker build -t python-cmd -f Dockerfile.cmd .

Maintenant, créez un autre Dockerfile qui utilise ENTRYPOINT :

nano Dockerfile.entrypoint

Ajoutez le contenu suivant :

FROM python:3.9-slim

WORKDIR /app

COPY greeting.py .

ENTRYPOINT ["python", "greeting.py"]
CMD ["default", "arguments"]

Enregistrez et quittez nano.

Construisez l'image :

docker build -t python-entrypoint -f Dockerfile.entrypoint .

Tester CMD vs ENTRYPOINT

Exécutons des conteneurs à partir des deux images et observons les différences.

Tout d'abord, exécutez un conteneur en utilisant l'image CMD sans arguments supplémentaires :

docker run --name cmd-container python-cmd

La sortie devrait être similaire à :

Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!

Maintenant, exécutez un conteneur avec l'image CMD mais fournissez des arguments personnalisés :

docker run --name cmd-container-custom python-cmd hello world

Sortie :

Script started!
No arguments provided.
Script finished!

Notez que l'intégralité de la commande a été remplacée par hello world, qui ne sont pas passés comme arguments à notre script.

Maintenant, exécutons un conteneur en utilisant l'image ENTRYPOINT sans arguments supplémentaires :

docker run --name entrypoint-container python-entrypoint

Sortie :

Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!

Enfin, exécutez un conteneur avec l'image ENTRYPOINT et fournissez des arguments personnalisés :

docker run --name entrypoint-container-custom python-entrypoint hello world

Sortie :

Script started!
Arguments provided: ['hello', 'world']
- hello
- world
Script finished!

Cette fois, nos arguments sont correctement passés au script Python car ENTRYPOINT définit l'exécutable, et tous les arguments supplémentaires fournis à docker run sont passés à cet exécutable.

Bonnes pratiques

  • Utilisez ENTRYPOINT pour les conteneurs qui doivent toujours exécuter une commande spécifique (comme notre script Python)
  • Utilisez CMD pour fournir des arguments par défaut qui peuvent être facilement remplacés
  • Combinez les deux en utilisant ENTRYPOINT pour la commande et CMD pour les arguments par défaut

Nettoyez les conteneurs :

docker rm cmd-container cmd-container-custom entrypoint-container entrypoint-container-custom

Vous avez maintenant appris la différence entre CMD et ENTRYPOINT dans Docker, ce qui est essentiel pour contrôler comment vos scripts Python s'exécutent au démarrage d'un conteneur.

Résumé

Dans ce lab, vous avez appris à exécuter des scripts Python au démarrage d'un conteneur Docker. Voici ce que vous avez accompli :

  1. Création d'un script Python simple qui s'exécute dans un conteneur Docker
  2. Construction d'une image Docker avec un Dockerfile
  3. Exécution d'un conteneur Docker qui exécute automatiquement le script Python
  4. Utilisation de variables d'environnement pour configurer votre application Python dans Docker
  5. Compréhension de la différence entre CMD et ENTRYPOINT dans les Dockerfiles

Ces compétences sont fondamentales pour la conteneurisation des applications Python et l'automatisation de leur déploiement. Vous pouvez maintenant :

  • Emballer vos applications Python avec toutes leurs dépendances
  • Configurer vos applications à l'aide de variables d'environnement
  • Contrôler comment vos applications démarrent à l'intérieur des conteneurs Docker
  • Choisir le mécanisme de démarrage approprié (CMD ou ENTRYPOINT) pour votre cas d'utilisation spécifique

Grâce à ces connaissances, vous pouvez créer des applications Docker plus complexes qui exécutent des scripts Python automatiquement au démarrage, ce qui rend votre processus de déploiement plus efficace et fiable.