Как запустить сценарий на Python при запуске контейнера Docker

DockerDockerBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Introduction

Docker is a powerful tool for containerizing applications, making it easier to develop, deploy, and manage software. In this tutorial, we will explore how to run a Python script when a Docker container starts. This approach allows you to automate your application deployment and streamline your development workflow. By the end of this lab, you will be able to create a Docker container that automatically executes your Python script on startup.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/start("Start Container") docker/ContainerOperationsGroup -.-> docker/stop("Stop Container") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ContainerOperationsGroup -.-> docker/create("Create Container") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/ps -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/start -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/stop -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/rm -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/logs -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/create -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} docker/build -.-> lab-410107{{"Как запустить сценарий на Python при запуске контейнера Docker"}} end

Creating a Simple Python Script

In this first step, we will create a simple Python script that will be executed when our Docker container starts. This script will print a message and the current date and time.

Let's start by creating a new directory for our project:

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

Now, let's create a simple Python script called app.py using the nano text editor:

nano app.py

In the nano editor, add the following Python code:

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)

Save the file by pressing Ctrl+O, then Enter, and exit nano by pressing Ctrl+X.

This script will:

  1. Print a welcome message
  2. Display the current date and time
  3. Keep the container running with a message every 10 seconds

Let's test our Python script to make sure it works correctly:

python3 app.py

You should see output similar to:

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.

Press Ctrl+C to stop the script.

Now that we have a working Python script, we can proceed to create a Docker container that will run this script when it starts.

Creating a Dockerfile

Now that we have our Python script ready, let's create a Dockerfile to define how our Docker container should be built.

A Dockerfile is a text file that contains all the commands needed to build a Docker image. This image will contain our Python script and all the necessary dependencies.

In the same directory (~/project/python-docker), create a new file named Dockerfile:

nano Dockerfile

Add the following content to the 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"]

Save and exit nano by pressing Ctrl+O, then Enter, and then Ctrl+X.

Let's understand what each line in the Dockerfile does:

  1. FROM python:3.9-slim: This specifies the base image to use. We're using the official Python 3.9 image with a slim variant to keep the size small.

  2. WORKDIR /app: This sets the working directory inside the container to /app.

  3. COPY app.py .: This copies our Python script from the host machine to the current working directory in the container (which is /app).

  4. CMD ["python", "app.py"]: This specifies the command to run when the container starts. In this case, it will run our Python script.

Now, let's build our Docker image using this Dockerfile:

docker build -t python-app .

This command builds a Docker image from the Dockerfile in the current directory (.) and tags it with the name python-app (-t stands for tag).

You should see output similar to:

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

The output may vary, but you should see "Successfully built" and "Successfully tagged" messages if everything went well.

You've now successfully created a Docker image that contains your Python script and will run it when a container is started from this image.

Running the Docker Container

Now that we have built our Docker image, we can run a container based on this image. The container will automatically execute our Python script when it starts.

To run a container from our image, use the following command:

docker run --name python-container python-app

This command starts a new container named python-container from the python-app image we created in the previous step.

You should see output similar to:

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.

The container is now running and executing our Python script. The script is designed to keep running indefinitely, printing a message every 10 seconds.

Press Ctrl+C to stop viewing the logs, but note that the container is still running in the background.

To verify that the container is running, use the following command:

docker ps

You should see your container in the list of running containers:

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

To stop the container, use the following command:

docker stop python-container

To start the container again, use:

docker start python-container

And to view the logs of the running container:

docker logs python-container

This will show the output of our Python script. You can press Ctrl+C to exit the logs view.

To remove the container when you're done, first stop it if it's running, then remove it:

docker stop python-container
docker rm python-container

You have now successfully created and run a Docker container that executes a Python script on startup.

Using Environment Variables with Python in Docker

Environment variables are a great way to configure your application without changing the code. In this step, we'll modify our Python script to use environment variables and update our Dockerfile to provide these variables.

First, let's update our Python script to read an environment variable:

nano app.py

Modify the script to include environment variable support:

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)

Save and exit nano by pressing Ctrl+O, then Enter, and then Ctrl+X.

Now, let's update our Dockerfile to include an environment variable:

nano Dockerfile

Update the Dockerfile to include the environment variable:

## 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"]

Save and exit nano, then rebuild the Docker image:

docker build -t python-app-env .

Now, run a container with the default environment variable:

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

You should see a greeting with "Docker User" in the output:

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

Press Ctrl+C to stop viewing the logs.

Stop and remove the container:

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

You can also override the environment variable when running the container:

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

This time, you should see your custom name in the greeting:

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

Press Ctrl+C to stop viewing the logs.

Stop and remove the container:

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

Using environment variables is a common practice in Docker to make your containers more configurable without having to rebuild the image for small changes.

Using ENTRYPOINT vs CMD in Dockerfile

In Docker, there are two instructions for specifying what command should run when a container starts: CMD and ENTRYPOINT. They have different purposes and behaviors, and understanding the difference is important for container management.

Understanding ENTRYPOINT and CMD

  • ENTRYPOINT: Defines the executable that will run when the container starts. It's harder to override at runtime.
  • CMD: Provides default arguments for the ENTRYPOINT or can specify the entire command if ENTRYPOINT is not used. It's easy to override at runtime.

Let's explore the difference by creating two different Dockerfiles.

First, create a new Python script that accepts command-line arguments:

nano greeting.py

Add the following code:

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!")

Save and exit nano.

Now, let's create a Dockerfile that uses CMD:

nano Dockerfile.cmd

Add the following content:

FROM python:3.9-slim

WORKDIR /app

COPY greeting.py .

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

Save and exit nano.

Build the image:

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

Now, create another Dockerfile that uses ENTRYPOINT:

nano Dockerfile.entrypoint

Add the following content:

FROM python:3.9-slim

WORKDIR /app

COPY greeting.py .

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

Save and exit nano.

Build the image:

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

Testing CMD vs ENTRYPOINT

Let's run containers from both images and observe the differences.

First, run a container using the CMD image without additional arguments:

docker run --name cmd-container python-cmd

Output should be similar to:

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

Now, run a container with the CMD image but provide custom arguments:

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

Output:

Script started!
No arguments provided.
Script finished!

Notice that the entire command was replaced with hello world, which are not passed as arguments to our script.

Now, let's run a container using the ENTRYPOINT image without additional arguments:

docker run --name entrypoint-container python-entrypoint

Output:

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

Finally, run a container with the ENTRYPOINT image and provide custom arguments:

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

Output:

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

This time, our arguments are properly passed to the Python script because ENTRYPOINT defines the executable, and any additional arguments provided to docker run are passed to that executable.

Best Practices

  • Use ENTRYPOINT for containers that should always run a specific command (like our Python script)
  • Use CMD to provide default arguments that can be easily overridden
  • Combine both by using ENTRYPOINT for the command and CMD for default arguments

Clean up the containers:

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

You've now learned the difference between CMD and ENTRYPOINT in Docker, which is essential for controlling how your Python scripts run when a container starts.

Summary

In this lab, you've learned how to run Python scripts when a Docker container starts. Here's what you've accomplished:

  1. Created a simple Python script that runs in a Docker container
  2. Built a Docker image with a Dockerfile
  3. Ran a Docker container that automatically executes the Python script
  4. Used environment variables to configure your Python application in Docker
  5. Understood the difference between CMD and ENTRYPOINT in Dockerfiles

These skills are fundamental for containerizing Python applications and automating their deployment. You can now:

  • Package your Python applications with all their dependencies
  • Configure your applications using environment variables
  • Control how your applications start inside Docker containers
  • Choose the appropriate startup mechanism (CMD or ENTRYPOINT) for your specific use case

With this knowledge, you can build more complex Docker applications that run Python scripts automatically on startup, making your deployment process more efficient and reliable.