Build, Ship and Deploy static website with Docker

Building the static web app docker image, ship the image to Docker Hub and deploy app with Docker

In this hands-on lab, we will try to build the docker image of static website, ship the image to Docker Hub and then deploy the app with Docker

After going through this hands-on lab, you will gain the following knowledge:

  • Docker overview
  • Use cases of Docker
  • Docker Architecture – daemon, client, registry, objects
  • How to setup Docker in your machine?
  • How to build app image?
  • How to start app container?
  • How to ship app image?
  • How to deploy the app through docker image?


  • Knowledge of Linux Fundamentals
  • Shell Basic knowledge (Check our Mastering Shell Scripting Course)
  • Git Fundamentals knowledge

Setting up Docker

If you have Ubuntu 20.04 (Focal Fossa).

You can install the Docker engine by using the following commands:

apt update && apt install -y

Run the following command to check the client and server versions of Docker

docker version

If you are interested in more information about Docker engine, then you can run following command:

docker info

Setting up Docker in your own machine

The following steps help you setup Docker in your machine so that you can quickly play with it in your own machine as well.

Go through following steps to setup Docker in your machine:

1. Visit Official Docker Documentation.

2. Choose the installation path as per your operating system.



3. For Windows or macOS, a native binary will be downloaded. Run the binary as per the instructions given in the official documentation.

4. For Linux, choose the preferred distribution and then proceed with the provided installation instructions.

Docker Overview

Docker is an open platform for developing, shipping, and running applications.

  • Separate your applications from your infrastructure
  • Manage infrastructure in the same ways you manage your applications
  • Reduce the delay between writing code and running it in production

Read more about it here.

Docker Architecture


Docker daemon (dockerd)

  • Listens for Docker API requests.
  • Manages Docker objects such as images, containers, networks, and volumes.
  • Communicate with other daemons to manage Docker services.

Docker client (docker)

  • Command Line Interface (CLI) for user to talk to Docker daemon.
  • Communicate with more than one daemon.

Docker registries

  • Stores Docker images.
  • Docker Hub is a public registry that anyone can use.
  • Docker uses Docker Hub to look for images by default else use custom registry.
  • You can run your own private registry. Used by companies for security reasons.
  • docker pull pull the required image from registry and docker push push the image to the registry.

Docker image

  • A read-only template with instructions for creating a Docker container like Class in programming.
  • Often an image is based on another image, with some additional customization. For example, you can create an Apache web server image based on Ubuntu image.
  • You can create your own images or use images created by others.
  • To build your own image, you create a Dockerfile with a instructions for defining the steps needed to create the image and run it.
  • Images define both what you want to package in application and its dependencies.

Docker container

  • A runnable instance of an image like Object in programming.
  • By default, container is isolated from other containers and its host machine. The isolation can be controlled.
  • You can create, start, stop, move, or delete a container using the Docker API or CLI.
  • You can attach storage to it.
  • When a container is removed, any changes to its state that are not stored in persistent storage disappear.


  • A text document that contains instructions for building Docker image.
  • Instructions are usually commands a user could call on the command line to assemble an image.
  • Each instruction in the Dockerfile adds a new “layer” to the image.
  • Using docker build users can create an automated build that executes several command-line instructions in succession.

Following is an example of Dockerfile:

FROM node:16-alpine3.11

# create app directory in container
RUN mkdir -p /home/app

# copy local app to container app directory
COPY ./app /home/app

# set default app direcotry in container
WORKDIR /home/app

# install app dependencies
RUN npm install

# run the server
CMD ["node", "server.js"]

Docker Basic Commands

In this section, you will go through some of the commonly used Docker commands. These commands will help you understand more about the functionalities of Docker and its ecosystem.

docker versionShow Docker versiondocker version
docker buildBuild an image from a Dockerfiledocker build -t image_name:v1 .
docker pullPull docker image or repository from registrydocker pull alpine
docker imagesList imagesdocker images
docker runRun a command in a new containerdocker run -it alpine sh
docker execRun a command in running containerdocker exec <container id/name> sh
docker psList containersdocker ps
docker inspectDisplay information on Docker objectdocker inspect <object id/name>
docker logsFetch the logs of a containerdocker logs <container id/name>
docker networkManage networksdocker network ls
docker stopStop one or more running containersdocker stop <container id/name> [or more]
docker rmRemove one or more containersdocker rm <container id/name> [or more]
docker rmiRemove one or more imagesdocker rmi <image id/name> [or more]
docker volumeManage volumesdocker volume ls

Playing with Commands

Try to copy and run each command and understand what is happening.

NOTE: Avoid copying all commands and running it.

# List all images
docker images

# Pull Postgres latest image (debian based)
docker pull postgres

# Pull Postgres alpine image
docker pull postgres:13.4-alpine

# Run Postgres container based on latest image
docker run --name deb-postgres -e POSTGRES_PASSWORD=password -d postgres

# Run Postgres container based on alpine image
docker run --name alpine-postgres -e POSTGRES_PASSWORD=password -d postgres:13.4-alpine

# See all the running containers
docker ps

# Execute command on running container (run same for alpine-postgres)
docker exec -it deb-postgres bash

# then run following commands
root@83b53844c490:/# su postgres
postgres@83b53844c490:/$ psql

# --- play with database ----
CREATE DATABASE dhanu; # create database
\c dhanu; # use database

# create users table
  person_id serial PRIMARY KEY,
  password VARCHAR(50) NOT NULL,

# list the tables

# insert records into table
INSERT INTO users(username, password, email)
VALUES ('admin', 'admin123', '');
INSERT INTO users(username, password, email)
VALUES ('foo', 'foo123', '');

# view the table content
select * from users;

# exit from psql

exit # exit from postgres user
exit # exit from root

# Stop running container
docker stop alpine-postgres

# Seel all containers (exited as well)
docker ps -a

# Remove an exited container
docker rm alpine-postgres

# Remove a running container forcefully
docker rm -f deb-postgres

# See logs of a container
docker logs deb-postgres

Building Static website Docker Image

In this section, you will build the Docker image for the static website.

NOTE: A static website is a website whose content doesn’t change unless changed by the developer in the web server whereas the Dynamic website content changes as per the user’s setting.

For the demo purpose, we will be using the online-cv open source project which is a minimal Jekyll Theme to host your online resume (CV). Hope you like the CV.

Go through the following set of instructions:

1. Get the static website source code:

git clone

2. Enter into the webcvstatic directory.

3. Review the Dockerfile.

4. Build the application image by running following command:

docker build -t webcv:v1 .

Running Static website Docker Image

In this step, you will run the static website by creating the container from the Docker image you built in previous section.

Run the static website container as:

docker run -d -p 30000:80 webcv:v1

Now, open the port URL http://localhost:30000.

You should see the Web CV running similar to below:

NOTE: Content are dummy only.
NOTE: Content are dummy only.

Shipping the Application Image

Now, since you are able to build the application image, you want to deploy it to the server.

For that purpose, you need to host this application image somewhere so that it can be taken from CI tool like Jenkins and then deploy it to the server.

To host the application image, we need registry where we can push our application image. For the demo purpose, we will be using Docker Hub.

NOTE: One can use private registry as well to store Docker images.

Prepare the application image

Currently, our application image repository name is webcv. We need to rename as per our Docker Hub username.

1. Run following commands to give new tag to image:

docker login # enter Docker hub credentials
docker tag webcv:v1 dhanusir/webcv:v1  # replace 'dhanusir' with your username

Push the application image

Now, run following command to push the application image:

docker push dhanusir/webcv:v1

Verify the application image

Visit Docker Hub and verify the application image.

Use or Deploy static website with Docker image

Now, your Web CV docker image is available in the Docker registry.

You can use this application image to deploy it in your server.

You can perform similar steps in your local machine as well.

For this, you need to delete the application image you created in the earlier step. Then, Docker engine will pull the image from registry and run the container out of it.

docker rmi -f dhanusir/webcv:v1       # for the demo in local machine only

Run the static website by just running the following command:

docker run --name webcv1 -d -p 30001:80 dhanusir/webcv:v1

Updating the static website to new version

In this section, you will go through the process of updating your web CV to new version.

For the demo purpose, we will update the role of the user here.

Run the following command to update the role in the static website index page.

sed -i 's/DevOps Engineer/Sr. DevOps Engineer/' webcv/index.html

Confirm by running the following git command:

git diff

Now, build the new docker image version for the web CV by running following command:

docker build -t webcv:v2 .

Confirm by checking the list of images:

docker images

Now, you need to ship this new version to the Docker Hub. 

Run the following commands to push the version v2:

docker tag webcv:v2 dhanusir/webcv:v2
docker push dhanusir/webcv:v2

You can confirm in the Docker Hub for the presence of v2 image. It will look like below:

Web CV versions in Docker Hub.
Web CV versions in Docker Hub.

Finally, update web CV app by removing previous container and running new container by running following commands:

docker rm -f webcv1
docker run --name webcv2 -d -p 30001:80 dhanusir/webcv:v1

Now, open the port URL http://localhost:30001.

You should see the update Web CV running similar to below:

Updated CV with role "Sr. DevOps Engineer"
Updated CV with role “Sr. DevOps Engineer”


I hope that by now you have a rough understanding of installing Docker, architecture of Docker, basic docker commands, how to build application image, how to run container, how to push local Docker image to public Docker registry and how to deploy app from the Docker registry hosted images.

Join Our Newsletter

Share this article:

Table of Contents