Learning Docker By Building a Python Application
From the past few days, I am exploring docker which is used to package and run the application in isolated containers, developed by Docker Inc. In this blog, I will show how we can create a docker image by writing a simple docker file for a python application that fetches the latest news from the web and will run it on our machine.
Here, we will cover what is docker, why we need it and will show step by step from writing Dockerfile to running it on our machine. At last, we will discuss some common useful docker commands. So without any delay let us start our journey.
What is Docker?
Docker is a lightweight virtual machine where we can run our application in an isolated environment called containers. Containers run directly within the host machine’s kernel and therefore containers are lightweight. You can run as many containers as you want on your machine. The most important aspect of docker is the isolation of containers and we can assemble all required infrastructure for our application in our Dockerfile without installing and configuring software, tools, dependencies, etc directly to our machine, we will see it when we discuss Dockerfile. Docker also provides a way to share our work by sharing docker images on dockerhub.
Each instruction in Dockerfile forms a layer of docker image and thus when you change any instruction in Dockerfile it will only change that layer not the whole image.
Why do we need Docker?
- It replaces the need for Virtual Machine inside our system as VM consumes more resources.
- You can easily develop your application and its supporting components using docker avoiding the overheads of installing and configuring that application. E.g to run your application with MySql database you can simply download a docker image of MySql and run it, no need for downloading and configuring in your system.
- It is platform-independent i.e images can run on any machine without the need for any configuration.
- From the above point, we can deduce that it is portable also.
- It gives us the ability to run our applications in an isolated environment.
- It is fast and efficient.
- It reduces the delay between writing code and running it in production.
Now after taking a bath in the ocean of docker, It is time to make a docker image and run it. We will make a docker image of a simple Python application that fetches the top ten latest news from a news website.
Dockerfile which is required to build a docker image of our python application is given below and the name of our python application is latest_news_crawler.py.
Each line in this file is an instruction that creates a layer of docker image and each instruction starts with a valid docker keyword followed by an argument of that instruction. As we can see below.
# line 1
FROM python:3
# line 2
LABEL author=”Amit Kumar”
# line 3
WORKDIR /user/src/app
# line 4
COPY latest_news_crawler.py /user/src/app
# line 5
RUN pip install — no-cache-dir requests pandas beautifulsoup4
# line 6
ENTRYPOINT [ “python3”, “latest_news_crawler.py” ]
Line1 that is FROM instruction should be the first statement in a docker file as it defines a base image from which we develop our own image. Here our base image is python3 on top of which we are adding our layers.
Bonus:-ARG is the only instruction that may precede FROM in the Dockerfile.
LABEL instruction is simply metadata for your image and it has a form of key-value pairs. Here I am adding author of this image to be of name Amit Kumar. It is an informational tag, not a mandatory one. You can add as many as key-value pairs in a label instruction.
It has following form-> LABEL <key>=<value> <key>=<value> <key>=<value> …
WORKDIR instruction sets the working directory to the given path and any given command of type RUN, CMD, ENTRYPOINT, COPY and ADD instructions will run in the current working directory of container filesystem. You can even change the working directory on subsequent instructions but only the latest defined working directory will work in that case. Here I have defined my working directory to be /user/src/app. If we do not use it in our dockerfile yet our dockerfile will build the image in the default location.
COPY instruction is used to copy files or directories from our system to the filesystem of the container. Here I am copying latest_news_crawler.py to /user/src/app path inside the container. latest_news_crawler.py is present in the same directory where dockerfile resides.
RUN instruction is used to run commands required for our image. Each RUN command creates a new layer on top of the existing image. As I mentioned above RUN command will run in the directory if we have specified our WORKDIR. As we have specified our WORKDIR below command will run in that directory and install following dependencies requests, pandas, beautifulsoup4.
ENTRYPOINT lets you define instructions to execute when a container is started. It has two forms we are using exec form here. Below we are instructing to run our latest_news_crawler.py file in our working directory.
After building this dockerfile save it in a text file named ‘Dockerfile’, then open your terminal and navigate to your directory where Dockerfile is saved and run the following command:-
docker build -t latest_news .
This command will look for dockerfile in the current directory and start building an image out of it. The -t flag signifies name for this image which is latest_news and dot(.) at the end of command implies to look for dockerfile in the current directory.
After building that images you can confirm that image is available by running below command:-
docker images
This command will list all the images available in your system like shown below:
Now it is time to run this image by typing following command:-
docker run latest_news
After running this command your image will run as an isolated container and since our application print the latest news from the web, so it will print that on your terminal.
You can see all of your containers by typing following command:-
docker ps -a
This will list all containers on your terminal whether containers are running or not as given below:
Here the name of my container is optimistic_sammet as we did not give any name to our container docker automatically gives a random name to each container. To override this default name you can run the following command with — name flag.
Docker run — name your_container_name latest_news
So finally you have seen all the steps from building a docker image to running it in your terminal.
If you want to delete your container type the following command:-
docker rm optimistic_sammet
To delete your docker image type following command:-
docker rmi latest_news
So it’s time to see some common useful docker commands:-
To see docker version
docker — version
To start the container
docker start [container-name]
To stop the container
docker stop [container-name]
To list all containers
docker ps -a
To list all running containers
docker ps
To see the history of docker commands
docker history
To see detailed information about any docker object e.g image, container, network, etc.
docker inspect [docker-object-name]
To stop and start a container
docker restart [container-name]
To see system-wide information
docker info
To list all port mapping for this container
docker port [container-name]