Week-5: Understanding Docker and Docker Compose

Mohammad Zeynali
4 min readSep 4, 2024

--

Docker and Docker Compose have revolutionized the way developers build, ship, and run applications by providing isolated environments and seamless orchestration. In this blog post, we’ll walk through a practical example of using Docker and Docker Compose to deploy a Python-based web application. This guide will highlight the essentials of setting up a Docker container and orchestrating it with Docker Compose, ensuring your application runs smoothly in any environment.

🔙 Previous: Week-4: Converting and Running Machine Learning Models with ONNX

🔜 Next:

Understanding Docker: The Container Powerhouse

Docker is a platform that allows developers to automate the deployment of applications inside lightweight, portable containers. These containers encapsulate all the dependencies your application needs, ensuring that it runs consistently, regardless of where it is deployed. The magic happens with the use of a Dockerfile—a script that contains a series of instructions Docker uses to build a container image.

Here’s a simple example of a Dockerfile for a Python web application:

FROM python:3.11-slim
COPY ./ /app
WORKDIR /app
RUN pip install -r requirements_prod.txt
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Breaking Down the Dockerfile

  1. Base Image: FROM python:3.11-slim - This line specifies the base image for the container, which in this case is a slim version of Python 3.11. This base image is minimal and ideal for production environments as it reduces the size of the container.
  2. Copying Application Code: COPY ./ /app - Copies the current directory's contents into the /app directory inside the container. This includes all the application code and dependencies.
  3. Setting the Working Directory: WORKDIR /app - Sets /app as the working directory within the container. All subsequent commands will be run from this location.
  4. Installing Dependencies: RUN pip install -r requirements_prod.txt - Installs the necessary Python dependencies specified in requirements_prod.txt. This ensures the container has all the libraries required to run the application.
  5. Setting Environment Variables: ENV LC_ALL=C.UTF-8 and ENV LANG=C.UTF-8 - These environment variables ensure that the container uses UTF-8 encoding, preventing any locale-related issues during runtime.
  6. Exposing Ports: EXPOSE 8000 - Tells Docker that the container listens on port 8000. This is crucial for mapping ports from the host machine to the container.
  7. Running the Application: CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"] - This command specifies the default command to run when the container starts. It launches the Uvicorn server, a lightweight ASGI server, on port 8000, hosting the FastAPI application defined in app.py.

Simplifying Multi-Container Deployments with Docker Compose

While Docker provides an excellent solution for containerizing individual applications, Docker Compose takes it a step further by allowing developers to define and run multi-container Docker applications. With Docker Compose, you can manage all the services your application requires, such as databases, caches, and web servers, in a single file.

Below is an example docker-compose.yml file for orchestrating the deployment of the Python web application:

version: "3"
services:
prediction_api:
build: .
container_name: "inference_container"
ports:
- "8000:8000"

Understanding the Docker Compose File

  1. Version: version: "3" - Specifies the version of the Docker Compose file format.
  2. Services: The services section defines each container that will run as part of the application stack. In this example, there is only one service, prediction_api.
  3. Service Definition:
  • build: build: . - Tells Docker Compose to build the Docker image for this service using the Dockerfile located in the current directory.
  • container_name: container_name: "inference_container" - Assigns a name to the container for easier identification and management.
  • ports: ports: - "8000:8000" - Maps port 8000 on the host machine to port 8000 on the container, allowing external access to the application.

Deploying Your Application

To deploy your application using Docker and Docker Compose, follow these steps:

  1. Build the Docker Image: Run the command docker build -t my-python-app . in your terminal, where my-python-app is the name you want to assign to your Docker image. This command reads the Dockerfile, builds the image, and tags it appropriately.
  2. Start the Application with Docker Compose: Run docker-compose up in your terminal. This command reads the docker-compose.yml file, builds the necessary image, and starts the container.
  3. Access Your Application: Open your browser and navigate to http://localhost:8000. You should see your Python web application running!

Here are codes:

Conclusion

By leveraging Docker and Docker Compose, you can create robust, scalable environments for your applications. Docker ensures consistency and portability, while Docker Compose simplifies multi-container orchestration. Together, they provide a powerful toolset for developers looking to streamline their deployment processes and enhance the reliability of their applications.

Whether you’re running a simple web service or a complex application stack, Docker and Docker Compose enable you to deploy with confidence and ease. So start containerizing your applications today and experience the benefits of a Docker-powered development workflow!

--

--

Mohammad Zeynali

Generative AI | Data Scientist l Machine Learning Engineer | MLOps l Edge Architect