Docker and Flask Containerization with ML model
Topics
- Introduction to Containers
- Installing Docker
- Creating and Testing a Flask App
- Dockerfile Basics
- Building a Container Image
- Running a Container Image
- Daemon Mode and Other Useful Commands
- Conclusion
- Code
1. Introduction to Containers
Food can become contaminated by germs, dampness, and other outside elements if it is left out in the open.
Similar to this, if you run an application on a server without the appropriate isolation and encapsulation, it may be risk to outside influences that could harm its stability or performance.
We can preserve the quality and freshness of food by putting it in self-contained, protected environments like cans, jars, and plastic bags.
Similar to this, we establish a secure and enclosed environment that aids in ensuring the consistency and stability of an application by wrapping it along with its dependencies within a container.
A container is a portable and lightweight software package that includes everything required for running an application, making it easier for developers to create and test, deploy an application without conflicts or other dependency issues, allowing developers to test it locally and easily deploy it in the cloud.
Containers provide isolation, which means that any programme executing inside a container is isolated from other applications as well as the underlying operating system.
For example, if you create a Debian based container image and run a Django-based application inside it on an Ubuntu 18.04 host system [ host system is the operating system on your computer that runs the container runtime], any issues or conflicts caused by the application will be contained within the container and will not affect other containers or the host system, even if another container image is running a different application.
This enables several programmes to operate on the same host system without interfering with one another, while also providing security and stability.
Containerization, which is an operating system-level virtualization, is used to create containers. Several containers can operate on the same operating system kernel due to this technique.
Containers are just lighhtweight VMs , right ? NO
- Virtual machines (VMs) and containers both offer a method to run applications in separate environments, but they do it in distinct ways
- A hypervisor is a software that creates and manages virtual machines, while Docker engine is a containerization platform that uses container technology to run applications in isolated environments.
- Hypervisors provide hardware-level virtualization, while Docker engine provides operating system-level virtualization
- Even so, containers are frequently referred to as “lightweight” because they are built on a shared operating system kernel and only contain the application and its dependencies.
- As comparison to a full VM, containers may be started and stopped quickly and use less resources.
For more understanding https://www.ibm.com/in-en/topics/containerization
2. Installing Docker
Docker makes containerization easier and more accessible for developers by providing a platform
Docker installation
For windows
Use the below commands to install in linux :
# Update your system's package index:
sudo apt-get update
# Install the required packages
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# Add Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Add the Docker repository to the APT sources
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Update the package index again
sudo apt-get update
# Install the latest version of Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# start the Docker service and set up automatic startup
sudo systemctl start docker
sudo systemctl enable docker
# check the status of Docker - it has to be enable and active(running)
sudo systemctl status docker
Container Image
An image in Container is a lightweight, independent, executable package that includes all of the code, libraries, and dependencies required to operate an application or service.It acts as the basis for containers.
This is the official link for the Container image in Docker. DockerHub
3. Creating and Testing a Flask App
Create an empty folder within that only we are going to work on,
Folder name: flask_docker
Install the packages
pip install flask numpy scikit-learn
In the flask_docker folder open a terminal , run
pip freeze --local > requirements.txt
it will create a requirements.txt file , then in the same folder create
app.py
# Import the Flask module
from flask import Flask, request
import numpy as np
import pickle
# Load the random forest model
with open('random_forest_IrisModel.pickle', 'rb') as f:
loaded_model = pickle.load(f)
# Create the Flask application
app = Flask(__name__)
# Define the predict endpoint
@app.route("/predict", methods=["POST"])
def predict():
# Get the input data as a dictionary
input_data = request.get_json()
# Convert the input data into a numpy array
input_array = np.array(list(input_data.values())).reshape(1, -1)
# Make the prediction using the loaded model
prediction = loaded_model.predict(input_array)
# Return the prediction as a JSON response
return {"prediction": prediction.tolist()}
if __name__ == "__main__":
# Start the Flask application
app.run(host='0.0.0.0', port=8080)
Run the application ‘ python app.py’
Note : random_forest_IrisModel.pickle the model file should be in the same directory
Use the code below to test the API.
test.py
import requests
import json
# Define the input data
input_data = {
"feature1": 1,
"feature2": 2,
"feature3": 3,
"feature4": 4
}
# Define the URL of the predict endpoint
url = "http://localhost:8080/predict"
# Send a POST request to the predict endpoint with the input data
response = requests.post(url, json=input_data)
# Print the response
print(response.json())
## output
## {'prediction': ['Iris-virginica']}
4. Dockerfile Basics
Creating, configuring, and packaging software into a portable container is simple with the help of a text file called a Dockerfile that contains a series of commands for constructing a Container image.
Dockerfile can contain instructions for setting up environment variables, transferring files into an image, running scripts, and installing dependencies.
Now that our flask app is ready, we’ll create a file with the name “Dockerfile” with no extension. In flask_docker folder
we are going to use the official python image from DockerHub — python:3.9
Each line will be executed one at a time when we build with Container Image
Dockerfile
FROM python:3.9
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 8080
CMD python app.py
- From python:3.9
This line specifies the base image for the Container, which is python:3.9
but you can choose for your requirement https://hub.docker.com/_/python
- WORKDIR /app
This line sets the working directory inside the container to /app . All subsequent commands will be executed in this directory.
- COPY . /app
This line copies all files in the current directory (where the Dockerfile is located) to the /app directory inside the container.
- RUN pip install -r requirements.txt
This line installs all the required packages specified in the requirements.txt file in the container.
- EXPOSE 8080
This line tells Container to expose port 8080 for the container to listen on. This does not actually publish the port to the host machine.
- python app.py
This line sets the default command to run python app.py , when a container is started from this image this line will be executed.
Therefore, the Container will use the base image python:3.9, set the working directory to /app, copy all files from the current directory to /app inside the container, install all necessary packages, expose port 8080 for the container to listen on, and run python app.py by default when it is built and started.
RUN vs CMD
During the creation of an image, commands are executed out using the RUN instruction.
The initial command that should be executed when the container starts is specified using the CMD instruction.
Now we should have all these files in same directory
5. Building a Container Image
Run the command below in the directory where app.py and the Dockerfile are located after opening a terminal.
docker build -t mlapp:v1 .
This command builds a Container image with the tag “mlapp” and version “v1” using the Dockerfile in the current directory. The “.” at the end of the command indicates the current directory.
Syntax
docker build -t ImageName:TagName directory
- -t : specifies the tag to be assigned to the Container image
- ImageName :the name you want to give to the Container image
- TagName :the tag you want to assign to the Container image
- directory :the directory where the Dockerfile is located
once it is done you’ll get the result as
for the above process only till EXPOSE 8080 has been executed, when we run the image then only CMD python app.py will run
you can check the Container image using the command
6. Running a Container Image
docker run -p 8080:8080 mlapp:v1
This command runs the Container image with the tag “mlapp” and version “v1” and maps port 8080 in the container to port 8080 on your local machine. You can access the application by navigating to http://localhost:8080/ in your web browser.
Syntax
docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]
- docker run :is the command used to run a container based on an image
- [OPTIONS] : specifies any options you want to pass to the docker run command
- IMAGE[:TAG] : specifies the name and tag of the Container image you want to run
- [COMMAND] [ARG…] :specifies the command and any arguments you want to run inside the container
Now that the image has been containerized, you can test it with test.py to see if everything was as expected.
7. Daemon Mode and Other Useful Commands
When a Container is run in daemon mode, the terminal session is not kept active and the container operates in the background
docker run -dp 8080:8080 mlapp:v1
To check the running containers
docker ps
To stop /start the container
docker stop <container ID>
docker start <container ID>
To remove a container
docker rm <container ID>
## if it is running , -f
docker rm -f <container ID>
To remove an Image
docker rmi <image_id or Name>
8. Conclusion
Here, I’ve demonstrated a simplistic application. If you are adept at these fundamentals, you can move on to more difficult stuff.
Flask provides a simple and flexible way to build a web API for your model, in contrast to Docker, which enables you to package and deploy your application in a portable and scalable way.
The creation and deployment of ML models are made easier by these tools.