When we build this file, we expect the index.html file to be copied to the /var/www/html directory within the container filesystem. Let’s have a look:

$ docker build -t <your_dockerhub_user>/nginx-hello-world .

[+] Building 1.6s (10/10) FINISHED

=> [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 211B 0.0s => [internal] load .dockerignore 0.0s

=> => transferring context: 2B 0.0s

=> [internal] load metadata for docker.io/library/ubuntu:bionic 1.4s => [1/5] FROM docker.io/library/ubuntu:bionic@sha256:152dc042… 0.0s => [internal] load build context 0.0s => => transferring context: 81B 0.0s

=> CACHED [2/5] RUN apt update && apt install -y curl 0.0s => CACHED [3/5] RUN apt update && apt install -y nginx 0s => [4/5] WORKDIR /var/www/html/ 0.0s => [5/5] ADD index.html ./ 0.0s

=> exporting to image 0.0s

=> => exporting layers 0.0s

=> => writing image sha256:cb2e67bd… 0.0s

=> => naming to docker.io/<your_dockerhub_user>/nginx-hello-world

This time, the build was much faster! When we executed the Docker build, it used a lot of layers from

the cache. That is one of the advantages of layered architecture; you only build the changing part and use the existing one the way it is.

Tip

Always add source code after installing packages and dependencies. The source code changes frequently and the packages more or less remain the same. This will result in faster builds and save a lot of CI/CD time.

Let’s rerun the container and see what we get. Note that you need to remove the old container before doing so:

$ docker ps      
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
092374c45015<your_dockerhub“nginx -g28 secondsUp 270.0.0.0:80->80/loving_
 _user>/nginx-‘daemon of…”agosecondstcp, :::80->80/tcpnoether
 hello-world     

$ docker rm 092374c45015 -f

092374c45015

At this point, we can’t see the container anymore. Now, let’s rerun the container using the following command:

$ docker run -d -p 80:80 <your_dockerhub_user>/nginx-hello-world cc4fe116a433c505ead816fd64350cb5b25c5f3155bf5eda8cede5a4…

$ docker ps      
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
cc4fe116a433<your_dockerhub“nginx -g52 secondsUp 500.0.0.0:80->80/eager_
 _user>/nginx-‘daemon of…”agosecondstcp, :::80->80/tcpgates
 hello-world     

Here, we can see that the container is up and running. Let’s use curl localhost to see what we get:

$ curl localhost

Hello World! This is my first docker image!

Here, we get a custom message instead of the default NGINX HTML response!

This looks goodenough for now, but I will discuss a few more directives to make this image more reliable. First, we haven’t explicitly documented what port this container should expose. This works perfectly fine, as we know that NGINX runs on port 80, but what if someone wants to use your image and doesn’t know the port? In that scenario, it is best practice to define the port explicitly. We will use the EXPOSE directive for that.

Tip

Always use the EXPOSE directive to give more clarity and meaning to your image.

We also need to define the action to the container process if someone sends a docker stop command. While most processes take the hint and kill the process, it makes sense to explicitly specify what STOPSIGNAL the container should send on a docker stop command. We will use the STOPSIGNAL directive for that.

Now, while Docker monitors the container process and keeps it running unless it receives a SIGTERM or a stop, what would happen if your container process hangs for some reason? While your application is in a hung state, Docker still thinks it is running as your process is still running. Therefore, monitoring the application through an explicit health check would make sense. We will use the HEALTHCHECK directive for this.

Let’s combine all these aspects and see what we get in the Dockerfile:

$ vim Dockerfile

FROM ubuntu:bionic

RUN apt update && apt install -y curl

RUN apt update && apt install -y nginx

WORKDIR /var/www/html/

ADD index.html ./

EXPOSE 80

CMD [“nginx”, “-g”, “daemon off;”]

STOPSIGNAL SIGTERM

HEALTHCHECK –interval=60s –timeout=10s –start-period=20s –retries=3 CMD curl -f localhost

Leave a Reply

Your email address will not be published. Required fields are marked *