How to set up a Python REST API using Docker?
How to create simple Flask application?
Open VS Code at the top go to File "Open Folder" so you can choose a folder to start with. In my example "python-docker". Now you'll see an empty space in VS Code. Go to the terminal and select "New Terminal" and make sure you are in the directory you just created. Type:
python3 -m venv .venv
Now you can see the virtual environment on the left side of your directory. Go to ".venv" and then to the "scripts" folder. This will allow you to see the activate file. In the terminal, type:
cd .venv
cd scripts
.\activate
.\activate activates your environment so that you can run any Python code. Select "run once" and your environment is started.
Now add these two simple commands to your virtual environment:
pip install Flask
pip freeze > requirements.txt
Next, create a app.py
script in VS Code. To do that simply navigate to the directory tree and under “Scripts” right click “New File”.
Now let’s add the code below:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
Before you can run it, please exit venv and start it again to make sure that the Python script is recognized. After that, you can test it with the following command:
deactivate
.\activate
python -m flask run
Now your website is accessible at localhost port 5000. In your favorite browser, type 172.0.0.1:5000 and you should see the following text: Hello Docker!.
As you can see, your web requests generate server logs. Now press CTRL+C and type deactivate so you are ready for the next part with Docker.
How to create a Dockerfile?
First, create a Docker file in the same folder as the app.py (Scripts).
Next, we need to add a line that tells Docker which base image you want to use. You can take your own image, but in this tutorial we will use an official Python image that includes all the tools and packages.
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
Let's create a working directory to make it easier for us. The working directory is the path for the default location. Now we can use relative paths based on the working directory.
WORKDIR /app
With the COPY
command we get the requirements like pip
in our image. For example, we can run pip install
in the next step. Syntax: First which file to copy and second where to copy the field.
COPY requirements.txt requirements.txt
Use RUN
to simply run pip3 install
. This works exactly as if we were to run pip3 install locally on our machine, but this time the modules are installed into the image.
RUN pip3 install -r requirements.txt
So we have installed our dependencies and our image is based on Python 3.8
The next step is to add our files (app.py and Dockerfile) to the Docker image. COPY
will help with this:
COPY app.py .
COPY Dockerfile .
Lastly, we need to add a line that says docker should run our Python script. We use the CMD
command and need to make our application visible to the outside world by specifying --host=0.0.0.0
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
How to build an image?
Use the Docker build
command to build our Docker image. The build command optionally requires a --tag
flag. The tag is used to specify the name of the image and an optional tag in the format name:tag
. For simplicity, we'll omit the optional tag for now. If you do not pass a tag, Docker uses "latest" as the default tag.
docker build --tag python-docker .
To view your local docker images use docker images
:
docker images
The Output should look like this:
How to run Docker Container?
To run an image inside a container, we use the docker run
command. We need to add --publish
to publish a port for our container, since our container runs in isolation, which includes networking. The format is: host port:container port
docker run --publish 8000:5000 python-docker
After running this command, you’ll notice that you were not returned to the command prompt. This is because our application is a REST server and runs in a loop waiting for incoming requests without returning control back to the OS until we stop the container.
Result:
Instead of “Hello, Docker!” python script, you can add any code you want. For example:
from flask import Flask
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
data={"data":"Hello World"}
return data
api.add_resource(HelloWorld,'/hello')
if __name__=='__main__':
app.run(debug=True)
Output: