Docker for devs with hands-on| Part-4

In case you are landing here directly, it’s recommended to read through this documentation first.

Following are the topics, which we shall be touching through this blog :-

  • Introduction to Dockerfile.
  • Generation of DockerImage from Dockerfile.
  • Launching Docker container from DockerImage.
  • Pre-defining instructions from Dockerfile.
  • Copying files from local to Container.
  • Executing simple-service in container using Dockerfile.
  • Difference between ADD & COPY operations.
  • Launching simple tomcat within Docker-container.
  • Deploying full fledged WAR file (Spring based WebApp) inside the Docker container containing tomcat based docker image.
  • Deploying full fledged JAR file (Spring Boot based App) inside the Docker container containing JDK based docker image.

Question :- Alright, we now created an enhanced Docker-Image of our own. But, wait wait… Is it a good idea always to create and store images like this ?

Answer:- The reason why it’s not a good idea generally is that the image that we’ve just created is not repeatable. And I have no way of looking at that image in four years time and getting any kind of understanding as to what’s inside that image. I could have put anything in there. So, for that reason, we almost always would create images using a Docker file instead.

Question :- Let’s demonstrate the process of launching Docker Container from the simple DockerFile ?

Step #1.) Let’s see the DockerFile (containing simple commands) :-

We have the DockerFile being placed in one of the directory :-

Step #2.) Let’s now build a image from this Dockerfile :-

Step #3.) Let’s now verify that, whether the images has been formed new :-

Step #4.) Let’s now confirm that, we don’t have any container active right now :-

Step #5.) Let’s now launch a fresh container(In Interactive mode) from the new image that we have recently created from the DockerFile:-

Step #6.) Let’s now exit from the aforesaid container and see it in list of our containers :-

Question :- Now, we want to further launch a fresh container from Dockerfile and also transfer some java based JAR file to the container ?

Step #1.) Let’s see the DockerFile (containing simple commands) :-

Note here that, CMD is command that we wish to execute, once we start this container. Also, we can also re-write the aforesaid Dockerfile as below :-

Note here that, we have defined the current-working-directory as the particular directory and then copied the JAR file from our local machine to the CWD. Also, we have now placed the DockerFile below directory :-

Step #2.) Let’s first see, from which java class file, have we generated the JAR :-

We now try to run the above java based JAR file at our local machine :

Step #3.) Let’s now generate a fresh Docker Image from this Dockerfile :

Step #4.) Let’s verify whether a fresh Docker-Image got generated from aforementioned step:

Step #5.) Let’s launch a fresh container from newly generated DockerImage:

Please note below crucial points :-

  • We had ran the container with “-i” option which means interactive mode.
  • We had ran the container with “-t” option which means, we shall connect to the container’s terminal as well.
  • In the fresh container that we just launched, observe that JDK is already installed, as suggested in the Dockerfile itself.
  • In the fresh container , also observe that a JAR file has also been copied, because the same has been mentioned in the Dockerfile.

Step #6.) Let’s now exit from our container and observe whether this container really shows up in the list anymore :-

Step #7.) Let’s now re-start our container again :-

Step #8.) Let’s now connect to our afore-started container. We shall log inside a bash shell inside this freshly launched container again :-

Step #9.) Let’s now manually run the JAR file :-

Question :- Can we also specify that particular Java based command to execute inside container, from the Dockerfile itself ?

Step #1.) Let’s see the DockerFile (containing simple commands) :-

Step #2.) Let’s list down active containers that we have :-

We note that, we have ONE active container here :-

Step #3.) Let’s now stop this container first :-

Step #4.) Let’s now list down all containers we have :-

Step #5.) Let’s now kill all of these stopped / inactive containers :-

Note that, we can just mention the first 2 chars of the container-id as well.

Step #6.) Let’s now again verify, whether the 3 containers are now gone :-

Step 7.) Let’s now generate a fresh Docker Image from this Dockerfile and verify, whether new image got generated :

Step #8.) Let’s launch a fresh container from newly generated DockerImage:

The big difference this time is, we’re not dropped into the back shell, it’s actually immediately doing something useful, of course, this could be a Web server as Spring Boots application. This is because, we have instructed in Dockerfile itself that, execute the Jar file.

Step #9.) Let’s exit out from our container and see it in our list :-

Step #10.) Let’s start our container fresh and observe the logs of our container :-

Note that, as soon as we start the container above, it gets started in DETACHED mode (See that, container status is Up) :-

Question:- What’s the difference between COPY and ADD commands in Dockerfile ?

Answer:- It’s quite difficult to see if you compare the two, they look very, very similar and they are. It’s just that the ADD command has some extra features. For example :-

  • ADD command can work with remote-urls.
  • It can also do things like unzipping or unpacking archives.
  • It looks like ADD is generally more useful and flexible.
  • COPY command is preferred because it’s just simpler and is more obvious what copy is going to do.

Question:- What’s the difference between CMD and ENTRYPOINT commands in Dockerfile ?

Answer:-

  • If you’re working with an image that has CMD, if you wish, you can change the command that gets executed. So, I could instead of running that Java service, I could just get dropped inside the bash terminal of Docker container. And that’s going to start the container from the image, but it overrides that default command. And as you can see, I’m now dropped onto the command line and I could start doing diagnostics or whatever I want to do.
  • The same isn’t true of entry points. Now, this is a hard coded command, we rerun the build and then run a container from it and notice

Question:- Now, I want “tomcat” inside our container. What are the ways ?

Answer:-

Part #1.) One of the ways of achieving this is that :

  • First, we install JAVA/JDK inside our ‘ubuntu’ docker-container.
  • Next, we install tomcat inside our ‘ubuntu’ docker-container.

Or the other way is to use the readily available docker-image, which contains the tomcat, pre-installed in it.

Part #2.) Next, let’s search for some official ready-made tomcat based Docker-Image :-

Note that, we have got many tags available for this particular docker-image.

Part #2.) We would be choosing the “8.5.73-jdk8-openjdk” tag of this “tomcat” image and download it first.

Part #3.) Let’s see, if this image has been downloaded well onto our local machine.

Part #4.) Let’s start the corresponding container from this image

Part #4.) Let’s do this require step as well, to see the tomcat in container. So, first we login to the container recently launched and copy the webapps directory :-

Part #5.) Let’s now verify by opening the web-page exposed by this docker container :-

Part #6.) Lets now stop this container & remove it :-

Lets now verify which all containers do we have ?

Note that, the containers have been stopped as well as removed now.

Part #7.) Let’s now see, which all images we have. Note that, we have “tomcat” based image present with us, because we downloaded it in above sections.

The highlighted one, we shall be removing going forward.

Part #7.) Let’s now remove corresponding images :-

Part #7.) Let’s again visualise, which all images do we have with us now :-

Observe that, now we don’t have any image for “tomcat” related now.

Question:- Kindly demonstrate the launch-process of simple tomcat based Docker container with the help of Dockerfile :-

Answer:-

Part #1.) Note that, we can also write a Dockerfile for all of the above operations (i.e. launching container containing tomcat) too :-

Note that, with RUN mv command, we are copying a particular directory from one folder to another folder 📂 , within the container itself.

Part #2.) Let’s now head to our best friend terminal and change directory to the place, where we have our Dockerfile as demonstrated above in step #1.

Part #3.) Let’s now perform the process of building a DockerImage from the aforementioned Dockerfile :-

Note that, we had kept the name of the docker-image as “tomcat-df-aditya”.

Part #4.) Let’s check whether, our DockerImage has been formed well :-

Part #5.) Let’s launch a fresh container from this newly formed image

Part #6.) Let’s observe whether our webapp is running now. Note that, host port is 8086 :-

Now, we have our basic tomcat version 8.5.73 UP & RUNNING.

Part #7.) Let’s now log-in inside our container

Question:- How come the container is taking us to the location “/usr/local/tomcat” as soon as we are logging inside this container ?

Answer:- It’s because the same has been defined inside the Dockerfile of the “tomcat” image, from which we have generated our image & container. See below, current working directory has been changed to “/usr/local/tomcat” in below Dockerfile of this particular image.

Question:- Now that, we have seen all building blocks, Kindly demonstrate the launch-process of a simple webapp through tomcat based Docker container with the help of Dockerfile :-

Answer:-

Part #1.) Let’s utilise the below shown Dockerfile for launching container containing tomcat and thereby deploying our WAR file into it :-

Note the following points :-

  • EXPOSE command is just an indication that, tomcat within our container would be exposed on port 8080.
  • With ENV JAVA_OPTS, we are setting the Java environment variables inside the container.

Part #2.) Let’s now head to our best friend terminal and change directory to the place, where we have our Dockerfile as demonstrated above in step #1.

Part #3.) Let’s now perform the process of building a DockerImage from the aforementioned Dockerfile :-

Note that, we had kept the name of the docker-image as “tomcat — webapp-aditya”.

Part #4.) Let’s check whether, our DockerImage has been formed well :-

Part #5.) Let’s launch a fresh container from this newly formed image :-

Part #6.) Lets now login into our container :-

Part #7.) Let’s observe whether our webapp is running now. Note that, host port is 8088 :-

Now, we have our web-application running on the tomcat through container.

Part #7.) Let’s now see our container :-

Part #8.) Let’s see the logs of our container now :-

Question:- Next, Kindly demonstrate the launch-process of a simple Spring-Boot based application through JDK based Docker container with the help of Dockerfile :-

Answer:-

Part #1.) Let’s search for a right Docker based Image (containing JDK) . We shall be using the OpenJDK version 8u312.

Part #2.) Let’s utilise the below-mentioned Dockerfile for launching container containing JDK and thereby deploying our JAR file into it :-

Part #3.) Let’s now head to our best friend terminal and change directory to the place, where we have our Dockerfile as demonstrated above in step #1.

Part #4.) Let’s now perform the process of building a DockerImage from the aforementioned Dockerfile :-

Note that, we had kept the name of the docker-image as “webapp-springboot-aditya”.

Part #5.) Let’s check whether, our DockerImage has been formed well :-

Part #6.) Let’s launch a fresh container from this newly formed image :-

Part #7.) Lets now login into our container :-

Part #8.) Let’s verify, the JDK version in our container :-

Part #9.) Let’s observe whether our webapp is running now. Note that, host port is 8089 :-

Now, we have our web-application running based on the SpringBoot.

Part #10.) Let’s now see our container :-

That’s all in this section. If you liked reading this blog, kindly do press on clap button multiple times, to indicate your appreciation. We would see you in next series.

References :-

Software Engineer for Big Data distributed systems