Understand Docker File content |Upgrade base CentOS Image | Create Docker File |Create tomcat container using CentOS Docker Image!

Barun Kumar
8 min readJun 22, 2021

Before we start creating a docker file, let’s understand what is docker file, docker file syntax and Docker image?

Environment variables are supported by the following list of instructions in the Dockerfile:

  • ADD
  • COPY
  • ENV
  • EXPOSE
  • FROM
  • LABEL
  • STOPSIGNAL
  • USER
  • VOLUME
  • WORKDIR
  • ONBUILD (when combined with one of the supported instructions above)

What is docker file?

Docker file is a text file that contains all commands, in order, needed to be build a given image.

What is Docker image?

A Docker image consists of read-only layers each of which represents a Dockerfile instruction. The layers are stacked and each one is a delta of the changes from the previous layer.

And doocker build build images automatically by reading the instruction given in docker file.

You can create a docker container in two ways

  1. Create ephemeral containers —> Refer docker page for more detail
  2. Use Multi-stage build —-> I will talks about this in this guide

Use Multi-stage build

Multi stage allow you to drastically reduce the size of your final image.

Don’t install unnecessary packages

To reduce complexity, dependencies, file sizes, and build times, avoid installing extra or unnecessary packages just because they might be “nice to have.” For example, you don’t need to include a text editor in a database image.

Docker File Syntax?

# This results in a single layer image
FROM - Base image that you want to use to create your image
#FORM centos:latest
LABEL - help organize images by project, record licensing information, automation, or for other reasons
#Example
# Set one or more individual labels
#LABEL com.example.version="0.0.1-beta"
#LABEL vendor1="ACME Incorporated"
#LABEL vendor2=ZENITH\ Incorporated
#LABEL com.example.release-date="2015-02-12"
#LABEL com.example.version.is-production=""
ENV - The ENV instruction sets the environment variable <key> to the value <value>. This value will be in the environment for all subsequent instructions in the build stage and can be replaced inline in many as well.
#ENV MY_NAME="John Doe"
#ENV MY_DOG=Rex\ The\ Dog
#ENV MY_CAT=fluffy
#ENV APP_DATA_FOLDER=/var/lib/SampleApp
#ENV SAMPLE_APP_CONFIG=${APP_DATA_FOLDER}/config/
ARG - The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build
#Example
#ARG HTTPS_PROXY=https://my-proxy.example.com
#ARG TOMCAT_FILE_PATH=/docker
VOLUME- The VOLUME instruction creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers.
#Example
#VOLUME /usr/local/tomcat
WORKDIR - Sets the working directory for the RUN, CMD, ENTRYPOINT, COPY and ADD instructions that are specified after it is used. can be run multiple times within the Dockerfile and the commands under it will then use the latest directory specified by WORKDIR.
#Example
#WORKDIR /opt/
#WORKDIR WORKDIR /usr/local/tomcat/webapps/
RUN - The RUN instruction will execute any commands in a new layer #Example
#RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'#
#RUN wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat-8.5.58.tar.gz
#RUN tar -xvzf apache-tomcat-8.5.58.tar.gz
#RUN mv apache-tomcat-8.5.58/* /opt/tomcat/
#RUN java -version
#RUN curl -O -L https://github.com/bktechtalk/dockerfile/blob/main/SampleWebApp.war
CMD - There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.
#Eaxmple
#CMD echo "This is a test." | wc -
ADD - The ADD instruction copies new files, directories or remote file URLs from host machine and adds them to the filesystem of the image at the path <dest>.
This includes handling of tar and URL handling
#Example
#ADD hom* /mydir/
COPY - Work Same as ADD without This includes handling of tar and URL handling.
#Exmple
#COPY test.txt /absoluteDir/
USER - The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for any RUN, CMD and ENTRYPOINT
#Example
#USER tomcat
EXPOSE - The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.
#Example
#EXPOSE 80/tcp
#EXPOSE 80/udp
ENTRYPOINT - Similar to CMD, but does not allow to override the command, An ENTRYPOINT allows you to configure a container that will run as an executable.
#Example
#ENTRYPOINT ["/opt/tomcat/bin/startup.sh","run"]

Note:
###########

RUN - command triggers while we build the docker image.CMD - command triggers while we launch the created docker image.CMD arguments can be overwritten by command line arguments, while ENTRYPOINT arguments are always used.COPY takes in a src and destination. It only lets you copy in a local or directory from your host (the machine-building the Docker image) into the Docker image itself.COPY <src> <dest>ADD  lets you do that too, but it also supports 2 other sources. First, you can use a URL instead of a local file/directory. Secondly, you can extract tar from the source directory into the destination.ADD <src> <dest>While functionality is similar, the ADD directive is more powerful in two ways:
It can handle remote URLs
It can also auto-extract tar files.

Also, you can follow reference link for more detail understanding.

Create your first Dockerfile for your environment using CentOS base image

Here we have Created a centos folder and Dockerfile under it and added the highlighted content in file.[root@dchydvirlanw01 ~]# cat centos/Dockerfile
FROM centos:latest
MAINTAINER selfIT.lab@home.com
RUN yum update -y

[root@dchydvirlanw01 ~]#

Create a base image using above docker file

Run docker Pre-requisites:

You should have a Linux Server with Docker Installed ( Can you window as well).

Check Docker status on your Linux Server

Refer Docker installation Link

[root@dchydvirlanw01 ~]# systemctl status docker.service
â docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2021-06-21 10:34:55 EDT; 15h ago
Docs: http://docs.docker.com
Main PID: 2510 (dockerd-current)
CGroup: /system.slice/docker.service
ââ2510 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt nati...
ââ2518 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2...
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.371245082-04:00" level=warning msg="failed to cleanup ipc mounts:\...rgument"
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.371843853-04:00" level=warning msg="3c0c7763028fbc7a11efeb19e5a0c7...rgument"
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.518186600-04:00" level=info msg="Firewalld running: false"
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.814018207-04:00" level=info msg="Removing stale sandbox 27a6e89387...788317)"
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.869222379-04:00" level=info msg="Default bridge (docker0) is assig...address"
Jun 21 10:34:54 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:54.906151474-04:00" level=info msg="Loading containers: done."
Jun 21 10:34:55 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:55.007020242-04:00" level=info msg="Daemon has completed initialization"
Jun 21 10:34:55 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:55.007176774-04:00" level=info msg="Docker daemon" commit="7d71120/1....n=1.13.1
Jun 21 10:34:55 dchydvirlanw01 dockerd-current[2510]: time="2021-06-21T10:34:55.019395542-04:00" level=info msg="API listen on /var/run/docker.sock"
Jun 21 10:34:55 dchydvirlanw01 systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
[root@dchydvirlanw01 ~]#

Pre-requisite:
- Must have a docker hub account user name (my docker hub user is- baruniitt06)
- Must have a repo created in docker hub (my repo name-rb-docker-repo)
- Image tage can be any relevant tags ( my tag- centos-baseimage)

[root@dchydvirlanw01 centos]# docker build -t baruniitt06/rb-docker-repo:centos-base-image .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM centos:latest
— -> 300e315adb2f
Step 2/3 : MAINTAINER selfIT.lab@home.com
— -> Using cache
— -> b80b8a70a88d
Step 3/3 : RUN yum update -y
— -> Using cache
Complete!
---> a5afdfee1d3a
Removing intermediate container d146684967f8
Successfully built a5afdfee1d3a
[root@dchydvirlanw01 centos]#
Check image status [root@dchydvirlanw01 centos]# docker image ls | grep a5afdfee1d3a
baruniitt06/rb-docker-repo centos-base-image a5afdfee1d3a About a minute ago 511 MB
[root@dchydvirlanw01 centos]#
Push image to docker hub repository[root@dchydvirlanw01 centos]# docker push baruniitt06/rb-docker-repo:centos-base-image
The push refers to a repository [docker.io/baruniitt06/rb-docker-repo]
97f8d182b55d: Pushed
2653d992f4ef: Layer already exists
centos-base-image: digest: sha256:f301ac338d2db350cdd64f88c408041b15902699aaa59965b487baed3b9c2d9a size: 742
[root@dchydvirlanw01 centos]#

Create a tomcat image

Now, You have your docker base docker image for your environment and want to crate tomcat image using that image.

here is my docker file for tomcat image.

[root@dchydvirlanw01 ~]# cat tomcat/Dockerfile
FROM baruniitt06/rb-docker-repo:centos-base-image
MAINTAINER selfIT.lab@home.com
RUN yum install tar wget -y
RUN mkdir /opt/tomcat/
WORKDIR /opt/tomcat/
RUN wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat-8.5.58.tar.gz
RUN tar -xvzf apache-tomcat-8.5.58.tar.gz
RUN mv apache-tomcat-8.5.58/* .
RUN yum -y install java
RUN java -version
RUN rm -rf apache-tomcat-8.5.58WORKDIR /opt/tomcat/webapps
RUN curl -O -L https://github.com/bktechtalk/dockerfile/blob/main/SampleWebApp.war
EXPOSE 8080ENTRYPOINT ["/opt/tomcat/bin/catalina.sh", "run"]
[root@dchydvirlanw01 ~]#

Create a tomcat image using my centos base image

I have my docker file in /root/tomcat folder[root@dchydvirlanw01 tomcat]# docker build -t baruniitt06/rb-docker-repo:tomcat .
Sending build context to Docker daemon 59.9 kB
Step 1/15 : FROM centos:latest
---> 300e315adb2f
Step 2/15 : MAINTAINER selfIT.lab@home.com
---> Using cache
---> b80b8a70a88d
Step 3/15 : RUN yum install tar wget -y
---> Running in a4d45c38e836
CentOS Linux 8 - AppStream 843 kB/s | 7.5 MB 00:09
CentOS Linux 8 - BaseOS 2.6 MB/s | 2.6 MB 00:01
CentOS Linux 8 - Extras 1.2 kB/s | 9.6 kB 00:08
Package tar-2:1.30-5.el8.x86_64 is already installed.
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
wget x86_64 1.19.5-10.el8 appstream 734 k
Installing dependencies:
libpsl x86_64 0.20.2-6.el8 baseos 61 k
publicsuffix-list-dafsa noarch 20180723-1.el8 baseos 56 k
Transaction Summary
================================================================================
Install 3 Packages
Total download size: 851 k
Installed size: 2.9 M
Downloading Packages:
(1/3): libpsl-0.20.2-6.el8.x86_64.rpm 422 kB/s | 61 kB 00:00
(2/3): publicsuffix-list-dafsa-20180723-1.el8.n 338 kB/s | 56 kB 00:00
(3/3): wget-1.19.5-10.el8.x86_64.rpm 178 kB/s | 734 kB 00:04
--------------------------------------------------------------------------------
Total 174 kB/s | 851 kB 00:04
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/wget-1.19.5-10.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Complete!
---> 2bea472ce5d4
Removing intermediate container 5c3fc2992ef4
Step 10/15 : RUN java -version
---> Running in 8cdc634a53de
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
---> 03f6acf3100e
Removing intermediate container 8cdc634a53de
Step 11/15 : RUN rm -rf apache-tomcat-8.5.58
---> Running in c9c7d70c6429
---> 24cb81795489
Removing intermediate container c9c7d70c6429
Step 12/15 : WORKDIR /opt/tomcat/webapps
---> f2a310845ea3
Removing intermediate container a4b74879b33a
Step 13/15 : RUN curl -O -L https://github.com/bktechtalk/dockerfile/blob/main/SampleWebApp.war
---> Running in ea7a334d2f91
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 179k 0 179k 0 0 46325 0 --:--:-- 0:00:03 --:--:-- 46325
---> a833286d73fd
Removing intermediate container ea7a334d2f91
Step 14/15 : EXPOSE 8080
---> Running in d4964d96dfc4
---> 1027ddf9e7a2
Removing intermediate container d4964d96dfc4
Step 15/15 : CMD /opt/tomcat/bin/catalina.sh run
---> Running in cf6b8b7407da
---> 3247511496f4
Removing intermediate container cf6b8b7407da
Successfully built 3247511496f4
#Check Image status[root@dchydvirlanw01 tomcat]# docker image ls | grep -i tomcat
baruniitt06/rb-docker-repo tomcat 3247511496f4 2 minutes ago 503 MB
[root@dchydvirlanw01 tomcat]#
#Create tomcat web server container using that tomcat base image.[root@dchydvirlanw01 tomcat]# docker run -d -it --name mywebserver -p 8081:8080 baruniitt06/rb-docker-repo:tomcat
c0f5bc86c2d3ca6ea9181b7c0b6a873467c7c05a3899903279fa306fc7705b29
The -d option, causes Docker to detach the container and have it run in the background. The -p argument establishes a port mapping, which defines that port 8080 of the docker container (as specified in dockerfile), should be exposed to port 8081 of our host machine.Check container status
- a : when container is not running
[root@dchydvirlanw01 tomcat]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0f5bc86c2d3 baruniitt06/rb-docker-repo:tomcat "/opt/tomcat/bin/c..." 14 seconds ago Up 14 seconds 0.0.0.0:8081->8080/tcp mywebserver
- Below command will show all running container[root@dchydvirlanw01 tomcat]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0f5bc86c2d3 baruniitt06/rb-docker-repo:tomcat "/opt/tomcat/bin/c..." About a minute ago Up About a minute 0.0.0.0:8081->8080/tcp mywebserver
[root@dchydvirlanw01 tomcat]#
#Login to tomcat container [root@dchydvirlanw01 tomcat]# docker exec -it c0f5bc86c2d3 bash
[root@c0f5bc86c2d3 webapps]#

Now Access your web server

http://<ip>:8081

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--