Docker for Machine Learning – Complete Step-by-Step Tutorial
1. What is Docker?
Docker is a tool that packages your application and everything it needs into a container.
For a Machine Learning project, your application may need:
- Python
- NumPy
- Pandas
- Scikit-learn
- Flask
- Your trained model
- Your Python code
Without Docker, you install all these things directly on your computer.
With Docker, we put them inside a container.
The basic idea is:
Machine Learning Project
↓
Dockerfile
↓
Docker Image
↓
Docker Container
↓
ML Application
JavaScript2. What will we build?
We will create a very simple ML application.
Our project will:
- Train a Machine Learning model.
- Save the model.
- Create an API using Flask.
- Create a Dockerfile.
- Build a Docker image.
- Run the image as a container.
- Access the ML application through a browser.
- Send data to the model for prediction.
3. Install the required software
You need:
Python
Check Python:
python --version
JavaScriptExample:
Python 3.11.9
JavaScriptDocker Desktop
Install Docker Desktop on Windows.
After installation, open Docker Desktop and make sure Docker is running.
Check Docker:
docker --version
JavaScriptExample:
Docker version 28.x.x
JavaScriptAlso check:
docker info
JavaScriptIf Docker is running, you will see Docker information.
4. Create the project folder
Create a folder called:
ML_Project
JavaScriptFor example:
E:\ML_Project
JavaScriptOpen this folder in VS Code.
Your project will eventually look like this:
ML_Project/
│
├── Dockerfile
├── app.py
├── model.py
├── model.pkl
└── requirements.txt
JavaScript5. Create the Machine Learning model
Create a file:
model.py
JavaScriptPut this code inside:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import joblib
# Load dataset
iris = load_iris()
X = iris.data
y = iris.target
# Split data
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
# Create model
model = LogisticRegression(max_iter=200)
# Train model
model.fit(X_train, y_train)
# Save model
joblib.dump(model, "model.pkl")
print("Model trained successfully!")
print("Model saved as model.pkl")
JavaScript6. Install the ML libraries
Before Docker, we can test the Python project locally.
Open the VS Code terminal.
Run:
pip install scikit-learn joblib
JavaScriptThen run:
python model.py
JavaScriptYou should see:
Model trained successfully!
Model saved as model.pkl
JavaScriptA new file should appear:
model.pkl
JavaScriptThis is our trained ML model.
7. Create the Flask application
Now create:
app.py
JavaScriptAdd:
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
# Load trained model
model = joblib.load("model.pkl")
@app.route("/")
def home():
return "Machine Learning API is running!"
@app.route("/predict", methods=["POST"])
def predict():
data = request.json
features = data["features"]
prediction = model.predict([features])
return jsonify({
"prediction": int(prediction[0])
})
if __name__ == "__main__":
app.run(
host="0.0.0.0",
port=5000
)
JavaScript8. Understand app.py
The first line:
from flask import Flask, request, jsonify
JavaScriptimports Flask and some useful functions.
This:
app = Flask(__name__)
JavaScriptcreates our Flask application.
This:
model = joblib.load("model.pkl")
JavaScriptloads our trained ML model.
9. Create the home API
We have:
@app.route("/")
def home():
return "Machine Learning API is running!"
JavaScriptWhen we open:
http://localhost:5000
JavaScriptthe application will return:
Machine Learning API is running!
JavaScript10. Create the prediction API
We created:
@app.route("/predict", methods=["POST"])
JavaScriptThis means our application has a prediction endpoint:
/predict
JavaScriptIt expects data like:
{
"features": [5.1, 3.5, 1.4, 0.2]
}
JavaScriptThe model receives these values and makes a prediction.
11. Create requirements.txt
Now create:
requirements.txt
JavaScriptPut this inside:
Flask
scikit-learn
joblib
JavaScriptThis file tells Docker which Python packages our application needs.
Think of it like a shopping list:
Flask
scikit-learn
joblib
JavaScriptDocker will install these packages inside the container.
12. Test the application without Docker
Before using Docker, first test the application normally.
Run:
python app.py
JavaScriptYou should see something similar to:
* Running on http://127.0.0.1:5000
JavaScriptOpen your browser:
http://localhost:5000
JavaScriptYou should see:
Machine Learning API is running!
JavaScriptPress:
CTRL + C
JavaScriptin the terminal to stop the application.
13. Now create the Dockerfile
This is the most important part.
Create a file with the exact name:
Dockerfile
JavaScriptImportant:
Do NOT name it:
Dockerfile.txt
JavaScriptDo NOT name it:
Dockerfile 1
JavaScriptThe filename must simply be:
Dockerfile
JavaScript14. Add Dockerfile code
Put this inside the Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
JavaScriptSave the file.
15. Understand the Dockerfile
Let’s understand every line.
FROM
FROM python:3.11-slim
JavaScriptThis tells Docker:
Start with a Python 3.11 environment.
We are using the slim version because it is smaller.
16. WORKDIR
WORKDIR /app
JavaScriptThis creates/uses:
/app
JavaScriptinside the container.
From this point, Docker will work inside /app.
17. COPY requirements.txt
COPY requirements.txt .
JavaScriptThis copies:
requirements.txt
JavaScriptfrom our computer into the Docker container.
18. RUN pip install
RUN pip install --no-cache-dir -r requirements.txt
JavaScriptDocker now installs:
Flask
scikit-learn
joblib
JavaScriptinside the container.
19. COPY project files
COPY . .
JavaScriptThis copies our project files into the container.
For example:
app.py
model.py
model.pkl
requirements.txt
JavaScript20. EXPOSE
EXPOSE 5000
JavaScriptOur Flask application uses port:
5000
JavaScriptThis tells Docker that the application listens on port 5000.
Important:
EXPOSE does not itself publish the port to your computer.
We will publish it later using:
-p 5000:5000
JavaScript21. CMD
This is very important.
Use exactly:
CMD ["python", "app.py"]
JavaScriptThere must be a space between:
CMD
JavaScriptand:
["python", "app.py"]
JavaScriptCorrect:
CMD ["python", "app.py"]
JavaScriptIncorrect:
CMD["python", "app.py"]
JavaScriptThe incorrect version can produce:
unknown instruction: CMD["python"
JavaScript22. Final project structure
Before building the Docker image, your project should look like:
ML_Project/
│
├── Dockerfile
├── app.py
├── model.py
├── model.pkl
└── requirements.txt
JavaScriptCheck carefully that the file is:
Dockerfile
JavaScriptand not:
Dockerfile.txt
JavaScript23. Build the Docker image
Open the terminal inside the ML_Project folder.
Run:
docker build -t ml-project .
JavaScriptLet’s understand this command.
docker build
JavaScriptmeans:
Build a Docker image.
-t ml-project
JavaScriptmeans:
Give the image the name
ml-project.
.
JavaScriptmeans:
Use the current folder as the build context.
24. What happens during the build?
Docker reads:
Dockerfile
JavaScriptThen it performs these steps:
Dockerfile
↓
Python Image
↓
Create /app
↓
Copy requirements.txt
↓
Install libraries
↓
Copy project files
↓
Create final Image
JavaScriptIf everything works, you should see something similar to:
Successfully built ...
Successfully tagged ml-project:latest
JavaScript25. Check the Docker image
Run:
docker images
JavaScriptYou should see something similar to:
REPOSITORY TAG IMAGE ID
ml-project latest xxxxx
JavaScriptThis means our Docker image has been created.
26. What is a Docker Image?
Think about an image as a package/template.
It contains everything required to run our application.
For our project:
Docker Image
│
├── Python
├── Flask
├── Scikit-learn
├── Joblib
├── app.py
└── model.pkl
JavaScriptThe image itself is not the running application.
27. Run the Docker container
Now execute:
docker run -p 5000:5000 ml-project
JavaScriptThis command creates and starts a container from our image.
28. Understand -p 5000:5000
This part:
-p 5000:5000
JavaScriptmeans:
Computer Port : Container Port
JavaScriptSo:
Your computer
localhost:5000
↓
Docker container
port 5000
↓
Flask application
JavaScript29. Open the application
Open your browser.
Go to:
http://localhost:5000
JavaScriptYou should see:
Machine Learning API is running!
JavaScriptCongratulations.
Your Machine Learning application is now running inside Docker.
30. Test the prediction API
The /predict endpoint expects a POST request.
Example input:
{
"features": [5.1, 3.5, 1.4, 0.2]
}
JavaScriptThe API may return:
{
"prediction": 0
}
JavaScriptThe number represents the predicted Iris class.
31. How the complete system works
Now understand the complete flow:
model.py
↓
Train ML model
↓
model.pkl
↓
app.py
↓
Load model
↓
Create API
↓
requirements.txt
↓
List dependencies
↓
Dockerfile
↓
Build Image
↓
Docker Image
↓
Run Container
↓
ML API
↓
localhost:5000
JavaScript32. Image vs Container
This is one of the most important Docker concepts.
Image
Image is the package/template.
ML Image
│
├── Python
├── Libraries
├── Code
└── Model
JavaScriptContainer
Container is the running version of that image.
ML Image
↓
docker run
↓
ML Container
↓
Running Application
JavaScriptA simple way to remember:
Image = Package
Container = Running Package
JavaScript33. Check running containers
Open another terminal and run:
docker ps
JavaScriptYou may see:
CONTAINER ID
IMAGE
STATUS
PORTS
JavaScriptYour ml-project container should be there.
34. Stop the container
Find the container ID:
docker ps
JavaScriptThen:
docker stop CONTAINER_ID
JavaScriptFor example:
docker stop abc123
JavaScript35. Start an existing container again
List all containers:
docker ps -a
JavaScriptThen start the container:
docker start CONTAINER_ID
JavaScript36. Remove a container
If you want to delete a container:
docker rm CONTAINER_ID
JavaScript37. Remove the image
To delete the Docker image:
docker rmi ml-project
JavaScriptBe careful: remove containers using that image first if Docker says the image is still in use.
38. Common Docker commands
Check Docker version
docker --version
JavaScriptCheck running containers
docker ps
JavaScriptCheck all containers
docker ps -a
JavaScriptCheck images
docker images
JavaScriptBuild image
docker build -t ml-project .
JavaScriptRun container
docker run -p 5000:5000 ml-project
JavaScriptStop container
docker stop CONTAINER_ID
JavaScriptStart container
docker start CONTAINER_ID
JavaScriptRemove container
docker rm CONTAINER_ID
JavaScriptRemove image
docker rmi ml-project
JavaScript39. Common beginner errors
Error 1: Dockerfile not found
If you get:
failed to read dockerfile
JavaScriptCheck that the file is named exactly:
Dockerfile
JavaScriptAlso make sure your terminal is inside the correct project folder.
Check your current folder in PowerShell:
pwd
JavaScript40. Error 2: CMD error
Wrong:
CMD["python", "app.py"]
JavaScriptCorrect:
CMD ["python", "app.py"]
JavaScriptThere must be a space.
41. Error 3: requirements.txt not found
If you get an error related to:
requirements.txt
JavaScriptmake sure your project looks like:
ML_Project/
│
├── Dockerfile
├── requirements.txt
├── app.py
└── model.pkl
JavaScriptThe Dockerfile and requirements.txt should be in the same project directory.
42. Error 4: model.pkl not found
If you get:
FileNotFoundError: model.pkl
JavaScriptmake sure you first run:
python model.py
JavaScriptThis creates:
model.pkl
JavaScriptThen build the Docker image again:
docker build -t ml-project .
JavaScript43. Error 5: Port already in use
If port 5000 is already being used, run:
docker run -p 5001:5000 ml-project
JavaScriptNow open:
http://localhost:5001
JavaScriptHere:
5001 = your computer
5000 = Docker container
JavaScript44. Error 6: Python package installation fails
If your ML libraries have compatibility problems with Python 3.13, use:
FROM python:3.11-slim
JavaScriptFor beginner ML projects, Python 3.11 is often a practical choice because many ML packages have broad support for it.
Then rebuild:
docker build -t ml-project .
JavaScript45. Why do we need Docker for ML?
Imagine your ML project works perfectly on your computer.
You give the project to another developer.
They install:
Python
Scikit-learn
Flask
Joblib
JavaScriptBut they have different versions.
The application may not work.
Docker helps by packaging the environment.
Your Computer
↓
Docker Image
↓
Same Environment
↓
Another Computer
↓
Same Application
JavaScriptThis makes deployment much easier and more consistent.
46. Docker in real ML deployment
A real ML project may look like:
Training
↓
Data
↓
Feature Engineering
↓
Model Training
↓
model.pkl
↓
API
↓
Docker
↓
Cloud
↓
Production
JavaScriptDocker is usually part of the deployment stage.
It is not the ML algorithm itself.
47. Important distinction
Docker does NOT replace:
Python
Scikit-learn
Pandas
NumPy
Flask
FastAPI
Cloud
JavaScriptDocker provides a containerized environment in which your application and its dependencies can run.
For example:
Docker
│
┌──────────┴──────────┐
│ │
Python Libraries
│ │
Flask Scikit-learn
│ │
└──────────┬──────────┘
│
ML Model
│
API Server
JavaScript48. Complete commands from start to finish
Once your files are ready, the main workflow is:
python model.py
JavaScriptThen:
docker build -t ml-project .
JavaScriptThen:
docker images
JavaScriptThen:
docker run -p 5000:5000 ml-project
JavaScriptThen open:
http://localhost:5000
JavaScriptTo check the container:
docker ps
JavaScriptTo stop it:
docker stop CONTAINER_ID
JavaScript49. Final project structure
Your final project should be:
ML_Project/
│
├── Dockerfile
│
├── model.py
│
├── model.pkl
│
├── app.py
│
└── requirements.txt
JavaScriptDockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
JavaScriptrequirements.txt
Flask
scikit-learn
joblib
JavaScriptMain commands
python model.py
JavaScriptdocker build -t ml-project .
JavaScriptdocker run -p 5000:5000 ml-project
JavaScript50. The most important Docker concepts to remember
If you are a beginner, remember these five things first:
1. Dockerfile
↓
Instructions
2. Docker Image
↓
Package
3. Docker Container
↓
Running Image
4. Docker Build
↓
Creates Image
5. Docker Run
↓
Creates/Starts Container
JavaScriptThe complete relationship is:
Dockerfile
│
│ docker build
▼
Docker Image
│
│ docker run
▼
Docker Container
│
▼
ML Application
│
▼
localhost:5000
JavaScriptThis is the basic Docker workflow you should understand before moving to more advanced topics such as Docker Compose, Docker Hub, cloud deployment, FastAPI, Kubernetes, and CI/CD.
