Intro to Docker [with Java Examples]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello, I’m Dalia. In this video I want to  give you a quick introduction to Docker   and cover the most important concepts you  need to understand to start using Docker.   I'll be using a java application for my examples   but the same basic concepts apply for any  technology you're using for your applications. Let’s say you have an application written in Java  - a simple Hello World application for example.   You run it and it prints Hello World as expected. In order for this application to run,   your source code is compiled into class  files that are executed by the JVM.  The JVM is in charge of interpreting  your application according to your   operating system - and all of this  is sitting on top of your hardware. Now you have a co-worker who wants to run your  application. If the co-worker has a JVM already,   you can just package your Hello World  application into a jar and send it over to them.   Your co-worker can then take  this jar and run your application   with a one-line command and  get your Hello World! Message. In this scenario, we may not  see the benefit of Docker. So, let’s explore a more realistic scenario. You have a web application and you’re using a  variety of technologies - maybe your application   is using a database (for example, MySQL or  MongoDB) - maybe it’s using an application   server (like Tomcat or Open Liberty)  - and this is all sitting on your JVM. You run your web application and  it works great on your machine.   At this point, you want to share it with a  co-worker. So you package it up into a war   and send it over to your  co-worker to run on their machine. In this case, your co-worker can’t simply run  one command and get your application up and   running like our previous scenario. They have  to setup their database – maybe you even offer   to help them with that but you find out they’re  using MacOS and you’re on Windows so you slowly   withdraw your offer and tell  them they're on their own. They go off and spend a bunch of time  figuring out how to install the database.   They get it setup and they’re  excited to get the app running.   You tell them, oh yeah, you also have  to setup the application server too. They do that and finally  they have their full stack.   Then, they go to run the application but then  they message you and tell you the app won’t start.   Your first response is, “but  it works on my machine!”. You start debugging and you discover  that they’re using Java 8 and you   used a new feature only available in Java 11.  You ask them to install Java 11 and use that   to run your app. You keep doing this back and  forth until you finally get the app working…. ...and then someone on the testing team  asks you for your app so they can test it. ...and then someone from the deployment team  reaches out to you so they can deploy it   or you want to deploy it in your CI/CD pipeline.   And you have to go through that  setup pain over and over again. You think - there must be a better way! That’s when containers come in to help! What is a container? A container is a standard component  that allows you to package your   application and its dependencies in  an easy-to-share way. Some of the most   important characteristics of a container is that  they’re portable, isolated, and lightweight. The name “container” comes from shipping  containers. With shipping containers, you   can ship a car or a bunch of apples and the ship  doesn’t need to worry about stacking the contents   of a containers the right way, keeping them at the  right temperature or the contents interfering with   one another. As long as you provide the contents  in a uniform container, they will be shipped. Similarly, your application can be a standalone  application, a web application an enterprise   application, it could be written in Java, Kotlin,  Python, JavaScript, it could use databases,   app servers or have whatever dependencies,  as long as you package it in a container,   your co-worker, tester, or deployment person  can run your application with minimal work. Docker is the software platform  that allows you to do this. Let’s take a look at our application from  earlier and see how Docker can help us with   our previous scenario through containerization. On my operating system, I’ll install Docker and  containerize my application and it’s dependencies.   In my case, I’ll containerize my application  code, app server, along with the JVM.   But I’ll separate out the database into a  separate container since it doesn’t need   to be closely tied to my application. The  question is how does this setup benefit me? Well, instead of your co-worker having to  setup everything by hand and potentially   make mistakes in the process, if they have  Docker installed, they can instead run a   couple of docker commands that you provide  them and get my application up and running. This setup scales a lot better. A common question when  learning about containers is:   What is the difference between  containers and virtual machines? They’re both trying to solve the same  problem but they approach it differently. Let’s take a look at the VM scenario. If we wanted  to run our applications in virtual machines,   our setup would look like this. We’d have  our hardware which will be running a host   operating system. Then we’ll have a hypervisor  which creates and runs our virtual machines. When VMs are created, each VM includes  its own guest operating system which the   application runs on. Unfortunately, having a  guest operating system is not cheap resource   wise – with each guest operating system,  lots of memory and CPU are taken up. Now, let’s compare that to Docker. As we’ve  seen before, Docker sits on our operating system   layer. But with Docker containers, you  do not have a guest operating system,   making docker containers much smaller  and faster than virtual machines.   When we run our application in containers,  we use fewer resources than if we ran them   in virtual machines which allows us to run more  containers if we’d like. The startup time on   a container is also faster especially that it  doesn’t have a guest operating system to load. There are pros and cons to using containers vs  virtual machines. We won’t dive into that here   but the main takeaway is that they both solve the   “it works on my machine” problem but  approach the solution in different ways. Now that we’ve covered the  basics and benefits of docker,   we’re ready to containerize our first application.   In order to understand the process, we’ll take  the simplest application and containerize it. The first step is to install  Docker on your operating system. Second step is to build a docker image. A docker  image is what will be used to create your running   container. It’s basically a template which is used  to create and run a container. In order to create   an image, you need a Dockerfile which will include  the instructions on how to build a docker image. Third step is to run our docker  container from the docker image. If you’re not sure about the difference  between an image and a container,   a helpful analogy are classes and runtime  objects in object-oriented programming.   You can think of an image as a class -  and the container as the runtime object   you instantiate from your class. You take a  Docker image and instantiate as many containers   as you like. So a container is the  running instance of your image. Let's go ahead and see these steps in action. I’ll create a simple application. You  can use your favorite IDE to do so. I’ll create a new Java project, for my Java  version, I'll choose Java 11 - you can use   whatever verison you'd like. I’ll select the  template option so I don’t have to type out   the main method. I’ll name my project  - HelloWorldDocker. Then click Finish. In my main method, I'll print a “Hello World!”  string. Then, I'll go ahead and run it. Here is the current stack for  our Hello World application.   I want to take this application  and run it in a Docker container. First, I need to install Docker. You can  install Docker from the get docker website,   I’ve included the link in the description.   Choose the instructions that go with  your operating system. I’m running on   Windows – so I’ve already gone through the  Docker installation process for windows. Once docker is installed and has started,  I like to run the docker version command   from my commandline to ensure that everything was  installed successfully and that docker is running.   I’ll open up the terminal  window and run docker version. Now that I have Docker installed, I'm  ready for our second step which is to build   a docker image. In order to create  an image, I need a Dockerfile. Let’s create that by  right-clicking on the project,   clicking New -> file then entering Dockerfile.  Make sure you spell Dockerfile as seen here. This file will include our instructions on how to  build the image for our hello world application.   The order of the commands in a Dockerfile is very  important as each line is executed one by one. An image is made out of layers. The first  instruction of a Dockerfile specifies the   base layer of your image using the FROM  keyword then the name of the base image. With Docker, you get access to a public repository  for Docker images called DockerHub. You can browse   DockerHub to see all the images available to  you. I've personally found that Docker makes   it a lot easier to quickly setup a database  - I've used the mysql image lots of times.   An important note here is to be careful  when you're pulling images from DockerHub.   I only pull official images or  images from trusted sources. Now back to my application. Since I'm using Java,  I'll use the OpenJDK official image as my base   image. Then, I will specify a colon then a tag, in  my case, I'll use the 11 tag which is the tag for   Java 11. I could also leave the colon and tag  off which will pull the latest openjdk image. In your Dockerfile, you can add comments  in your Dockerfile with the hash sign. Next, I will create a new app  directory for my application files. I will use the RUN keyword followed by  the mkdir command with the directory name. Your Dockerfile can have multiple Run commands.  An important note here is that when you’re using   the RUN command, you’re executing commands  for your image. Meaning that this line is   creating a directory that will live inside  your container – not on your host machine. Next, I need to copy the application files  from my host machine into the image filesystem. So, I will use the COPY keyword then specify what  I'm copying from my host machine - in this case,   it's my Main class file located in  the out directory - then the second   argument is the directory in the  image where the files will be copied. I want to pause here and talk about the difference  between the COPY and RUN keywords. I used to get   confused on when my instructions apply to the  image I'm creating and when they apply to my host   machine. What helped me was to remember that when  I use RUN , the commands only apply to the image.   But when I use COPY, the first argument   applies to my host machine but the  second argument applies to the image. Next, I need to set the directory where I’ll  be executing future commands. I can do so   with the WORKDIR keyword then  specifying the app directory. Lastly, every Dockerfile needs to specify  the command that will execute when you start   a container from the image. Your  Dockerfile must contain one CMD or   ENRTYPOINT instruction specifying the default  instruction for your container. In my case,   I want to run my Main class when my container  starts. I'll use the CMD keyword then specify   the command I would run if I was trying to run my  Main class from the terminal, which is java Main. And that’s all we’ll have in our Dockerfile.  The file basically says: pull an OpenJDK image,   copy my application files into the image and  run the application when the container starts. There are other keywords you can use in a  Dockerfile but these are a good starting point. Now that we’ve finished writing our  Dockerfile, we’re ready to build our image. You can use this icon in IntelliJ IDEA to  build your image or you can use the terminal.   Let's see how we can do this using terminal. We'll run the "docker build" command. Then,  I'll use the -t option to specify my image   name and tag. I’ll call my image hello-world  and give it a 1.0 tag. You could also not   have a tag and it’ll default to a tag called  “latest”. Then, I need to specify the path   where my Dockerfile is located. Since I’m already  in the directory where the Dockerfile is located,   I can just specify a dot here for  current directory. Now let's run this. The command runs and you see the output here  including the result of each instruction in your   Dockerfile. When the FROM openjdk:11 instruction  is executed, Docker will look for the image   locally and if it doesn't find it, it'll pull it  from DockerHub. Since I don't have the openjdk   image locally, this build is taking a bit of  time but the subsquent builds won't take as long. Then we see the rest of  the Dockerfile instructions   ran successfully and our  hello-world:1.0 image is built. If we want to see the current images  we have, we can run docker images. You'll now see my new hello-world  image is now listed with the 1.0 tag.   You also see the image ID, when it  was created and the size of the image. At this point, we haven’t  actually run any containers yet,   we just created an image. I want to instantiate  my image and run my container based on this image. We can do that with the "docker run"  command. I need to specify the name   of the image that the container will be based on. I execute the docker run command  which creates the Docker container   and runs it which prints  off a Hello World! message.   This time, the Hello World! message is coming from  our application running in a Docker container. If we want to see the list of currently  running containers, we can run docker ps.   You’ll notice that our container isn’t listed  here because our application prints hello world   and immediately terminates.  Since the docker ps command   only list the containers running right now,  we don't see our hello-world container. If we want to see a list of all containers,  running and stopped, we can run docker ps –a.   Now, we see our container that already ran and  terminated. The Docker ps command lists all the   container's information including the container  ID and the image this container was based on.   You'll also notice that since we  didn't specify a container name,   Docker gave it a random silly name. Let’s change our application code a bit to mimic  the behavior of a continuously running container.   I’m going to add a loop that prints a message  every 2 seconds. You can imagine that this   is some web application that you'll  have up and running for your users. I have made my source code changes but those  are not the files going in my image. When my   image is built, Docker copies the class files so  I need to trigger an update to my class files.   I'll do that by rebuilding my project.  Or you can simply run your application. The class files have been updated so I can build  a new image using the same build command from   earlier - but this time, I'll give my image a  2.0 tag. The command runs and you'll notice it   takes less time since we already have the  openjdk:11 image pulled from last time. Now let’s run a new container from my 2.0 image.  This time, I’m going to run the container in   detached mode using the -d option which means that  the container will start and run in the background   without taking up my console window with all  the messages being printed every 2 seconds. The command is executed which  starts a container in the background   and prints out the new container's ID. Now, this time, if I run docker ps,   we see the container in our list  since it's currently running. From, here I can start as many  containers as I would like.   Let’s start another container from my 2.0  image. We can use the same command again. Now I see two containers when I run docker ps. If I want to see what is  happening in my containers so far,   I can use the docker logs command and pass in the  ID of the container I want to see the logs of.   Notice that I can use the short version of the  ID printed in the docker ps command instead   of the very long one that was printed  after my container was first created.   Looks like my container is  currently on iteration 22. If you're using IntelliJ IDEA,   you can also see a list of images and  containers in the services windows. There are lots of Docker features available in  IntelliJ IDEA that make developing application   in Docker easier. You can learn about  them through the link in the description. This wraps up our video. I hope  it was beneficial and you can now   get started using Docker with your  applications. Thanks for watching!
Info
Channel: JetBrainsTV
Views: 23,972
Rating: undefined out of 5
Keywords: JetBrains, software development, developer tools, programming, developer, docker, container, image, intellij idea, intellij, dockerfile, dockerhub
Id: FzwIs2jMESM
Channel Id: undefined
Length: 21min 16sec (1276 seconds)
Published: Wed May 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.