Picture this, you built a cool homepage for a website and it is working exactly as you want on your machine. You share it with someone else to get their feedback, but it just won't work the same way. Believe it or not, this happens all the time in the software development world. Docker is a tool that helps you solve this.
What is Docker?
Docker is a powerful tool for creating, deploying, and managing software applications in containers. A container is a lightweight, standalone, and executable package that includes everything needed to run the software, such as code, libraries, and dependencies. Think of it as a complete bundle with all the inner working hidden from the outer world. Docker can be used to create these containers which are independent of the host's environment, thus providing the same experience across systems.
How does this work?
Containers have their standalone filesystem thanks to the images they are built on. An Image is a building block of the container and hence houses everything that is required for the container to run - the code, the filesystem, dependencies.
Docker packages these all in one image which can then be used to create the containers.
In this tutorial, we will containerise a simple Python application. Note that the same process can be used to create containers of any size.
Project Structure
Go ahead and create a new folder on your system. We will call this docker-test
. Create a python file called pydock.py
. Add the following sample code to the python file or feel free to use your own code.
from faker import Faker
from tabulate import tabulate
fake = Faker()
# print 10 fake names and addresses
table = [['name','address']]
# generating the names and addresses
for _ in range(10):
name = fake.name()
address = fake.address()
table.append([name,address])
# print in tabular format
print(tabulate(table,headers='firstrow',tablefmt='fancy_grid'))
This is a simple application that generates fake names and addresses in a tabular format. Notice that we are using external libraries - faker
and tabulate
for the same.
Now create a .dockerignore
file in the root of the project. Use this to add the files that you want to ignore while creating an image. Your folder structure should look like this:
docker-test
-- pydock.py
-- .dockerignore
Docker Setup
Go ahead and install Docker Desktop for your system from here. While you are at it, create an account on dockerhub as well.
Once docker desktop is installed, you can open the application. This will automatically start a docker daemon
in background.
Dockerfile - where the magic lives
Next, create a file called Dockerfile
in the root of the project. This defines how the image will be created and what will be used to create the image. The project structure should now look like this:
docker-test
-- pydock.py
-- .dockerignore
-- Dockerfile
Edit the contents of the Dockerfile
as follows:
FROM python:3.8-slim-buster
WORKDIR /app
COPY . .
RUN pip install Faker tabulate
CMD [ "python3","pydock.py"]
Let's go over the contents of this Dockerfile
from top to bottom.
- The
FROM
instruction specifies what kind of image we want to create. We can pull pre-built images from DockerHub, including full-scale Operating Systems. However in this case, we just need to build a python image so we are usingpython:3.8-slim-buster
. You can choose any python image that are mentioned here - The
WORKDIR
instruction specifies the working directory in the container's filesystem. Think of this as the path where your image will sit and run in the container. In this case it is/app
. - The
COPY
instruction lets you copy files from your machine to the image. The syntax isCOPY <source> <target>
, where<source>
is the file path on your local machine and<target>
is the file path on the container starting from the working directory. -
RUN
instruction is used to execute commands during the build process of a Docker image. Here we are using this to install our dependencies -Faker
andtabulate
. - The
CMD
instruction is used to specify the default command to be executed when a container is started from the image. Notice thatCMD
uses an array format to define the commands whileRUN
uses a simple string format
IMPORTANT: Docker images are a set of layers. Every instruction in a Dockerfile
creates a layer. These layers are cached internally for faster image builds.
Building a Docker image
Once you are done with the Dockerfile
, we can move on to create your first Docker image. Open terminal in the root of your project. You can check if Docker is running using
docker --version
To build an image, run the following:
docker build -t <username>/<image-name>:<tag> .
You can call the image whatever you want, but the following conventions are generally used.
- The
-t
option lets you create a tag for you image. -
<username>
is your docker hub username. -
<image-name>
is the name you want to give to the image. -
<tag>
is like the version number for the image. -
.
is the path whereDockerfile
is present, here we have it in the root of the project
Docker starts creating image layers from the instructions mentioned in the Dockerfile
. Once done, you can check your built image in Docker Desktop.
Running the container
To run the image inside a container, we will use the following:
docker run <username>/<image-name>:<tag>
This will run a container from the image that we built in the above process. You should see a similar output once you run the above command.
Congratulations🎉🎉! You have created your first Docker Container successfully. You can check the container in Docker Desktop and even publish this to Docker Hub. You can share this image with others and they can simply run this as a standalone application. No installation fuss, no dependency issues, nothing! They won't even know what's inside the container but the container works as required!
Top comments (3)
Great blog! Concise and easy to follow with all the things explained in details.
Kudos!
Great work @ag2byte
Good work... Easy to understand...