Note: The original code is from Udacity's Cloud Native Fundamentals Nanodegree Scholarship Program. The referenced files can be found here.
This post does not provide instructions on installing Docker. For assistance, please refer here.
In this post we're going to go through the process of running a simple Python web app on a container. But, what is a container?
A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. (Source: Docker)
As containers run on the same operating system, they require fewer resources than virtual machines. (Source: Wikipedia)
Let's start with a simple Python web application that serves a single endpoint. We save this file as
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World" if __name__ == "__main__": app.run(host='0.0.0.0')
On running the command
python3 app.py, we can open our browser and on checking
http://localhost:5000/), we get a simple web page with the text "Hello World"!!
(We use port 5000, as it is the default port for Flask. For more about getting started with Flask, please see here.)
Since we're importing the Flask package, we need a file that contains the requirements for the app to run.
Create a new file named
requirements.txt with the contents
where 1.1.1 is the Flask version. Feel free to use a different version! We'll use this file later for our Dockerfile.
Now that we have a working application, we can get started on containerizing it!
A container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. (Source: Docker)
To build an image, we require a Dockerfile, which is a text-based script of instructions (Source: Docker Docs).
To start with, our Dockerfile requires a parent image on top of which our instructions will run (more info here).
python is the image name, while
3.8-alpine3.12 is the tag. An image can have various tags, representing different versions of the image. Alpine images are smaller in size than normal images.
An optional step is to add a label to the image.
FROM python:3.8-alpine3.12 LABEL developer="importhuman"
Next, we need to copy the contents from our local directory to the container directory.
FROM python:3.8-alpine3.12 LABEL developer="importhuman" COPY . /app
This copies all contents from the current directory, to a new directory named
/app on the container.
Next, we set this directory as our working directory. All further instructions will be carried out in this directory.
FROM python:3.8-alpine3.12 LABEL developer="importhuman" COPY . /app WORKDIR /app
The container needs to install dependencies to run the application successfully. So, we add a command to carry out the installation.
FROM python:3.8-alpine3.12 LABEL developer="importhuman" COPY . /app WORKDIR /app RUN pip install -r requirements.txt
All these steps will build the image. To run the image and hence the container, we add the final step.
FROM python:3.8-alpine3.12 LABEL developer="importhuman" COPY . /app WORKDIR /app RUN pip install -r requirements.txt CMD ["python3", "app.py"]
Our instructions are ready. Now, we can build our image!
In the command line, run the following command:
docker build -t image-name path/to/image
-t image-name gives your image the name "image-name", thus you can give it whatever name you'd like!
path/to/image is the path to the directory containing the Dockerfile. If you're running the command in the same directory as the Dockerfile, replace
path/to/image with a dot.
Now, you can run
docker images and you should be able to see your newly built image!