Mastering Docker: Deploying Web Servers and Testing with Ease - How to Build, Push, Pull, and Verify Docker Images for Web Server Deployment?.

Mastering Docker: Deploying Web Servers and Testing with Ease - How to Build, Push, Pull, and Verify Docker Images for Web Server Deployment?.

Question :

How can I create a Dockerfile with a base image of Linux, such as Rocky Linux or CentOS, to deploy a web server (specifically httpd) on port 80? Additionally, I'd like to include the installation of prerequisite programs using yum install, such as httpd, vim, net-tools, and bind-utils. After creating the Dockerfile, I want to push it to Docker Hub, pull the newly pushed Docker image, run and execute a container with the updated image, and finally, verify and test it on a web browser. Could you provide the steps or a guide on how to accomplish this?


Step-1 ( Install Docker on your machine)

I am using a Virtual Machine here, and my OS is centos-9 stream. So make sure you have enough pre-requisite work done like repository setup, host entry, and default firewall ports open. so let's install the docker-engine on virtual-machine. Follow this official docker engine setup link :

# yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \

# yum install -y yum-utils
sudo yum-config-manager --add-repo  

# yum install docker-ce docker-ce-cli docker-buildx-plugin docker-compose-plugin

# sudo systemctl start docker 
# sudo systemctl enable docker

Congratulation. Your docker setup is launched successfully on your VM Linux centos-9 stream server. So let's create Dockerfile as per our question mentioned earlier.

# mkdir ~/Docker
# vi ~/Docker/Dockerfile

FROM rockylinux:9
RUN yum update -y
RUN yum install -y bind-utils vim  wget nmap net-tools httpd unzip
WORKDIR /var/www/html
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

Step-2 ( build the docker image from dockerfile )

[root@localhost Docker]# docker build -t rockyweb:v1 .

[+] Building 90.8s (8/8) FINISHED                                                                                                                    docker:default
 => [internal] load .dockerignore                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                0.0s
 => [internal] load build definition from Dockerfile                                                                                                           0.0s
 => => transferring dockerfile: 336B                                                                                                                           0.0s
 => [internal] load metadata for                                                                                                0.0s
 => CACHED [1/4] FROM                                                                                                           0.0s
 => [2/4] RUN yum update -y                                                                                                                                   55.5s
 => [3/4] RUN yum install -y bind-utils vim  wget nmap net-tools httpd unzip                                                                                  33.3s
 => [4/4] WORKDIR /var/www/html                                                                                                                                0.1s
 => exporting to image                                                                                                                                         1.8s
 => => exporting layers                                                                                                                                        1.8s
 => => writing image sha256:b0dc71435fb5fc1eee603d9158c48703b890f6cd5d0ad8ff1bcd8adbd8e0c993                                                                   0.0s
 => => naming to
[root@localhost Docker]# docker images
rockyweb     v1        b0dc71435fb5   6 minutes ago   292MB

Step-3 ( Tag image and push on docker registry )

Let's Tag with the new version and push this docker image on the docker hub for publically access.

[root@localhost Docker]# docker tag rockyweb:v1 rockyhttpd:v1
[root@localhost Docker]# docker images
rockyhttpd   v1        b0dc71435fb5   15 minutes ago   292MB
rockyweb     v1        b0dc71435fb5   15 minutes ago   292MB

Note: From the running container create an image and tag it with a new name.

[root@localhost Docker]# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS                                     NAMES
91b1c0e0490a   rockylinux:9   "/bin/bash"   38 minutes ago   Up 38 minutes>80/tcp, :::32768->80/tcp   c1

[root@localhost Docker]# docker commit 91b1c0e0490a jangidrakesh71/c1:v1

Before pushing image on the docker hub, you have to log in on the docker hub first. Follow this official docker hub link for more :

[root@localhost Docker]# docker login
--Log in with your Docker ID or email address to push and pull images from Docker Hub. If you don't have a Docker ID, head over to to create one.
You can log in with your password or a Personal Access Token (PAT). Using a limited-scope PAT grants better security and is required for organizations using SSO. Learn more at

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See

Login Succeeded
[root@localhost Docker]#

[root@localhost Docker]# docker push jangidrakesh71/rockyhttpd:v1
The push refers to repository []
5f70bf18a086: Pushed
9d71ef5fb785: Pushed
5de793c738a4: Pushed
c4bc4a1387e8: Mounted from library/rockylinux
v1: digest: sha256:96cf71b21c9fe222eeac8ecdbc946f18f427c4c413ff9904843adbcbf9f4ea70 size: 1159

Let's Check the DockerHub account and check whether image pushed successfully or not. Go to this link:

Step-4 (Pull a custom image and run a container )

[root@localhost Docker]# docker pull jangidrakesh71/rockyhttpd:v1
v1: Pulling from jangidrakesh71/rockyhttpd
489e1be6ce56: Already exists
2dd56c91439e: Already exists
7d91ded6796d: Already exists
4f4fb700ef54: Already exists
Digest: sha256:96cf71b21c9fe222eeac8ecdbc946f18f427c4c413ff9904843adbcbf9f4ea70
Status: Downloaded newer image for jangidrakesh71/rockyhttpd:v1
[root@localhost Docker]# docker run -itd --name=c1 -v c1:/var/www/html -p 80:80 jangidrakesh71/rockyhttpd:v1
[root@localhost Docker]# docker ps -a
CONTAINER ID   IMAGE                          COMMAND                  CREATED         STATUS         PORTS                               NAMES
91bc91ee0e20   jangidrakesh71/rockyhttpd:v1   "/usr/sbin/httpd -D …"   4 seconds ago   Up 2 seconds>80/tcp, :::80->80/tcp   c1
[root@localhost Docker]# cd /var/lib/docker/volumes/c1/_data/
[root@localhost _data]# ls
[root@localhost _data]# cat index.html
This is docker container c1
[root@localhost _data]# docker inspect c1

[root@localhost _data]# curl
This is docker container c1

Congratulation you have deployed your web application successfully.

Lets download a static website template and paste there code contents on container "c1" volume location. That is actually mounted on containers /var/www/html internally. So lets download static website content from link :

Download website content using wget

[root@localhost Docker]# pwd

[root@localhost Docker]# wget
--2023-12-01 13:48:50--
Resolving (, 2001:8d8:100f:f000::28f
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2040237 (1.9M) [application/zip]
Saving to: ‘’                               100%[==================================================================================>]   1.95M  1.43MB/s    in 1.4s

2023-12-01 13:48:52 (1.43 MB/s) - ‘’ saved [2040237/2040237]

Don't forgot to remove previous index.html content :

[root@localhost Docker]# rm -rf /var/lib/docker/volumes/c1/_data/index.html

and now unzip content on location /var/lib/docker/volumes/c1/_data/

[root@localhost Docker]# unzip 
   creating: healet-html/
  inflating: healet-html/about.html
  inflating: healet-html/blog.html
   creating: healet-html/css/
  inflating: healet-html/css/bootstrap.css
  inflating: healet-html/css/font-awesome.min.css
  inflating: healet-html/css/responsive.css
  inflating: healet-html/css/style.css
  inflating: healet-html/css/
  inflating: healet-html/css/style.scss
   creating: healet-html/fonts/
  inflating: healet-html/fonts/fontawesome-webfont.ttf
  inflating: healet-html/fonts/fontawesome-webfont.woff
  inflating: healet-html/fonts/fontawesome-webfont.woff2
  inflating: healet-html/fonts/octin_sports_rg.ttf
   creating: healet-html/images/
  inflating: healet-html/images/about-img.jpg
  inflating: healet-html/images/b1.jpg
  inflating: healet-html/images/b2.jpg
  inflating: healet-html/images/client.jpg
  inflating: healet-html/images/favicon.png
  inflating: healet-html/images/o1.jpg
  inflating: healet-html/images/o2.jpg
  inflating: healet-html/images/o3.jpg
  inflating: healet-html/images/p1.png
  inflating: healet-html/images/p2.png
  inflating: healet-html/images/p3.png
  inflating: healet-html/images/p4.png
  inflating: healet-html/images/p5.png
  inflating: healet-html/images/p6.png
  inflating: healet-html/images/p7.png
  inflating: healet-html/images/p8.png
  inflating: healet-html/images/slider-bg.jpg
  inflating: healet-html/index.html
   creating: healet-html/js/
  inflating: healet-html/js/bootstrap.js
  inflating: healet-html/js/custom.js
  inflating: healet-html/js/jquery-3.4.1.min.js
  inflating: healet-html/shop.html

and move all content on /var/lib/docker/volumes/c1/_data/

[root@localhost Docker]#  mv ./healet-html/*  /var/lib/docker/volumes/c1/_data/

And now do entry n /etc/hosts file and then open browse the website content with your FQDN.

[root@localhost Docker]# vi /etc/hosts   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6