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
JavaScript

2. What will we build?

We will create a very simple ML application.

Our project will:

  1. Train a Machine Learning model.
  2. Save the model.
  3. Create an API using Flask.
  4. Create a Dockerfile.
  5. Build a Docker image.
  6. Run the image as a container.
  7. Access the ML application through a browser.
  8. Send data to the model for prediction.

3. Install the required software

You need:

Python

Check Python:

python --version
JavaScript

Example:

Python 3.11.9
JavaScript

Docker Desktop

Install Docker Desktop on Windows.

After installation, open Docker Desktop and make sure Docker is running.

Check Docker:

docker --version
JavaScript

Example:

Docker version 28.x.x
JavaScript

Also check:

docker info
JavaScript

If Docker is running, you will see Docker information.


4. Create the project folder

Create a folder called:

ML_Project
JavaScript

For example:

E:\ML_Project
JavaScript

Open this folder in VS Code.

Your project will eventually look like this:

ML_Project/

├── Dockerfile
├── app.py
├── model.py
├── model.pkl
└── requirements.txt
JavaScript

5. Create the Machine Learning model

Create a file:

model.py
JavaScript

Put 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")
JavaScript

6. Install the ML libraries

Before Docker, we can test the Python project locally.

Open the VS Code terminal.

Run:

pip install scikit-learn joblib
JavaScript

Then run:

python model.py
JavaScript

You should see:

Model trained successfully!
Model saved as model.pkl
JavaScript

A new file should appear:

model.pkl
JavaScript

This is our trained ML model.


7. Create the Flask application

Now create:

app.py
JavaScript

Add:

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
    )
JavaScript

8. Understand app.py

The first line:

from flask import Flask, request, jsonify
JavaScript

imports Flask and some useful functions.

This:

app = Flask(__name__)
JavaScript

creates our Flask application.

This:

model = joblib.load("model.pkl")
JavaScript

loads our trained ML model.


9. Create the home API

We have:

@app.route("/")
def home():
    return "Machine Learning API is running!"
JavaScript

When we open:

http://localhost:5000
JavaScript

the application will return:

Machine Learning API is running!
JavaScript

10. Create the prediction API

We created:

@app.route("/predict", methods=["POST"])
JavaScript

This means our application has a prediction endpoint:

/predict
JavaScript

It expects data like:

{
    "features": [5.1, 3.5, 1.4, 0.2]
}
JavaScript

The model receives these values and makes a prediction.


11. Create requirements.txt

Now create:

requirements.txt
JavaScript

Put this inside:

Flask
scikit-learn
joblib
JavaScript

This file tells Docker which Python packages our application needs.

Think of it like a shopping list:

Flask
scikit-learn
joblib
JavaScript

Docker 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
JavaScript

You should see something similar to:

* Running on http://127.0.0.1:5000
JavaScript

Open your browser:

http://localhost:5000
JavaScript

You should see:

Machine Learning API is running!
JavaScript

Press:

CTRL + C
JavaScript

in 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
JavaScript

Important:

Do NOT name it:

Dockerfile.txt
JavaScript

Do NOT name it:

Dockerfile 1
JavaScript

The filename must simply be:

Dockerfile
JavaScript

14. 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"]
JavaScript

Save the file.


15. Understand the Dockerfile

Let’s understand every line.

FROM

FROM python:3.11-slim
JavaScript

This tells Docker:

Start with a Python 3.11 environment.

We are using the slim version because it is smaller.


16. WORKDIR

WORKDIR /app
JavaScript

This creates/uses:

/app
JavaScript

inside the container.

From this point, Docker will work inside /app.


17. COPY requirements.txt

COPY requirements.txt .
JavaScript

This copies:

requirements.txt
JavaScript

from our computer into the Docker container.


18. RUN pip install

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

Docker now installs:

Flask
scikit-learn
joblib
JavaScript

inside the container.


19. COPY project files

COPY . .
JavaScript

This copies our project files into the container.

For example:

app.py
model.py
model.pkl
requirements.txt
JavaScript

20. EXPOSE

EXPOSE 5000
JavaScript

Our Flask application uses port:

5000
JavaScript

This 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
JavaScript

21. CMD

This is very important.

Use exactly:

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

There must be a space between:

CMD
JavaScript

and:

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

Correct:

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

Incorrect:

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

The incorrect version can produce:

unknown instruction: CMD["python"
JavaScript

22. Final project structure

Before building the Docker image, your project should look like:

ML_Project/

├── Dockerfile
├── app.py
├── model.py
├── model.pkl
└── requirements.txt
JavaScript

Check carefully that the file is:

Dockerfile
JavaScript

and not:

Dockerfile.txt
JavaScript

23. Build the Docker image

Open the terminal inside the ML_Project folder.

Run:

docker build -t ml-project .
JavaScript

Let’s understand this command.

docker build
JavaScript

means:

Build a Docker image.

-t ml-project
JavaScript

means:

Give the image the name ml-project.

.
JavaScript

means:

Use the current folder as the build context.


24. What happens during the build?

Docker reads:

Dockerfile
JavaScript

Then it performs these steps:

Dockerfile

Python Image

Create /app

Copy requirements.txt

Install libraries

Copy project files

Create final Image
JavaScript

If everything works, you should see something similar to:

Successfully built ...
Successfully tagged ml-project:latest
JavaScript

25. Check the Docker image

Run:

docker images
JavaScript

You should see something similar to:

REPOSITORY     TAG       IMAGE ID
ml-project     latest    xxxxx
JavaScript

This 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
JavaScript

The image itself is not the running application.


27. Run the Docker container

Now execute:

docker run -p 5000:5000 ml-project
JavaScript

This command creates and starts a container from our image.


28. Understand -p 5000:5000

This part:

-p 5000:5000
JavaScript

means:

Computer Port : Container Port
JavaScript

So:

Your computer
localhost:5000

Docker container
port 5000

Flask application
JavaScript

29. Open the application

Open your browser.

Go to:

http://localhost:5000
JavaScript

You should see:

Machine Learning API is running!
JavaScript

Congratulations.

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]
}
JavaScript

The API may return:

{
    "prediction": 0
}
JavaScript

The 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
JavaScript

32. Image vs Container

This is one of the most important Docker concepts.

Image

Image is the package/template.

ML Image

├── Python
├── Libraries
├── Code
└── Model
JavaScript

Container

Container is the running version of that image.

ML Image

docker run

ML Container

Running Application
JavaScript

A simple way to remember:

Image = Package

Container = Running Package
JavaScript

33. Check running containers

Open another terminal and run:

docker ps
JavaScript

You may see:

CONTAINER ID
IMAGE
STATUS
PORTS
JavaScript

Your ml-project container should be there.


34. Stop the container

Find the container ID:

docker ps
JavaScript

Then:

docker stop CONTAINER_ID
JavaScript

For example:

docker stop abc123
JavaScript

35. Start an existing container again

List all containers:

docker ps -a
JavaScript

Then start the container:

docker start CONTAINER_ID
JavaScript

36. Remove a container

If you want to delete a container:

docker rm CONTAINER_ID
JavaScript

37. Remove the image

To delete the Docker image:

docker rmi ml-project
JavaScript

Be 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
JavaScript

Check running containers

docker ps
JavaScript

Check all containers

docker ps -a
JavaScript

Check images

docker images
JavaScript

Build image

docker build -t ml-project .
JavaScript

Run container

docker run -p 5000:5000 ml-project
JavaScript

Stop container

docker stop CONTAINER_ID
JavaScript

Start container

docker start CONTAINER_ID
JavaScript

Remove container

docker rm CONTAINER_ID
JavaScript

Remove image

docker rmi ml-project
JavaScript

39. Common beginner errors

Error 1: Dockerfile not found

If you get:

failed to read dockerfile
JavaScript

Check that the file is named exactly:

Dockerfile
JavaScript

Also make sure your terminal is inside the correct project folder.

Check your current folder in PowerShell:

pwd
JavaScript

40. Error 2: CMD error

Wrong:

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

Correct:

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

There must be a space.


41. Error 3: requirements.txt not found

If you get an error related to:

requirements.txt
JavaScript

make sure your project looks like:

ML_Project/

├── Dockerfile
├── requirements.txt
├── app.py
└── model.pkl
JavaScript

The Dockerfile and requirements.txt should be in the same project directory.


42. Error 4: model.pkl not found

If you get:

FileNotFoundError: model.pkl
JavaScript

make sure you first run:

python model.py
JavaScript

This creates:

model.pkl
JavaScript

Then build the Docker image again:

docker build -t ml-project .
JavaScript

43. Error 5: Port already in use

If port 5000 is already being used, run:

docker run -p 5001:5000 ml-project
JavaScript

Now open:

http://localhost:5001
JavaScript

Here:

5001 = your computer
5000 = Docker container
JavaScript

44. Error 6: Python package installation fails

If your ML libraries have compatibility problems with Python 3.13, use:

FROM python:3.11-slim
JavaScript

For 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 .
JavaScript

45. 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
JavaScript

But 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
JavaScript

This 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
JavaScript

Docker 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
JavaScript

Docker 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
JavaScript

48. Complete commands from start to finish

Once your files are ready, the main workflow is:

python model.py
JavaScript

Then:

docker build -t ml-project .
JavaScript

Then:

docker images
JavaScript

Then:

docker run -p 5000:5000 ml-project
JavaScript

Then open:

http://localhost:5000
JavaScript

To check the container:

docker ps
JavaScript

To stop it:

docker stop CONTAINER_ID
JavaScript

49. Final project structure

Your final project should be:

ML_Project/

├── Dockerfile

├── model.py

├── model.pkl

├── app.py

└── requirements.txt
JavaScript

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

requirements.txt

Flask
scikit-learn
joblib
JavaScript

Main commands

python model.py
JavaScript
docker build -t ml-project .
JavaScript
docker run -p 5000:5000 ml-project
JavaScript

50. 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
JavaScript

The complete relationship is:

                 Dockerfile

docker build

               Docker Image

docker run

             Docker Container


              ML Application


              localhost:5000
JavaScript

This 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.

Scroll to Top