Build and Deploy Flask REST API on Docker
Docker is an OS level virtualization software platform that enables developers to develop, package, ship and run applications by using containers. Containers allow developers to package an application with dependencies and libraries. Docker containers not only make it easier to create, deploy and run applications but also makes you confident that your application will run on any machine regardless of the host machine's specifications.
In this section, we will explore the steps to dockerize your flask app.
Getting Started
Table of contents
- Install Docker
- Install Python and flask
- Create Flask API
- Run and Test
- Requirements file generation
- Create dockerfile
- Build and run the docker image
- Push and pull docker images (optional)
Requirements
- python
- flask
- docker
Step 1: Install docker
- Download the docker installer from https://docs.docker.com/desktop. In this tutorial, we will be deploying the flask api on a windows machine. Download the windows installer and double-click on it to install.
- Enable Hyper-V Windows Feature on the Configuration page.
- Follow the installation process and after completion, click Close and restart your machine.
- Sometimes, docker does not start automatically. To start the Docker tool, search docker on the search bar and select Docker Desktop from the search results.
Docker needs virtualization technology to be enabled from the BIOS settings. If not then enable it. Install Linux subsystems for windows to start docker on your machine. Follow the link https://docs.microsoft.com/en-us/windows/wsl/install-manual#step-6---install-your-linux-distribution-of-choice to install it.
Step 2: Install python and flask
Install python
Python is a prerequisite for creating flask APIs. If not installed, install python3 from the official site [download]. Check the add to path option while installing it. You can also add it manually to the path in System / User variables.
Install flask
- Install virtual environment package, if not installed.
python -m pip install virtualenv
- Create a folder named app and open the command prompt in that folder.
- Create a virtual environment named
venv
.
python -m venv venv
- Switch to the virtual environment.
venv/Scripts/activate
- Install the flask package.
pip install flask
Step 3: Create flask API
Create an API for providing book information using the flask package. Create a file named app.py
under the current directory and add the following code to it.
import flask
from flask import request, jsonify
app = flask.Flask(__name__)
app.config["DEBUG"] = True
# Create some test data for our catalog in the form of a list of dictionaries.
books = [
{
"id": 1,
"isbn":"9781593279509",
"title":"Eloquent JavaScript, Third Edition",
"subtitle":"A Modern Introduction to Programming",
"author":"Marijn Haverbeke",
"published":"2018-12-04T00:00:00.000Z",
"publisher":"No Starch Press",
"pages":472,
"description":"JavaScript lies at the heart of almost every modern web application, from social apps like Twitter to browser-based game frameworks like Phaser and Babylon. Though simple for beginners to pick up and play with, JavaScript is a flexible, complex language that you can use to build full-scale applications.",
"website":"http://eloquentjavascript.net/"
},
{
"id": 2,
"isbn":"9781491943533",
"title":"Practical Modern JavaScript",
"subtitle":"Dive into ES6 and the Future of JavaScript",
"author":"Nicolás Bevacqua",
"published":"2017-07-16T00:00:00.000Z",
"publisher":"O'Reilly Media",
"pages":334,
"description":"To get the most out of modern JavaScript, you need learn the latest features of its parent specification, ECMAScript 6 (ES6). This book provides a highly practical look at ES6, without getting lost in the specification or its implementation details.",
"website":"https://github.com/mjavascript/practical-modern-javascript"
}
]
@app.route('/', methods=['GET'])
def home():
return '''<h1>VLib - Online Library</h1>
<p>A flask api implementation for book information. </p>'''
@app.route('/api/v1/books/all', methods=['GET'])
def api_all():
return jsonify(books)@app.route('/api/v1/books', methods=['GET'])
def api_id():
if 'id' in request.args:
id = int(request.args['id'])
else:
return "Error: No id field provided. Please specify an id."results = []
for book in books:
if book['id'] == id:
results.append(book)return jsonify(results)
@app.route("/api/v1/books", methods = ['POST'])
def api_insert():
book = request.get_json()
books.append(book)
return "Success: Book information has been added."
@app.route("/api/v1/books/<id>", methods=["DELETE"])
def api_delete(id):
for book in books:
if book['id'] == int(id):
books.remove(book)
return "Success: Book information has been deleted."
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
Explanation of the above code,
- Imported the flask package and create an app using
flask.Flask(__name__)
method. books
dictionary contains book-related information.- Created
get
,post
,delete
APIs to perform CRUD operations on books dictionary. @app.route(‘/’, methods=[‘GET’])
,@app.route(‘/api/v1/books/all’, methods=[‘GET’])
apis for reading,@app.route(“/api/v1/books”, methods = [‘POST’])
api for inserting,@app.route(“/api/v1/books/<id>”, methods=[“DELETE”])
for deleting the book information.- Finally created a server in the localhost with port 5000 using
app.run(host=”0.0.0.0", port=5000)
Step 4: Run and Test
Execute the app.py
file in the terminal using the following command to run the flask app.
python app.py
Great! You have created your own flask API.
Step 5: Generate requirements file
The requirements.txt
file contains all package-related information used in the project. Create the requirements.txt
file by executing the following command.
pip freeze > requirements.txt
Step 6: Create dockerfile
Dockerfile is an essential document which contains instructions to build a Docker image.
Create a dockerfile
under the current directory and add the following code to it,
FROM alpine:latestRUN apk update
RUN apk add py-pip
RUN apk add --no-cache python3-dev
RUN pip install --upgrade pipWORKDIR /app
COPY . /app
RUN pip --no-cache-dir install -r requirements.txtCMD ["python3", "app.py"]
- Dockerfile starts with
FROM
command to set the base image toalphine
. RUN
command is used to execute commands in the container. It is useful to perform system update, pip upgradation, and package installation.WORKDIR
command creates a directory namedapp
for the container.COPY
command transfer files / folders to the file system of the container.CMD
command runs the python commandapp.py
in the container.
Step 7: Build and run the docker image
- Build the docker image using the following command,
docker build -t flask-rest-api .
flask-rest-api is the image name(you can change if required).
- To list the docker images, use the following command,
docker images
- Run the docker image using the following command,
docker run -d -p 5000:5000 flask-rest-api
To list the docker image status, use the following command,
docker ps -a
- You can use the
logs
command to list the logs of a container by specifying the container id.
docker logs <CONTAINER ID OR CONTAINER NAME>
docker logs ebae5d67bff984937e1700eee05afd760e331923ac3be73c825ef1e49f8b6bee
There you have it! Your own flask app in the docker container :)
Now you can test the APIs using a browser or postman.
Step 8: Push and pull Docker images (optional)
GitHub is a platform to push and pull our codes. Similar to GitHub, we can push and pull Docker image onto Docker Hub. Docker Hub is an online platform to host, find, and share docker images.
In this section, we will push the newly created docker image onto Docker Hub.
- Login to Docker Hub using your credentials. If you don’t have one, create a new account using the link https://hub.docker.com/signup.
- Click on create repository button to create a new repository.
- Provide a name and description for the repository. Set visibility to Public and click on the create button.
- Login to the docker on your terminal using the following command,
docker login --username=<your-username>
- Tag your image with the repository. Find the docker image id using
docker images
command if required.
docker images
docker tag <your-image-id> <dockerhub-username>/<repo-name>:<tag>
- Push your image to the repo.
docker push <dockerhub-username>/<repo-name>
- Execute the following command to save the image as a tar file (if required),
docker save <repo-name> > <repo-name>.tar
- Execute the following command to load the docker image from the archived tar file (if required),
docker load — input <repo-name>.tar
- You can also use the search option to search the docker images from docker hub and pull them using the pull command,
docker search <repo-name>
docker pull <dockerhub-username>/<repo-name>
Thanks for reading this article.
Thanks Gowri M Bhatt for reviewing the content.
If you enjoyed this article, please click on the clap button 👏 and share to help others find it!
The article is also available on Dev.
The full source code for this tutorial can be found here,