Python tutorials > Deployment > Containerization > How to build/run Docker images?

How to build/run Docker images?

This tutorial covers building and running Docker images, essential skills for containerizing Python applications for deployment. We'll explore the Dockerfile, Docker Compose, and commands for image creation and execution.

Prerequisites

Before you begin, ensure you have the following installed:

  1. Docker: Download and install Docker Desktop for your operating system from the official Docker website.
  2. Python: Ensure Python is installed. This tutorial focuses on the Docker aspects, not Python itself.

Creating a Dockerfile

The Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Let's break down each line:

  • FROM python:3.9-slim-buster: Specifies the base image. Here, we are using a lightweight Python 3.9 image based on Debian.
  • WORKDIR /app: Sets the working directory inside the container to /app.
  • COPY requirements.txt .: Copies the requirements.txt file (if you have one) from your local directory to the /app directory in the container.
  • RUN pip install --no-cache-dir -r requirements.txt: Installs the Python dependencies listed in requirements.txt. --no-cache-dir helps reduce image size.
  • COPY . .: Copies all files from your local directory to the /app directory in the container.
  • CMD ["python", "app.py"]: Specifies the command to run when the container starts. This assumes you have an app.py file which is the entry point of your application.

FROM python:3.9-slim-buster

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "app.py"]

Building the Docker Image

To build the Docker image, navigate to the directory containing your Dockerfile and run the following command in your terminal:

  • docker build: The Docker build command.
  • -t my-python-app: Tags the image with the name my-python-app. You can choose any name you like.
  • .: Specifies the build context, which is the current directory. Docker will look for the Dockerfile in this directory.

This command will build the image based on the instructions in your Dockerfile. You'll see output as each instruction is executed.

docker build -t my-python-app .

Running the Docker Image

To run the Docker image, use the following command:

  • docker run: The Docker run command.
  • -d: Runs the container in detached mode (in the background).
  • -p 5000:5000: Maps port 5000 on your host machine to port 5000 inside the container. This is important if your application exposes a port. Change the ports if your app uses different ones.
  • my-python-app: The name of the image you want to run.

This command will start the container based on your image. If your application is a web server listening on port 5000, you can access it by navigating to http://localhost:5000 in your browser.

docker run -d -p 5000:5000 my-python-app

Using Docker Compose (Optional)

Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file (docker-compose.yml) to configure your application's services. Here's a basic example:

  • version: "3.9": Specifies the Docker Compose file version.
  • services: Defines the services that make up your application.
  • web: The name of the service (you can choose any name).
  • build: .: Specifies that the image should be built from the Dockerfile in the current directory.
  • ports: Defines port mappings, similar to the -p flag in docker run.

To start your application using Docker Compose, navigate to the directory containing your docker-compose.yml file and run:

docker-compose up -d

This will build the image and start the container in detached mode.

version: "3.9"
services:
  web:
    build: .
    ports:
      - "5000:5000"

Concepts Behind the Snippet

The core concept revolves around isolating your application and its dependencies within a container. The Dockerfile provides instructions for creating a reproducible environment. The docker build command transforms these instructions into an image, which is a snapshot of your application and its runtime environment. The docker run command then creates a container from this image, essentially running your application in an isolated environment.

Real-Life Use Case Section

Imagine you're deploying a Flask web application. Without Docker, you need to ensure the server environment has the correct Python version, Flask, and all other dependencies. This can be time-consuming and error-prone, especially when deploying to multiple environments (development, staging, production). Docker solves this by packaging the application and its dependencies into a single, portable container. You can then deploy this container to any environment that has Docker installed, guaranteeing consistency and reproducibility.

Best Practices

  • Use a specific base image version: Avoid using latest tag. Always specify a specific version (e.g., python:3.9-slim-buster) for reproducibility.
  • Minimize image size: Use multi-stage builds to reduce the final image size by only including necessary components.
  • Use .dockerignore: Create a .dockerignore file to exclude unnecessary files from being copied into the image, further reducing its size and build time. Include things like .git, __pycache__, and virtual environment directories.
  • Security: Keep your base images updated to patch security vulnerabilities. Use a non-root user inside the container for added security.
  • Health Checks: Implement health checks in your Dockerfile to allow Docker to monitor the health of your application and restart it if it becomes unhealthy.

Interview Tip

When discussing Docker, be prepared to explain the concepts of images and containers, the role of a Dockerfile, and the benefits of containerization. Demonstrate your understanding of Docker commands like build, run, and compose. Mentioning best practices like minimizing image size and ensuring security will also impress your interviewer.

When to use them

Use Docker when you need to:

  • Package an application and its dependencies into a single, portable unit.
  • Ensure consistent behavior across different environments (development, staging, production).
  • Scale your application horizontally by running multiple containers.
  • Simplify deployment and management of complex applications.

Memory footprint

Docker containers generally have a smaller memory footprint compared to virtual machines because they share the host OS kernel. However, the memory footprint depends on the application running inside the container and the base image used. Using slim base images like python:3.9-slim-buster can help minimize the memory footprint.

Alternatives

Alternatives to Docker include:

  • Podman: A container engine that can run containers without requiring root privileges.
  • LXC/LXD: System containers, which provide a more lightweight alternative to virtual machines.
  • Virtual Machines (VMs): Provide full OS virtualization, offering greater isolation but with a higher overhead.

Pros

  • Portability: Containers can run on any platform that supports Docker.
  • Isolation: Containers isolate applications from each other and the host system.
  • Scalability: Easy to scale applications by running multiple containers.
  • Reproducibility: Dockerfiles ensure consistent build and deployment processes.

Cons

  • Learning Curve: Requires understanding of Docker concepts and commands.
  • Resource Overhead: While less than VMs, containers still consume resources.
  • Security Considerations: Improperly configured containers can introduce security risks.

FAQ

  • What is the difference between an image and a container?

    An image is a read-only template that contains the instructions for creating a container. A container is a runnable instance of an image.

  • How do I stop a running container?

    You can stop a running container using the command: docker stop <container_id>. You can find the container ID using docker ps.

  • How do I remove a Docker image?

    You can remove a Docker image using the command: docker rmi <image_id>. You can find the image ID using docker images.