Welcome to the second part of our Docker tutorial series. In this part we will build a Docker image by writing a very simple Dockerfile and we will publish the image on Dockerhub. This very simple example will make it easy for you to understand the steps rather than involving you in understanding a complex Dockerfile at this stage!
In part one of this tutorial, we created our first Docker container and it was based on Alpine Linux image. We’ll resume exactly where we concluded the previous part. Running the following command in terminal creates and runs an alpine container (after pulling the image from Dockerhub, if it doesn’t already exist in local repository).
> docker container run -it alpine /bin/sh
After running the container, this command also moves us into the shell of container. As we saw in first part we can execute the standard Linux file system commands like ls
, mkdir
and so on.
However, as this is a minimal Linux image, it doesn’t come shipped with many tools/packages pre-installed. Instead we can decide which tools are required for our application and we can install only those tools or packages so avoiding the useless stuff and keeping the size of our image minimal.
Lets try something… in your container’s shell, try to execute curl
command. curl
does not come preinstalled in alpine
image so you’ll get the error curl not found
.
> curl https://google.com
As this is a (containerised) Linux machine, you should be able to install any package and tool with normal Alpine Linux commands. Alpine Linux uses apk
tool as its package manager. As you are still inside your container shell, execute the following command.
> apk add curl

So this results in successful installation of curl. Now execute curl https://google.com
, this time it will not fail.
Scenario
Consider a simple scenario that all your team of five persons needs is a lightweight alpine
machine which has curl
installed. Let’s also assume that there is no such existing image available on Dockerhub. The solution is pretty simple that you will build a Docker image yourself and your team members will use your new Docker image 🙂
Build a new Docker image using Dockerfile
To build a new Docker image, you first need to be able to define its structure. Considering the scenario stated above, we need a container image that has following two characteristics…
- It should be a light-weight
alpine
image. - It should have curl enabled.
From the discussion so far, we know following already…
- The Linux
alpine
image doesn’t come shipped withcurl
. - The Linux
alpine
image does haveapk
package manager tool available. - When we executed
apk add curl
, it installedcurl
successfully in thealpine
container.
Based on this information, let’s write instructions in a Dockerfile which will be used to build our new Docker image! Do following steps:
- Create a folder
curl-alpine
(or any other suitable name) - Create a file named
Dockerfile
inside that folder and paste following code in that file.
- While you are inside
curl-alpine
folder, execute the following command (we will explain it in a while).
> docker build -t curl-alpine:latest .
Awesome! You have built your own first Docker image. Before we move ahead, lets see what does this build command do!
Explaining the docker build
command
Let’s explain the command docker build -t curl-alpine:latest .
docker
, you know, is the utility/tool.build
is the name of command-t
is the flag which can be used to specify a name for the image and optionally a tag. In our command, we have named the imagecurl-alpine
and tagged itlatest
. The syntax isimage_name:tag
..
is the build context. It must be path to a directory. This.
here implies that the build context is current directory. If yourDockerfile
is somewhere else, you can specify the path to the directory which contains it.
Explaining the Dockerfile
Our example is so basic so our Dockerfile
contains only two commands. See below the output of docker build
.

The output clearly shows where the two steps of our Dockerfile. You can see that Step 1/2 : FROM alpine:latest
results in just linking to the existing image that we downloaded in first part.
The second step (Step 2/2 : RUN apk add --no-cache curl
) involves the downloading and installing curl
as well as its dependencies.
Now any container created using our curl-alpine
image will have pre-installed curl
unlike the official alpine
image.
The beauty of Docker:
The beauty of Docker lies in the fact that it builds images layer by layer. Each command in Dockerfile is a layer for which an intermediary image is created. As you have seen in the output of docker build
command, it didn’t pull the alpine
image again instead it referenced to the existing image in local repository. This results not only in faster processing of build
command but it also saves the disk space by avoiding multiple copies of same image.
This is a very basic example but in next tutorials you’ll see Docker files with more commands (i.e. more layers) and you’ll recognise that how useful is this layered structure.
Running the container
Good job so far! Next step is to run the container which is same as we did in first part. Run the following command…
> docker container run -it curl-alpine /bin/sh
So you are inside the shell of your containerised Alpine Linux
machine which is unlike the one we created in first part in that that it already has curl
installed because we made curl
part of our curl-alpine
image using the commands we listed in Dockerfile
. Now if you try to execute following command,
> curl https://google.com
This time it will run successfully without having to install curl
manually. So you’re good to share your Dockerfile
with your team members and they can simply docker build
and docker run
to have this simple identical machine across the team.
You can use command docker container ls
to see the list of containers running (use flag -a
to see stopped ones also). You can see that the new container is built using our own image curl-alpine
.

Explaining the docker container run
command
Let’s see what are the components of command docker container run -it curl-alpine /bin/sh
docker
is the utility/tool.container
which is a parent command, you can think of it as a namespace for other commands which are related to containers likerun
,list
etc.run
is the command to run a container.-it
these are two flags together;-i
(interactive) and-t
(allocate a pseudo terminal).curl-alpine
is the name of Docker image which is used to create this container. (We have built this image in the section above: Build a new Docker image using Dockerfile)./bin/sh
we can specify any command here that we want to execute after container runs./bin/sh
opens the shell of container. You can use any valid command, for example try following.
> docker container run -it curl-alpine curl https://google.com
As you see, this time the control does not shift inside the container’s shell but instead the curl
command gets executed inside and the output is displayed in the host shell.
Publishing your Docker image to Dockerhub
You can push your Docker images to Dockerhub and those will be accessible to the people all over or even if you want to share within your team Dockerhub is a good central place. Let us now push the image we created in section above (Build a new Docker image using Dockerfile).
To push a Docker image to your Dockerhub account, you need to name your image prefixed with your account name and then push it. For example my Dockerhub account name is atifazad so the commands for me are as follows (replace atifazad with your account name):
> docker tag curl-alpine atifazad/curl-alpine:latest
> docker push atifazad/curl-alpine
When everything goes good, these commands result in similar to…

On Dockerhub, you can view this image here: https://hub.docker.com/r/atifazad/curl-alpine and you can see the command to pull this image.
docker pull atifazad/curl-alpine
Now with your image available on Dockerhub, your teammates don’t have to take the Dockerfile
and build
the image. Instead they can simply execute docker pull <your_dockerhub_username>/curl-alpine
and then docker container run
as explained above 🙂
What’s ahead!
This tutorial explains how to build and publish your own Docker image with a very simple Dockerfile
example. When you have to create a Docker setup for your projects you’ll follow similar steps but with a more detailed and sophisticated Dockerfile
and probably also using docker-compose
to support your development environment.
In the next tutorial in this series, we will build upon what we have learned so far and we will Dockerise a simple application. Till then good bye 🙂