Hello! Welcome to the first lesson in our module on MLOps and Model Deployment.
In our previous module, we focused on building and refining powerful AI models, culminating in implementing safety guardrails. But a model sitting in a notebook is like a brilliant blueprint that never becomes a building. The crucial next step is to get your model out into the world where it can provide real value. This is the domain of MLOps (Machine Learning Operations).
This lesson marks our first step into MLOps. We'll tackle one of the most fundamental challenges in software deployment: ensuring that an application that works on your machine also works reliably everywhere else. To do this, we'll learn how to containerize ML applications using Docker.
By the end of this lesson, you will be able to:
- Explain what containerization is and why it's essential for deploying ML applications.
- Understand the key Docker concepts: images and containers.
- Write a
Dockerfileto package a Python ML application. - Build, run, and manage your containerized application.
- Share your application with the world using Docker Hub.
1. The Deployment Problem and the Container Solution
Imagine you've built a fantastic ML model served via a Flask API. It works perfectly on your Windows machine with Python 3.9 and scikit-learn version 1.3.0. Now, you hand it over to a colleague who uses a Mac with Python 3.10, or you try to deploy it to a Linux server in the cloud. Suddenly, nothing works. This is the "it works on my machine" problem, a classic headache in software development caused by differences in operating systems, library versions, and environment configurations.
Containerization solves this problem by packaging your application, along with all its dependencies, libraries, and configuration files, into a single, isolated, and portable unit called a container.
Complete Dockers For Data Science Tutorial In One Shot
To understand the core problem that containers solve, let's watch this explanation from Krish Naik. He clearly illustrates the chaos of managing dependencies across different developer and server environments.
Watch the segment from 01:23 to 07:10. Focus on how inconsistencies in libraries and configurations between development, QA, and production environments can cause applications to fail, and how containers are presented as the solution.
As the video explains, a container acts like a standardized shipping container for your software. It ensures that your application runs the same way, no matter where it's deployed.
Containers vs. Virtual Machines (VMs)
You might have heard of Virtual Machines (VMs), which also provide isolated environments. However, they work very differently. A VM emulates an entire computer, including a full guest operating system, making it very large and slow to start.
Containers are much more lightweight. They share the host system's operating system kernel, only packaging the application and its specific dependencies.
How to Containerize an Application Using Docker - DataCamp
This article from DataCamp provides a concise comparison between containers and virtual machines. The table is particularly helpful for a quick overview.
Read the first part of the article, up to and including the table under the heading 'Containers vs virtual machines'. This will clarify the architectural and performance differences.
For ML applications, the lightweight and fast nature of containers is a huge advantage, allowing for rapid scaling and efficient resource use.
2. Docker: Images and Containers
Docker is the leading platform for creating and managing containers. To work with Docker, you need to understand two fundamental concepts: Images and Containers.
- Docker Image: A static, read-only blueprint that contains everything needed to run an application: the code, a runtime (like Python), libraries, and environment variables. Think of it as a class in object-oriented programming.
- Docker Container: A running instance of a Docker image. It's the live, executing environment where your application runs. Think of it as an object or an instance of a class.
You build an image once, and you can use it to create and run many identical containers.

Complete Dockers For Data Science Tutorial In One Shot
Let's reinforce the distinction between an image and a container. This video provides a clear explanation.
Watch from 12:57 to 16:30. Pay attention to the analogy: the Docker image is the entire package of dependencies, and the container is the running environment created from that package.
3. Setting Up Your Docker Environment
Before we can build anything, you need to install Docker on your machine. The most common way to do this is by installing Docker Desktop.
How to Containerize an Application Using Docker - DataCamp
This DataCamp article provides straightforward installation instructions for Windows, macOS, and Linux.
Follow the instructions in the sections 'Step 1: Installing Docker' and 'Step 2: Verify Docker installation'. Make sure you can successfully run docker run hello-world.
Important Note: As mentioned in the video from Krish Naik (at 00:29:45), on some systems (especially Windows), you may need to enable virtualization in your computer's BIOS/UEFI settings. If you encounter errors during installation, this is the first thing to check.
4. Hands-On: Containerizing an ML API
Now for the practical part. We'll take a simple ML model, wrap it in a Flask API, and then containerize it with Docker.
Step 1: Prepare the ML Application
First, create a new project directory. Inside this directory, create two files: app.py and requirements.txt.
app.py:
This script loads the Iris dataset from scikit-learn, trains a simple Random Forest model, and exposes a /predict endpoint using Flask.
# app.py
from flask import Flask, request, jsonify
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import numpy as np
# Initialize Flask app
app = Flask(__name__)
# Load and prepare the model
iris = load_iris()
X, y = iris.data, iris.target
X_train, _, y_train, _ = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)
@app.route('/predict', methods=['POST'])
def predict():
# Get features from the JSON request
data = request.get_json()
features = data['features']
# Make prediction
prediction = model.predict([features])
# Return the prediction as JSON
return jsonify({
'prediction': int(prediction[0]),
'class_name': iris.target_names[prediction[0]]
})
if __name__ == '__main__':
# Run the app, accessible from outside the container
app.run(host='0.0.0.0', port=5000)
Note the host='0.0.0.0'. This is crucial for making the Flask app accessible from outside the Docker container.
requirements.txt:
This file lists the Python libraries our application needs. Pinning versions is a best practice for ensuring reproducibility.
# requirements.txt
scikit-learn==1.3.0
numpy==1.24.3
Flask==2.2.2
Step 2: Write the Dockerfile
The Dockerfile is a script that contains the step-by-step instructions for building our Docker image. In your project directory, create a file named Dockerfile (with no file extension).
# 1. Use an official Python runtime as a parent image
FROM python:3.9-slim
# 2. Set the working directory in the container
WORKDIR /app
# 3. Copy the dependencies file first to leverage Docker cache
COPY requirements.txt .
# 4. Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# 5. Copy the application code into the container
COPY . .
# 6. Make port 5000 available to the world outside this container
EXPOSE 5000
# 7. Define the command to run the application
CMD ["python", "app.py"]
Let's break this down:
FROM python:3.9-slim: Every Docker image starts from a base image. We're using a lightweight ("slim") official Python 3.9 image.WORKDIR /app: Sets the default directory for all subsequent commands inside the container.COPY requirements.txt .: Copies only therequirements.txtfile into the container. We do this first to take advantage of Docker's layer caching. Since dependencies rarely change, this layer won't need to be rebuilt often, speeding up future builds.RUN pip install ...: Executes the command to install our Python libraries.--no-cache-dirkeeps the image size smaller.COPY . .: Copies the rest of our application code (likeapp.py) into the container.EXPOSE 5000: Informs Docker that the container listens on port 5000. This is documentation; it doesn't actually publish the port.CMD ["python", "app.py"]: Specifies the default command to run when the container starts.

Step 3: Build the Docker Image
Now, open your terminal in the project directory and run the docker build command.
# The -t flag "tags" (names) our image as 'ml-iris-app'.
# The '.' at the end specifies the build context (the current directory).
docker build -t ml-iris-app .
You'll see Docker execute each step from your Dockerfile.
Step 4: Run the Docker Container
Once the image is built, run it as a container with the docker run command.
# The -p flag "publishes" a port, mapping port 5000 on your host machine
# to port 5000 inside the container.
docker run -p 5000:5000 ml-iris-app
Your terminal will now show the output from the Flask server, indicating that your containerized application is running!
Step 5: Test the Containerized Application
Open a new terminal window (leave the container running in the first one) and use curl to send a POST request to your API. We'll send the features for an Iris setosa flower.
curl -X POST -H "Content-Type: application/json" \
-d '{"features": [5.1, 3.5, 1.4, 0.2]}' \
http://localhost:5000/predict
You should receive a successful JSON response:
{"class_name":"setosa","prediction":0}
Congratulations! You've successfully containerized and run your first ML application.
5. Managing and Sharing Your Containers
Your work with Docker doesn't stop after you run a container. You also need to know how to manage it.
Essential Management Commands
Here are a few commands you'll use all the time. Run these in your terminal.
-
List running containers:
docker ps -
Stop a container (use the CONTAINER ID from
docker ps):docker stop <your-container-id> -
View logs from a container (extremely useful for debugging):
docker logs <your-container-id> -
List all containers (including stopped ones):
docker ps -a -
List all images on your machine:
docker images
Sharing Your Image on Docker Hub
Docker Hub is a public registry for Docker images, like GitHub for code. Pushing your image there allows anyone to pull and run your containerized application.
Complete Dockers For Data Science Tutorial In One Shot
This video provides a clear, step-by-step guide on how to push your custom image to Docker Hub.
Watch from 52:43 to 58:20. Follow the process: Log in using docker login. Tag your local image with your Docker Hub username (docker tag local-image:tag username/repo-name:tag). This step is crucial. Push the image using docker push username/repo-name:tag.
By following these steps, you can share your ml-iris-app with colleagues or deploy it to any cloud provider that supports Docker containers.
Conclusion
In this lesson, you've taken a massive step from being a model developer to becoming a deployment-ready engineer. You learned how to solve the "it works on my machine" problem by packaging an ML application into a portable, reproducible container with Docker.
Key Takeaways:
- Containerization bundles an application with its dependencies, ensuring it runs consistently across any environment.
- Docker Images are the static blueprints, while Docker Containers are the live, running instances of those images.
- The
Dockerfileis the recipe for building an image, with commands likeFROM,WORKDIR,COPY,RUN, andCMD. - Optimizing your
Dockerfile(e.g., copyingrequirements.txtfirst) can significantly speed up build times. - The
docker build,docker run, anddocker pushcommands are the core workflow for building, running, and sharing containerized applications.
Preview of the Next Lesson:
Now that we can package our applications, a new set of questions arises. How do we track which version of a model is inside a container? How do we compare the performance of different models we've trained? In our next lesson, you will learn to track experiments and model versions using MLflow, another cornerstone tool in the MLOps toolkit.