0 00:00:00,019 --> 00:00:00,050 in 1 00:00:00,159 --> 00:00:03,740 this video, I will teach you all the main concepts of docker, 2 00:00:03,750 --> 00:00:07,250 including getting your first hands on experience with it. 3 00:00:07,460 --> 00:00:09,819 So if you have to use docker at work, 4 00:00:09,829 --> 00:00:14,300 or if you need to learn docker to level up your engineering skills and need to get 5 00:00:14,310 --> 00:00:17,250 started fast and understand all the main concepts and 6 00:00:17,260 --> 00:00:19,659 learn basics of how to work with Docker, 7 00:00:19,870 --> 00:00:24,459 this crash course is exactly right for you. First we'll start by 8 00:00:24,620 --> 00:00:25,040 and what do 9 00:00:25,239 --> 00:00:27,479 is why was it even created basically, 10 00:00:27,489 --> 00:00:30,770 what problems it solves in engineering and how 11 00:00:30,780 --> 00:00:33,529 it helps in software development and deployment process. 12 00:00:33,650 --> 00:00:35,560 So you will understand exactly why do 13 00:00:35,759 --> 00:00:41,689 is such a big deal and why it has become so popular and widely used in IT projects 14 00:00:42,119 --> 00:00:45,479 and as part of a virtualization solution, doer 15 00:00:45,709 --> 00:00:50,770 being an improvement over virtual machines or the next evolution step, 16 00:00:50,779 --> 00:00:54,330 I will also explain the difference between virtual machine and darker, 17 00:00:54,340 --> 00:00:56,430 and what are the advantages of 18 00:00:56,639 --> 00:00:58,099 doer in this comparison. 19 00:00:58,299 --> 00:01:00,810 After we've understood why we want to use do 20 00:01:01,029 --> 00:01:03,209 in the first place, we will install 21 00:01:03,450 --> 00:01:07,209 doer and learn how to actually work with it. We will learn the concepts of 22 00:01:07,349 --> 00:01:09,589 doer images, containers, darker 23 00:01:09,690 --> 00:01:12,160 registry, public and private registries, 24 00:01:12,169 --> 00:01:18,580 and we will run containers locally based on some of the images available on Docker 25 00:01:18,790 --> 00:01:21,010 public Registry called Docker Hub. 26 00:01:21,260 --> 00:01:24,480 We will also learn the concept of creating your own images 27 00:01:24,489 --> 00:01:28,430 and learning about the docker image blueprint called Docker File. 28 00:01:28,589 --> 00:01:29,160 And of course, 29 00:01:29,169 --> 00:01:33,540 we will see all this in action and learn all the docker commands for pulling images, 30 00:01:33,550 --> 00:01:37,199 running containers, building your own docker image, et cetera. 31 00:01:37,440 --> 00:01:42,139 We will also learn about versioning images with image text, and finally, 32 00:01:42,150 --> 00:01:44,720 after you've learned how to work with Docker, 33 00:01:44,730 --> 00:01:48,580 I will also explain with graphical animations how do 34 00:01:48,790 --> 00:01:53,370 fits in the big picture of software development and deployment process. 35 00:01:53,379 --> 00:01:54,910 So by the end of this video, 36 00:01:54,919 --> 00:01:59,250 you will feel way more confident about your knowledge and understanding in 37 00:01:59,449 --> 00:01:59,730 doer 38 00:01:59,919 --> 00:02:03,209 and can easily build on that foundation knowledge 39 00:02:03,325 --> 00:02:06,335 to become a docker power user if you want to. 40 00:02:06,575 --> 00:02:08,015 And under the video description, 41 00:02:08,026 --> 00:02:11,595 I will provide some resources to learn even more about Docker 42 00:02:11,766 --> 00:02:15,656 and become more advanced in it. But before we jump right in, 43 00:02:15,886 --> 00:02:18,035 it seems like many of you watching the 44 00:02:18,046 --> 00:02:21,095 videos on our channel are still not subscribed, 45 00:02:21,106 --> 00:02:23,695 so if you're getting some value out of the 46 00:02:23,705 --> 00:02:26,716 free tutorials I put out regularly on this channel, 47 00:02:26,725 --> 00:02:31,322 be sure to subscribe not to me, any future videos or tutorials. 48 00:02:31,332 --> 00:02:35,272 I would also be happy to connect with you on my other social media accounts, 49 00:02:35,281 --> 00:02:39,841 where I post behind the scenes content, weekly updates and so on. 50 00:02:40,011 --> 00:02:42,602 So I hope to connect to you there as well. 51 00:02:42,611 --> 00:02:47,462 Well, I am super excited to teach you all this, so let's get into it. 52 00:02:47,761 --> 00:02:51,022 Let's start with the most important question. What is do? 53 00:02:51,261 --> 00:02:54,981 Why was it even created? And what problem does it solve? 54 00:02:58,199 --> 00:03:02,119 In simple words, Docker is a virtualization software 55 00:03:02,229 --> 00:03:05,899 that makes developing and deploying applications very easy, 56 00:03:06,240 --> 00:03:10,669 much easier compared to how it was done before Docker was introduced. 57 00:03:10,899 --> 00:03:14,460 And Docker does that by packaging an application 58 00:03:14,630 --> 00:03:17,660 into something called a container that has 59 00:03:17,669 --> 00:03:20,169 everything the application needs to run, 60 00:03:20,360 --> 00:03:24,300 like the application code itself, its libraries and dependencies, 61 00:03:24,330 --> 00:03:27,820 but also the run time and environment configuration. 62 00:03:28,259 --> 00:03:31,210 So application and it's running environment are 63 00:03:31,220 --> 00:03:35,229 both packaged in a single docker package, 64 00:03:35,240 --> 00:03:37,619 which you can easily share and distribute. 65 00:03:38,029 --> 00:03:40,369 Now, why is this a big deal, 66 00:03:40,380 --> 00:03:42,570 and how were applications actually developed 67 00:03:42,580 --> 00:03:45,750 and deployed before Docker was introduced. 68 00:03:46,100 --> 00:03:50,770 Let's see that to understand the benefits of Docker more clearly. 69 00:03:54,429 --> 00:03:57,940 So how did we develop applications before containers? 70 00:03:58,320 --> 00:04:01,610 Usually when you have a team of developers working on some application, 71 00:04:01,649 --> 00:04:04,190 they would have to install all the services. 72 00:04:04,199 --> 00:04:05,240 That application 73 00:04:05,350 --> 00:04:07,929 depends on or needs, like database services, 74 00:04:07,940 --> 00:04:10,960 et cetera directly on their operating system. 75 00:04:10,970 --> 00:04:11,419 Right. 76 00:04:11,550 --> 00:04:15,800 For example, if you're developing a JavaScript application and you need a post 77 00:04:16,149 --> 00:04:17,369 SQL database, 78 00:04:17,640 --> 00:04:18,769 maybe you need 79 00:04:19,070 --> 00:04:24,429 a for cashing mosquito for messaging. Like if you have a micro service application. 80 00:04:24,910 --> 00:04:28,920 Now you need all these services locally on your development environment 81 00:04:28,929 --> 00:04:32,269 so you can actually develop and test the application right, 82 00:04:32,649 --> 00:04:38,420 and every developer in the team would then have to go and install all those services, 83 00:04:38,429 --> 00:04:42,890 configure and run them on their local development environment 84 00:04:42,899 --> 00:04:46,160 and depending on which operating system they're using, 85 00:04:46,279 --> 00:04:48,640 the installation process will be different 86 00:04:48,970 --> 00:04:50,130 because installing a post 87 00:04:50,470 --> 00:04:51,660 QL database on 88 00:04:51,779 --> 00:04:52,079 me 89 00:04:52,339 --> 00:04:56,339 OS is different from installing it on a Windows machine, For example, 90 00:04:56,619 --> 00:04:59,859 another thing with installing services directly on 91 00:04:59,869 --> 00:05:03,049 an operating system following some installation guide 92 00:05:03,149 --> 00:05:07,380 is that usually have multiple steps of installation, 93 00:05:07,579 --> 00:05:09,700 and then configuration of the service. 94 00:05:09,730 --> 00:05:13,109 So with multiple commands that you have to execute to install, 95 00:05:13,119 --> 00:05:15,010 configure and set up the service, 96 00:05:15,019 --> 00:05:20,429 the chances of something going wrong and error happening is actually pretty high. 97 00:05:20,440 --> 00:05:21,309 And this approach, 98 00:05:21,320 --> 00:05:25,535 or this process of setting up a development environment for a developer, 99 00:05:25,545 --> 00:05:30,765 can actually be pretty tedious, depending on how complex your application is. 100 00:05:30,774 --> 00:05:34,695 For example, if you have 10 services that your application is using, 101 00:05:34,954 --> 00:05:41,214 then you would have to do that installation 10 times for each service. 102 00:05:41,225 --> 00:05:41,695 And again, 103 00:05:41,704 --> 00:05:44,795 it will differ within the team based on 104 00:05:44,804 --> 00:05:47,195 what operating system each developer is using. 105 00:05:47,464 --> 00:05:51,635 Now let's see how containers solve some of these problems 106 00:05:51,970 --> 00:05:52,940 with containers. 107 00:05:52,950 --> 00:05:55,040 You actually do not have to install any 108 00:05:55,049 --> 00:05:57,880 of the services directly on your operating system, 109 00:05:58,019 --> 00:06:04,089 because with Docker you have that service packaged in one isolated environment. 110 00:06:04,170 --> 00:06:04,940 So you have 111 00:06:05,260 --> 00:06:10,170 posters QL with a specific version packaged with its whole configuration 112 00:06:10,380 --> 00:06:12,000 inside of a container. 113 00:06:12,220 --> 00:06:16,950 So as a developer, you don't have to go and look for some binaries 114 00:06:17,100 --> 00:06:19,750 to download and install on your machine. 115 00:06:19,869 --> 00:06:22,630 But rather you just go ahead and start that service 116 00:06:22,640 --> 00:06:27,029 as a docker container using a single docker Command, 117 00:06:27,049 --> 00:06:30,559 which fetches the container package from Internet 118 00:06:30,739 --> 00:06:32,750 and starts it on your computer 119 00:06:33,170 --> 00:06:35,299 and the docker command will be the same 120 00:06:35,309 --> 00:06:38,690 regardless of which operating system you're on, 121 00:06:38,809 --> 00:06:42,709 and it will also be the same regardless of which service you are installing. 122 00:06:42,720 --> 00:06:46,149 So if you have 10 services that your JavaScript application depends on, 123 00:06:46,230 --> 00:06:52,079 you would just have to run 10 docker commands for each container, and that will be it. 124 00:06:52,380 --> 00:06:55,239 So as you see docker standardises, 125 00:06:55,250 --> 00:06:58,269 the process of running any service on your development 126 00:06:58,279 --> 00:07:01,769 environment and makes the whole process much easier. 127 00:07:01,790 --> 00:07:05,239 So you can basically focus and work more on development instead 128 00:07:05,250 --> 00:07:08,510 of trying to install and configure services on your machine. 129 00:07:09,019 --> 00:07:13,269 And this obviously makes setting up your local development environment 130 00:07:13,429 --> 00:07:16,070 much faster and easier than 131 00:07:16,299 --> 00:07:19,010 the option without containers. 132 00:07:19,190 --> 00:07:21,089 Plus with the Docker, 133 00:07:21,100 --> 00:07:24,519 you can even have different versions of the same application 134 00:07:24,570 --> 00:07:28,535 running on your local environment without having any conflict, 135 00:07:28,545 --> 00:07:30,774 which is very difficult to do 136 00:07:30,934 --> 00:07:33,904 if you're installing that same application with 137 00:07:33,915 --> 00:07:36,565 different versions directly on your operating system, 138 00:07:36,855 --> 00:07:41,975 and we will actually see all of this in action in the demo part of this video. 139 00:07:42,105 --> 00:07:46,605 Now let's see how containers can improve the application deployment process 140 00:07:46,924 --> 00:07:50,994 before containers. A traditional deployment process would look like this 141 00:07:51,500 --> 00:07:55,910 development team would produce an application artefact or a package 142 00:07:56,059 --> 00:07:59,410 together with a set of instructions of how to actually 143 00:07:59,420 --> 00:08:03,380 install and configure that application package on the server. 144 00:08:03,390 --> 00:08:06,920 So you would have something like a jar file for job 145 00:08:06,929 --> 00:08:11,140 application or something similar depending on the programming language used. 146 00:08:11,529 --> 00:08:13,190 And in addition, of course, 147 00:08:13,200 --> 00:08:15,700 you would have some kind of database service 148 00:08:15,709 --> 00:08:18,339 or some other services that your application needed, 149 00:08:18,489 --> 00:08:21,450 also with a set of instructions of how to configure 150 00:08:21,600 --> 00:08:26,420 and set it up on the server so that application could connect to it and use it. 151 00:08:26,690 --> 00:08:28,920 So the development team would give that application 152 00:08:28,929 --> 00:08:32,950 artefact or package over to the operations team, 153 00:08:33,130 --> 00:08:34,489 and the operations team 154 00:08:34,690 --> 00:08:36,510 would handle installing 155 00:08:36,710 --> 00:08:38,510 and configuring the application 156 00:08:38,760 --> 00:08:41,659 and all its tenant services like database, for example. 157 00:08:41,669 --> 00:08:44,880 Now, the problem with this kind of approach is that first of all, 158 00:08:44,890 --> 00:08:47,880 you need to configure everything and install everything 159 00:08:48,049 --> 00:08:52,109 again directly on the operating system, which I mentioned 160 00:08:52,489 --> 00:08:55,659 in the development context that is actually very error prone, 161 00:08:55,669 --> 00:08:59,520 and you can have various different problems during the setup process. 162 00:08:59,539 --> 00:09:03,330 You can also have conflicts with dependency versions where 163 00:09:03,340 --> 00:09:06,000 two services are depending on the same library, 164 00:09:06,010 --> 00:09:08,070 for example, but with different versions. 165 00:09:08,080 --> 00:09:09,239 And when that happens, 166 00:09:09,250 --> 00:09:12,659 it's gonna make the setup process way more difficult and complex. 167 00:09:12,700 --> 00:09:16,530 So basically a lot of things that can go wrong when operations 168 00:09:16,539 --> 00:09:21,780 team is installing and setting up application and services on a server. 169 00:09:22,330 --> 00:09:25,830 Another problem that could arise from this kind of process is 170 00:09:25,960 --> 00:09:28,750 when there is a miscommunication between 171 00:09:28,820 --> 00:09:31,500 the development team and operations team. 172 00:09:31,880 --> 00:09:35,440 Because since everything is in a textual guide, 173 00:09:35,450 --> 00:09:40,559 like an instruction list of how to configure and run the application, 174 00:09:40,729 --> 00:09:42,489 or maybe some kind of checklist, 175 00:09:42,500 --> 00:09:45,400 there could be cases where developers forget 176 00:09:45,409 --> 00:09:47,989 to mention some important step about configuration. 177 00:09:48,000 --> 00:09:49,880 And when that part fails, 178 00:09:49,890 --> 00:09:55,565 the operations team have to go back to developers and ask for more details and input. 179 00:09:55,684 --> 00:09:58,585 And this could lead to some back and forth communication 180 00:09:58,594 --> 00:10:02,025 until the application is successfully deployed on the server. 181 00:10:02,034 --> 00:10:05,494 So basically you have this additional communication overhead where 182 00:10:05,505 --> 00:10:09,094 developers have to communicate in some kind of textual 183 00:10:09,275 --> 00:10:11,705 graphical whatever format, 184 00:10:11,815 --> 00:10:13,744 how the application should run, 185 00:10:13,994 --> 00:10:17,275 and as I mentioned, this could lead to issues and miscommunications 186 00:10:17,469 --> 00:10:21,820 with containers. This process is actually simplified because 187 00:10:22,080 --> 00:10:25,549 now developers create an application package 188 00:10:25,700 --> 00:10:28,309 that doesn't only include the code itself, 189 00:10:28,320 --> 00:10:33,109 but also all the dependencies and the configuration for the application. 190 00:10:33,119 --> 00:10:36,789 So instead of having to write that in some textual format and document, 191 00:10:37,020 --> 00:10:41,270 they basically just package all of that inside the application artefact. 192 00:10:41,280 --> 00:10:44,409 And since it's already encapsulated in one environment, 193 00:10:44,995 --> 00:10:47,645 the operations people don't have to configure any 194 00:10:47,656 --> 00:10:49,755 of this stuff directly on the server. 195 00:10:49,765 --> 00:10:53,125 So it makes the whole process way easier. 196 00:10:53,226 --> 00:10:57,185 And there is less room for issues that I mentioned previously. 197 00:10:57,375 --> 00:11:00,846 So the only thing now that operations team need to do in this case 198 00:11:00,856 --> 00:11:06,945 is to run a docker command that gets the container package that developers created 199 00:11:07,096 --> 00:11:08,955 and runs it on the server. 200 00:11:09,135 --> 00:11:11,426 The same way operations team will run a serve 201 00:11:11,771 --> 00:11:15,471 that application needs also as docker containers, 202 00:11:15,502 --> 00:11:19,901 and that makes the deployment process way easier on the operation side. 203 00:11:19,911 --> 00:11:20,661 Now, of course, 204 00:11:20,671 --> 00:11:23,651 the operations team will have to install and set up the docker run 205 00:11:23,661 --> 00:11:28,012 time on the server before they will be able to run containers. 206 00:11:28,091 --> 00:11:32,781 But that's just one time effort for one service or one technology. 207 00:11:32,901 --> 00:11:35,541 And once you have docker run time installed, 208 00:11:35,552 --> 00:11:38,382 you can simply run docker containers on that server 209 00:11:41,780 --> 00:11:46,770 Now. At the beginning, I mentioned that docker is a virtualization tool, 210 00:11:46,969 --> 00:11:52,109 just like a virtual machine, And virtual machines have been around for a long time. 211 00:11:52,289 --> 00:11:55,229 So why did darker become so widely adopted? 212 00:11:55,239 --> 00:11:58,950 What advantages it has over virtual machines, 213 00:11:58,960 --> 00:12:00,799 and what is the difference between the two? 214 00:12:01,070 --> 00:12:03,739 For that, we need to see a little bit of how doer 215 00:12:03,960 --> 00:12:05,890 works on a technical level. 216 00:12:06,099 --> 00:12:07,809 I also said that with Docker, 217 00:12:07,820 --> 00:12:11,500 you don't need to install services directly on operating system. 218 00:12:11,679 --> 00:12:12,270 But 219 00:12:12,520 --> 00:12:17,510 in that case, how does Docker run its containers on an operating system? 220 00:12:17,700 --> 00:12:19,679 Now, in order to understand all this, 221 00:12:19,849 --> 00:12:23,909 let's first look at how an operating system is made up. 222 00:12:23,919 --> 00:12:26,130 Operating systems have two main layers. 223 00:12:26,309 --> 00:12:28,369 You have the operating system kernel 224 00:12:28,559 --> 00:12:31,669 and the operating system applications. Layer 225 00:12:32,039 --> 00:12:37,989 and kernel is the part that communicates with the hardware components like CPU, 226 00:12:38,000 --> 00:12:39,969 memory storage, et cetera. 227 00:12:39,979 --> 00:12:42,289 So when you have a physical machine 228 00:12:42,409 --> 00:12:45,909 with all these resources and you install operating system 229 00:12:46,159 --> 00:12:47,710 on that physical machine, 230 00:12:47,859 --> 00:12:50,494 the kernel of the operating system will actually 231 00:12:50,505 --> 00:12:53,244 be the one talking to the hardware components 232 00:12:53,354 --> 00:12:57,354 to allocate resources like CPU memory storage, et cetera, 233 00:12:57,515 --> 00:13:01,255 to the applications, then running on that operating system. 234 00:13:01,364 --> 00:13:05,005 And those applications are part of the applications layer, 235 00:13:05,114 --> 00:13:07,505 and they run on top of the kernel layer. 236 00:13:07,840 --> 00:13:12,049 So kernel is kind of a middle man between the applications that you see 237 00:13:12,169 --> 00:13:14,409 when you interact with your computer 238 00:13:14,520 --> 00:13:17,770 and the underlying hardware of your computer. 239 00:13:17,950 --> 00:13:23,950 And now, since Docker and Virtual Machine are both virtualization tools, 240 00:13:23,960 --> 00:13:25,340 the question is 241 00:13:25,500 --> 00:13:30,549 what part of the operating system they actually virtualize? 242 00:13:30,630 --> 00:13:32,289 And that's where the main difference 243 00:13:32,299 --> 00:13:34,765 between docker and virtual machines actually like 244 00:13:34,955 --> 00:13:38,005 so docker virtualize the applications layer. 245 00:13:38,244 --> 00:13:40,465 This means when you run a docker container, 246 00:13:40,474 --> 00:13:43,934 it actually contains the applications layer 247 00:13:44,094 --> 00:13:47,515 of the operating system and some other applications 248 00:13:47,525 --> 00:13:49,674 installed on top of that application layer. 249 00:13:49,924 --> 00:13:52,815 It could be a java run time or python or whatever, 250 00:13:53,104 --> 00:13:58,625 and it uses the kernel of the host because it doesn't have its own kernel. 251 00:13:58,929 --> 00:14:01,090 The virtual machine, on the other hand, 252 00:14:01,109 --> 00:14:04,500 has the applications layer and its own kernel. 253 00:14:04,510 --> 00:14:07,919 So it virtualize the complete operating system, 254 00:14:07,929 --> 00:14:12,750 which means that when you download a virtual machine image on your host. 255 00:14:13,010 --> 00:14:17,325 It doesn't use the hosts kernel. It actually boots up its own. 256 00:14:17,544 --> 00:14:21,715 So what does this difference between darker and virtual machine actually mean? 257 00:14:21,724 --> 00:14:26,875 First of all, the size of the darker packages or images are much smaller 258 00:14:27,015 --> 00:14:30,674 because they just have to implement one layer 259 00:14:30,895 --> 00:14:32,215 of the operating system 260 00:14:32,455 --> 00:14:35,224 so darker images are usually a couple of megabytes. 261 00:14:35,234 --> 00:14:39,974 Large virtual machine images, on the other hand, can be a couple of gigabytes. 262 00:14:40,294 --> 00:14:44,135 This means when working with Docker, you actually save a lot of disc space. 263 00:14:44,580 --> 00:14:49,729 You can run and start docker containers much faster than virtual machines, 264 00:14:49,739 --> 00:14:53,580 because virtual machine has to put up a kernel every time it starts, 265 00:14:53,770 --> 00:14:56,169 while docker container just reuses 266 00:14:56,340 --> 00:14:59,669 the host kernel and it just starts the application layer on top of it. 267 00:14:59,679 --> 00:15:02,979 So while virtual machine needs a couple of minutes to start up, 268 00:15:02,989 --> 00:15:05,409 docker containers usually start up in a 269 00:15:05,510 --> 00:15:06,510 few milliseconds. 270 00:15:06,780 --> 00:15:08,960 The third difference is compatibility, 271 00:15:09,010 --> 00:15:14,599 so you can run virtual image of any operating system on any other 272 00:15:14,739 --> 00:15:16,590 operating system host. 273 00:15:16,599 --> 00:15:20,729 So on a Windows machine, you can run a Linux virtual machine, for example. 274 00:15:21,080 --> 00:15:26,359 But you can't do that with Docker, at least not directly so What is the problem here? 275 00:15:26,650 --> 00:15:30,719 Let's say you have a Windows operating system with Windows Kernel 276 00:15:30,869 --> 00:15:34,309 and its application layer, and you want to run a Linux 277 00:15:34,460 --> 00:15:40,169 based docker image directly on that Windows host. The problem here is that Linux 278 00:15:40,299 --> 00:15:46,210 based Docker image cannot use the Windows kernel. It would need a Linux kernel to run 279 00:15:46,429 --> 00:15:49,919 because you can run a Linux application layer on a windows Kern. 280 00:15:50,481 --> 00:15:52,981 So that's kind of an issue with Docker. 281 00:15:53,171 --> 00:15:54,012 However, 282 00:15:54,252 --> 00:15:56,831 when you're developing on Windows or Me 283 00:15:57,021 --> 00:15:57,461 OS, 284 00:15:57,752 --> 00:16:03,822 you want to run various services because most containers for the popular services 285 00:16:03,952 --> 00:16:05,841 are actually Linux based. 286 00:16:05,961 --> 00:16:11,651 Also interesting to know that Docker was originally written and built for Linux 287 00:16:12,231 --> 00:16:13,142 but later 288 00:16:13,533 --> 00:16:16,494 actually made an update and developed what's 289 00:16:16,504 --> 00:16:20,903 called Docker desktop for Windows and Mac, 290 00:16:20,914 --> 00:16:23,174 which made it possible 291 00:16:23,443 --> 00:16:29,294 to run Linux based containers on Windows and Mac computers as well. 292 00:16:29,304 --> 00:16:34,304 So the way it works is that darker desktop uses a hypervisor layer 293 00:16:34,453 --> 00:16:36,504 with a lightweight Linux 294 00:16:36,736 --> 00:16:37,945 distribution on top of it 295 00:16:38,185 --> 00:16:40,875 to provide the needed Linux kernel 296 00:16:41,185 --> 00:16:43,546 and this way make running Linux 297 00:16:43,695 --> 00:16:48,726 based containers possible on Windows and Mac operating systems. 298 00:16:48,736 --> 00:16:49,486 And by the way, 299 00:16:49,495 --> 00:16:53,625 if you want to understand more about virtualization and how virtual machines work. 300 00:16:53,635 --> 00:16:55,835 And what a hypervisor, for example, is. 301 00:16:55,846 --> 00:16:59,616 You can watch my other video, where I explain all of that in detail. 302 00:17:00,309 --> 00:17:02,840 So this means for local development. 303 00:17:02,849 --> 00:17:07,430 As an engineer, you would install darker desktop on your Windows or Mac 304 00:17:07,680 --> 00:17:08,640 OS computer 305 00:17:08,819 --> 00:17:09,800 to run Linux 306 00:17:09,920 --> 00:17:15,160 based images, which, as I mentioned most of the popular services databases, 307 00:17:15,170 --> 00:17:18,219 etcetera are mostly Linux based. 308 00:17:18,229 --> 00:17:19,560 So you would need that, 309 00:17:19,939 --> 00:17:22,050 and that brings us to the 310 00:17:22,199 --> 00:17:23,800 installation of 311 00:17:24,040 --> 00:17:24,329 doer. 312 00:17:24,780 --> 00:17:27,680 In order to do some demos and learn docker in practise, 313 00:17:27,689 --> 00:17:29,119 you would first need to install it. 314 00:17:29,560 --> 00:17:30,910 So in order to install Docker, 315 00:17:30,920 --> 00:17:34,390 you just go to their official page for installation guide 316 00:17:34,510 --> 00:17:35,810 and follow the steps. 317 00:17:35,819 --> 00:17:40,650 Because Docker gets updated all the time, the installation changes. 318 00:17:40,660 --> 00:17:43,050 So instead of me just giving you some comments that 319 00:17:43,060 --> 00:17:46,290 may work now but will get updated in the future, 320 00:17:46,300 --> 00:17:48,579 you should always refer to the latest 321 00:17:48,589 --> 00:17:52,150 documentation for installation Guide for any tool. 322 00:17:52,619 --> 00:17:55,869 So if we search for Docker desktop 323 00:17:56,229 --> 00:17:57,310 installation 324 00:17:58,510 --> 00:18:02,859 and click on one of those links like install on Windows, so that's 325 00:18:03,050 --> 00:18:04,489 the Docker desktop, 326 00:18:04,760 --> 00:18:06,099 the tool that I mentioned that 327 00:18:06,260 --> 00:18:10,219 solved this problem of running Linux based images on a different operating system, 328 00:18:10,229 --> 00:18:13,130 but it actually includes a lot of other things when you install it. 329 00:18:13,140 --> 00:18:16,680 So what are you exactly installing with Docker desktop? 330 00:18:17,380 --> 00:18:19,689 And you see exactly what's included in there. 331 00:18:19,880 --> 00:18:23,239 So basically, get the Docker service itself. It's called Docker 332 00:18:23,349 --> 00:18:23,790 Engine Engine. 333 00:18:24,069 --> 00:18:29,680 That's the main part of the docker that makes this virtualization possible. 334 00:18:29,689 --> 00:18:32,630 But when we have a service, we need to communicate with that, right, 335 00:18:32,640 --> 00:18:33,800 So we need a client 336 00:18:33,939 --> 00:18:35,890 that can talk to that service. 337 00:18:35,900 --> 00:18:40,969 So Docker Desktop actually comes with a command line interface client, 338 00:18:41,250 --> 00:18:44,959 which means we can execute darker commands on a command line 339 00:18:45,140 --> 00:18:51,239 to start containers to create containers, start stop them, remove them et cetera, 340 00:18:51,349 --> 00:18:57,760 and do all kinds of things. And it also comes with a graphical user interface client. 341 00:18:57,900 --> 00:19:00,640 So if you're not comfortable working with command line, 342 00:19:00,650 --> 00:19:06,160 you can actually use the graphical user interface where you can do all these things. 343 00:19:06,189 --> 00:19:08,770 But in a nice, user friendly U, I 344 00:19:09,130 --> 00:19:11,619 So you get all these things when you install Docker desktop, 345 00:19:11,630 --> 00:19:14,260 basically everything that you need to get started with Docker 346 00:19:14,630 --> 00:19:17,920 and of course, depending on which operating system you're on, 347 00:19:17,930 --> 00:19:20,489 you're gonna choose that one Mac Windows or Linux. 348 00:19:20,500 --> 00:19:26,439 So let's click on one of those, and you basically just follow the instructions. 349 00:19:26,449 --> 00:19:28,800 You have some system requirements. You have to check 350 00:19:28,969 --> 00:19:32,119 things like the the version of your Mac OS, 351 00:19:32,880 --> 00:19:34,869 how much resources you're gonna need. 352 00:19:35,050 --> 00:19:39,949 And you also have the options for Mac with Intel or Mac 353 00:19:39,959 --> 00:19:44,339 with Apple Silicon so you can toggle between those and basically, 354 00:19:44,349 --> 00:19:49,449 just choose the guide that matches your computer specifications. 355 00:19:49,500 --> 00:19:52,239 And once you have that, check the system requirements, 356 00:19:52,439 --> 00:19:55,334 go ahead and click on one of those. 357 00:19:55,474 --> 00:19:57,324 In my case, I have Mac with Intel 358 00:19:57,525 --> 00:19:59,555 Chip, so I would click on this one, 359 00:19:59,564 --> 00:20:02,655 and that's actually the Docker desktop installer. 360 00:20:02,714 --> 00:20:05,994 So if I click, it's gonna download this DMG 361 00:20:06,094 --> 00:20:09,635 image. And once it's downloaded, you basically just follow 362 00:20:09,785 --> 00:20:11,305 the steps described here, 363 00:20:11,564 --> 00:20:14,204 right? You double click on it, open the application 364 00:20:14,564 --> 00:20:15,224 and so on. 365 00:20:16,260 --> 00:20:20,099 And same for Windows. If your windows, you basically click on this one 366 00:20:20,250 --> 00:20:22,869 and download Docker desktop for Windows 367 00:20:22,979 --> 00:20:25,880 and make sure to check the system requirements 368 00:20:26,040 --> 00:20:28,000 and kind of prepare everything 369 00:20:28,300 --> 00:20:30,170 you need for starting Docker. 370 00:20:30,459 --> 00:20:35,750 Generally for latest versions of Windows, Mac or whatever operating system. 371 00:20:35,859 --> 00:20:39,800 It should be pretty easy and straightforward to install Docker. 372 00:20:40,079 --> 00:20:41,810 So go ahead and do that. 373 00:20:42,030 --> 00:20:43,900 Once you're done with installation, 374 00:20:44,260 --> 00:20:48,180 you can simply start the service by searching Docker. 375 00:20:48,439 --> 00:20:49,579 And if I click on it, 376 00:20:49,849 --> 00:20:51,420 you will see right here 377 00:20:51,660 --> 00:20:53,030 that it's actually 378 00:20:53,500 --> 00:20:56,640 starting up. Docker service for Docker engine. 379 00:20:58,359 --> 00:20:59,540 And there you go, 380 00:21:00,020 --> 00:21:00,810 it's running, 381 00:21:01,130 --> 00:21:05,000 And this view here that you are seeing this window is 382 00:21:05,010 --> 00:21:08,439 actually the graphical user interface of Docker that I mentioned. 383 00:21:08,599 --> 00:21:13,079 So that's the client that you can use to interact with the docker engine. 384 00:21:13,199 --> 00:21:17,500 So you have a list of containers running currently, so there's no list, 385 00:21:17,770 --> 00:21:21,689 same with images. If I switch to images, I have cleaned up my environment. 386 00:21:21,699 --> 00:21:25,270 So I'm starting with scratch with empty state just like you. 387 00:21:25,660 --> 00:21:28,790 So we are ready to start using darker. 388 00:21:28,890 --> 00:21:32,229 But first you may be wondering what are images, 389 00:21:32,239 --> 00:21:34,189 And that's what I'm gonna explain next, 390 00:21:34,199 --> 00:21:36,589 because it's a very important concept in darker 391 00:21:40,400 --> 00:21:45,640 now men that Docker allows to package the application with its environment 392 00:21:45,650 --> 00:21:50,569 configuration in this package that you can share and distribute easily. 393 00:21:50,910 --> 00:21:53,050 So just like an application artefact file, 394 00:21:53,060 --> 00:21:56,790 like when we create a zip or tar file or a jar file, 395 00:21:56,800 --> 00:22:00,800 which you can upload to a artefact storage and then 396 00:22:00,810 --> 00:22:03,670 download on the server or locally whenever you need it. 397 00:22:03,859 --> 00:22:09,880 And that package or artefact that we produce with Docker is called a docker image. 398 00:22:09,890 --> 00:22:12,500 So it's basically an application artefact 399 00:22:12,790 --> 00:22:15,439 but different from Jar File 400 00:22:15,569 --> 00:22:17,619 or from other application artefacts. 401 00:22:17,839 --> 00:22:21,390 It not only has the compiled application code inside, 402 00:22:21,469 --> 00:22:24,119 but additionally has information about 403 00:22:24,219 --> 00:22:26,079 the environment configuration. 404 00:22:26,270 --> 00:22:29,719 It has the operating system application layer, as I mentioned, 405 00:22:29,729 --> 00:22:34,900 plus the tools like node N, PM or Java run time 406 00:22:35,045 --> 00:22:35,625 installed on that, 407 00:22:35,635 --> 00:22:39,135 depending on what programming language your application was written in. 408 00:22:39,344 --> 00:22:42,364 For example, if you have a JavaScript application, 409 00:22:42,545 --> 00:22:46,935 you would need node Js and N PM to run your application right, 410 00:22:47,285 --> 00:22:52,625 So in the darker image, you would actually have node and N PM installed already. 411 00:22:52,824 --> 00:22:57,234 You can also add environment variables that your application needs. For example, 412 00:22:57,439 --> 00:22:58,939 you can create directories. 413 00:22:58,949 --> 00:23:02,300 You can create files or any other environment 414 00:23:02,310 --> 00:23:05,699 configuration whatever you need around your application. 415 00:23:05,849 --> 00:23:10,250 So all of that information is packaged in the docker image, 416 00:23:10,260 --> 00:23:12,229 together with the application code, 417 00:23:12,550 --> 00:23:15,810 and that's the great advantage of Docker that we talked about. 418 00:23:15,829 --> 00:23:18,719 And as I said, the package is called an image. 419 00:23:19,219 --> 00:23:22,410 So if that's an image, what is a container, then? 420 00:23:22,670 --> 00:23:26,300 Well, we need to start that application package somewhere, right? 421 00:23:26,420 --> 00:23:30,329 So when we take that package or image and download 422 00:23:30,339 --> 00:23:34,140 it to a server or your local computer laptop, 423 00:23:34,150 --> 00:23:36,089 we want to run it on the computer. 424 00:23:36,150 --> 00:23:38,050 The application has to actually run. 425 00:23:38,619 --> 00:23:41,920 And when we run that image on an operating system 426 00:23:42,099 --> 00:23:45,209 and the application inside starts in the pre 427 00:23:45,219 --> 00:23:48,729 configured environment that gives us a container. 428 00:23:48,959 --> 00:23:53,250 So a running instance of an image is a container. 429 00:23:53,260 --> 00:23:58,349 So a container is basically a running instance of an image and 430 00:23:58,359 --> 00:24:02,969 from the same image from one image you can run multiple containers, 431 00:24:02,979 --> 00:24:06,030 which is a legitimate use case if you need to run 432 00:24:06,180 --> 00:24:10,489 multiple instances of the same application for increased performance, 433 00:24:10,500 --> 00:24:13,415 for example, and that's exactly what we were seeing here. 434 00:24:13,425 --> 00:24:18,135 So we have the images. These are the application packages, basically, 435 00:24:18,275 --> 00:24:20,234 and then from those images we can start 436 00:24:20,244 --> 00:24:23,694 containers which we will see listed right here, 437 00:24:23,704 --> 00:24:26,974 which are running instances of those images. 438 00:24:27,244 --> 00:24:28,645 And I also said that 439 00:24:28,834 --> 00:24:31,535 in addition to the graphical user interface, 440 00:24:31,545 --> 00:24:35,864 we get a command line interface client do client that can talk to do 441 00:24:36,204 --> 00:24:36,444 engine. 442 00:24:36,939 --> 00:24:37,650 And 443 00:24:37,819 --> 00:24:40,130 since we installed Docker desktop, 444 00:24:40,140 --> 00:24:43,670 we should have that docker CLI also available locally, 445 00:24:43,680 --> 00:24:47,910 which means if you open your terminal, you should be able to execute docker commands 446 00:24:48,189 --> 00:24:50,619 and documents. We can do anything. 447 00:24:50,630 --> 00:24:54,594 For example, we can check what images we have available locally. 448 00:24:54,604 --> 00:25:00,035 So if I do docker images that will give me a list of images that I have locally, 449 00:25:00,064 --> 00:25:04,484 which in this case I don't have any which we saw in the graphical user interface. 450 00:25:04,494 --> 00:25:08,405 And I can also check the containers using a command docker, 451 00:25:09,280 --> 00:25:10,390 PS 452 00:25:11,640 --> 00:25:12,250 and again, 453 00:25:12,479 --> 00:25:14,969 I don't have any running containers yet. 454 00:25:15,260 --> 00:25:18,020 Now, before moving on, I want to give a shout out to Net 455 00:25:18,150 --> 00:25:19,000 Hopper. Neuer's 456 00:25:19,349 --> 00:25:21,109 cloud platform, called 457 00:25:21,489 --> 00:25:21,589 kubernetes 458 00:25:21,689 --> 00:25:27,890 application operations, offers an easy way for devops teams to deliver, manage, 459 00:25:27,900 --> 00:25:32,699 upgrade, connect, secure and monitor applications in one or more ktis 460 00:25:33,030 --> 00:25:33,750 clusters. 461 00:25:34,160 --> 00:25:38,349 With this platform, they basically create this virtual network layer 462 00:25:38,459 --> 00:25:40,739 that connects multiple environments. 463 00:25:40,839 --> 00:25:44,510 For example, if you have multiple cloud platforms and multiple 464 00:25:44,880 --> 00:25:48,170 clusters, even your own on Premise Data centre, 465 00:25:48,180 --> 00:25:50,050 where your application gets deployed, 466 00:25:50,239 --> 00:25:55,795 you can connect all these in a one virtual network so you can deploy and operate 467 00:25:55,805 --> 00:25:58,775 your community's workloads as if it was in 468 00:25:58,785 --> 00:26:02,584 one cluster or one infrastructure environment and the get 469 00:26:02,704 --> 00:26:06,594 up centric approach they use offers the visibility to know who 470 00:26:06,604 --> 00:26:10,375 did what and when for both your infrastructure and application. 471 00:26:10,599 --> 00:26:14,209 So with Net Hopper enterprises can automate their operations. 472 00:26:14,219 --> 00:26:17,010 And instead of building an own platform, 473 00:26:17,020 --> 00:26:20,550 devops teams can focus on what matters the most, 474 00:26:20,560 --> 00:26:24,109 which is releasing more application features faster. 475 00:26:24,349 --> 00:26:29,300 So check them out. You can actually sign up for a free account and take it for a spin 476 00:26:29,500 --> 00:26:32,569 to see if Net Hopper is the right solution for you. 477 00:26:36,239 --> 00:26:39,729 Now it's clear that we get containers by running images, 478 00:26:40,069 --> 00:26:43,709 But how do we get images to run containers from? 479 00:26:44,189 --> 00:26:45,489 Let's say we want to run 480 00:26:46,160 --> 00:26:47,739 a database container or 481 00:26:47,989 --> 00:26:52,449 or some lock collector service container. How do we get their darker images? 482 00:26:52,689 --> 00:26:55,829 Well, that's where docker registries come in. 483 00:26:56,150 --> 00:27:02,949 So there are ready docker images available online in an image storage or registry. 484 00:27:03,000 --> 00:27:09,050 So basically, this is a storage specifically for darker image type of artefacts, 485 00:27:09,430 --> 00:27:12,209 and usually the companies developing those services 486 00:27:12,459 --> 00:27:13,209 like ready 487 00:27:13,829 --> 00:27:16,349 to be et cetera, as well as Docker. 488 00:27:16,359 --> 00:27:21,939 Community itself will create what's called official images. So you know this mongo 489 00:27:22,319 --> 00:27:24,420 image was actually created by 490 00:27:24,959 --> 00:27:27,060 itself or the Docker community. 491 00:27:27,130 --> 00:27:31,689 So you know, it's an official verified image from Docker itself. 492 00:27:31,699 --> 00:27:36,160 And Docker itself offers the biggest docker registry 493 00:27:36,270 --> 00:27:37,930 called Docker Hub, 494 00:27:37,939 --> 00:27:42,119 where you can find any of these official images and many other 495 00:27:42,130 --> 00:27:44,849 images that different companies or individual 496 00:27:44,859 --> 00:27:48,410 developers have created and uploaded there. 497 00:27:48,959 --> 00:27:51,089 So if we search for dark Hub 498 00:27:51,489 --> 00:27:55,930 right here, you see doctor Hub Container Image library. 499 00:27:57,449 --> 00:27:58,089 And 500 00:27:58,319 --> 00:27:59,530 that's how it looks like. 501 00:27:59,540 --> 00:28:02,189 And you don't actually have to register or sign 502 00:28:02,199 --> 00:28:05,239 up on Dock Hub to find those official images. 503 00:28:05,250 --> 00:28:10,250 So anyone can go on this website and basically browse the container images. 504 00:28:10,290 --> 00:28:12,380 And here in Search Bar, 505 00:28:12,500 --> 00:28:16,339 you can type any service that you're looking for. For example, ready 506 00:28:16,569 --> 00:28:17,560 that I mentioned. 507 00:28:17,689 --> 00:28:19,479 And if I hit enter, 508 00:28:19,640 --> 00:28:21,180 you will basically see a 509 00:28:21,530 --> 00:28:27,430 list of various ready related images as well as the ready service itself 510 00:28:27,829 --> 00:28:29,520 as a darker image. 511 00:28:29,530 --> 00:28:34,359 And here you have this batch or label that says darker official image, for example, 512 00:28:34,369 --> 00:28:36,959 for the reddest image that we are going to choose here, 513 00:28:36,969 --> 00:28:40,319 you see that it is actually maintained by Docker community. 514 00:28:40,329 --> 00:28:44,780 The way it works is that Docker has a dedicated team that is responsible 515 00:28:44,885 --> 00:28:50,344 for reviewing and publishing all content in the darker official images. 516 00:28:50,354 --> 00:28:54,704 And this team works in the collaboration with the technology creators, 517 00:28:54,714 --> 00:28:57,954 or maintainers, as well as security experts 518 00:28:58,064 --> 00:29:01,864 to create and manage those official darker images. 519 00:29:02,329 --> 00:29:05,890 So this way it is ensured that not only the 520 00:29:05,900 --> 00:29:09,959 technology creators are involved in the official image creation, 521 00:29:10,000 --> 00:29:14,099 but also all the darker security, best practises and production. 522 00:29:14,109 --> 00:29:17,959 Best practises are also considered in the image creation, 523 00:29:18,189 --> 00:29:22,890 and that's basically the Description page with all the 524 00:29:22,900 --> 00:29:25,849 information about how to use this darker image, 525 00:29:25,859 --> 00:29:27,500 what it includes, et cetera 526 00:29:28,199 --> 00:29:32,989 and again, as I said, Docker Hub is the largest docker image registry, 527 00:29:33,000 --> 00:29:36,319 so you can find images for any service that you 528 00:29:36,459 --> 00:29:38,689 want to use on Docker Hub. 529 00:29:38,910 --> 00:29:39,859 Now, of course, 530 00:29:39,869 --> 00:29:45,560 technology changes and there are updates to applications in those technologies. 531 00:29:45,589 --> 00:29:47,910 So you have a new version of red 532 00:29:48,040 --> 00:29:49,270 or mango to B, 533 00:29:49,660 --> 00:29:51,380 and in that case a new 534 00:29:51,650 --> 00:29:53,390 doer image will be created, 535 00:29:53,760 --> 00:29:56,869 so images are version as well, 536 00:29:57,199 --> 00:29:59,640 and these are called image tags. 537 00:29:59,660 --> 00:30:03,709 And on the page of each image you actually 538 00:30:03,719 --> 00:30:08,069 have the list of versions or tags of that image 539 00:30:08,250 --> 00:30:09,829 listed right here. 540 00:30:09,939 --> 00:30:11,000 So this is for 541 00:30:11,849 --> 00:30:14,079 And if I search for um Post, 542 00:30:14,430 --> 00:30:15,339 for example, 543 00:30:19,199 --> 00:30:21,890 you will see different image tags for 544 00:30:22,319 --> 00:30:24,089 res image also listed here. 545 00:30:24,630 --> 00:30:29,430 So when you're using a technology and you need a specific version, you can choose 546 00:30:29,650 --> 00:30:33,189 a darker image that has that version of the technology. 547 00:30:33,290 --> 00:30:37,660 And there is a special tag that all images have 548 00:30:37,790 --> 00:30:41,890 called latest. So right here you see this latest tag 549 00:30:42,280 --> 00:30:44,469 or here as well in the recent text. 550 00:30:44,819 --> 00:30:50,750 So latest tag is basically the latest, the last image that was built. 551 00:30:50,760 --> 00:30:54,589 So if you don't specify or choose a version explicitly, 552 00:30:54,729 --> 00:30:58,089 you basically get the latest image from the Docker hub. 553 00:30:58,099 --> 00:31:00,719 So now we've seen what images are 554 00:31:00,930 --> 00:31:03,030 and where you can get them. 555 00:31:03,050 --> 00:31:04,229 So now the question is, 556 00:31:04,239 --> 00:31:09,113 how do we actually get the image from Docker Hub and download it 557 00:31:09,123 --> 00:31:13,083 locally on our computer so we can start a container from that image. 558 00:31:13,192 --> 00:31:19,912 So first we locate the image that we want to run as a container locally for our demo. 559 00:31:19,922 --> 00:31:21,213 I'm going to use an engine 560 00:31:21,453 --> 00:31:24,253 image. So go ahead and search for Engine, 561 00:31:24,883 --> 00:31:28,625 which is basically a simple Web server and has a U I. 562 00:31:28,916 --> 00:31:32,635 So we will be able to access our container from 563 00:31:32,645 --> 00:31:36,005 the browser to validate The container has started successfully. 564 00:31:36,176 --> 00:31:37,286 That's why I'm choosing engine, 565 00:31:38,145 --> 00:31:41,145 and here you have a bunch of image tags 566 00:31:41,735 --> 00:31:42,845 that you can choose from. 567 00:31:43,095 --> 00:31:48,676 So the second step after locating the image is to pick a specific image tech 568 00:31:49,270 --> 00:31:51,150 and note that selecting 569 00:31:51,420 --> 00:31:56,300 a specific version of image is the best practise in most cases. 570 00:31:56,359 --> 00:32:00,699 And let's say we choose version 1.23. 571 00:32:00,709 --> 00:32:05,040 So we're choosing this tag right here and to download an image. 572 00:32:05,050 --> 00:32:09,140 We go back to our terminal and we execute docker 573 00:32:09,510 --> 00:32:13,819 Pull command, and we specify the name of the image, 574 00:32:13,939 --> 00:32:14,920 which is 575 00:32:15,040 --> 00:32:15,900 engine X. 576 00:32:16,619 --> 00:32:18,900 So you have that whole command here as well, 577 00:32:18,930 --> 00:32:22,229 so that's basically the name of the image that you have written here. 578 00:32:22,449 --> 00:32:23,910 So that's NGX. 579 00:32:24,310 --> 00:32:25,030 And then 580 00:32:25,170 --> 00:32:30,000 we specify the image tag by separating it with a colon 581 00:32:30,219 --> 00:32:31,439 and then the version 582 00:32:31,630 --> 00:32:34,089 1.23. That's what we chose. 583 00:32:34,530 --> 00:32:38,520 That's the whole command. So Docker Client will contact do 584 00:32:38,699 --> 00:32:41,829 Hub and will say, I want to grab 585 00:32:41,979 --> 00:32:42,670 the engine 586 00:32:42,810 --> 00:32:47,760 image with this specific tag and download it locally. So let's execute. 587 00:32:49,869 --> 00:32:53,609 And here we see that it's pulling the image from 588 00:32:53,869 --> 00:32:56,500 the image registry Docker hub. 589 00:32:56,750 --> 00:32:59,890 And the reason why we don't have to tell Docker to 590 00:33:00,010 --> 00:33:04,819 find that image on Docker Hub is because Docker Hub is actually the default 591 00:33:04,989 --> 00:33:10,300 location where Docker will look for any images that we specify right here. 592 00:33:10,579 --> 00:33:13,839 So it's automatically configured as a location for 593 00:33:13,849 --> 00:33:17,579 downloading the images from and the download happened. 594 00:33:17,949 --> 00:33:22,770 And now if we execute docker images command again, as we did here, 595 00:33:23,050 --> 00:33:26,890 we should actually see one image now locally, which is engine 596 00:33:27,430 --> 00:33:29,060 with an image tag 597 00:33:29,180 --> 00:33:30,760 1.23 598 00:33:31,030 --> 00:33:34,089 and some other information like the size of the image, 599 00:33:34,260 --> 00:33:37,010 which is usually in megabytes, 600 00:33:37,119 --> 00:33:38,079 as I mentioned. 601 00:33:38,199 --> 00:33:40,140 So we have an image now locally, 602 00:33:40,489 --> 00:33:45,540 and if we pull an image without any specific tag, 603 00:33:45,900 --> 00:33:49,959 so we do this basically docker pull a name of the image. 604 00:33:49,969 --> 00:33:54,880 And if I execute this, you see that it is pulling the latest image automatically. 605 00:33:55,060 --> 00:33:56,459 And now if I do do 606 00:33:56,660 --> 00:33:57,760 images again, 607 00:33:58,160 --> 00:34:01,329 we're gonna see two images of engine 608 00:34:02,140 --> 00:34:04,140 with two different text, 609 00:34:04,329 --> 00:34:08,438 right? So these are actually two separate images with different versions. 610 00:34:08,668 --> 00:34:09,120 Cool. 611 00:34:09,129 --> 00:34:10,899 Now we have images locally, 612 00:34:10,909 --> 00:34:15,958 but obviously they are only useful when we run them in a container environment. 613 00:34:15,969 --> 00:34:18,719 How can we do that? Also super easy. 614 00:34:18,899 --> 00:34:22,449 We pick the image we already have available locally 615 00:34:22,560 --> 00:34:25,280 with the tag. So let's say we want to run 616 00:34:25,429 --> 00:34:27,120 this image as a container 617 00:34:27,489 --> 00:34:30,830 and we execute darker run command 618 00:34:30,978 --> 00:34:31,280 and 619 00:34:31,429 --> 00:34:33,399 with the name of the image 620 00:34:33,639 --> 00:34:35,030 and the tag 621 00:34:35,830 --> 00:34:37,050 super easy 622 00:34:37,530 --> 00:34:38,790 and let's execute. 623 00:34:39,050 --> 00:34:42,978 And that command actually starts the container based on the image. 624 00:34:43,040 --> 00:34:46,239 And we know the container started because we see the 625 00:34:46,250 --> 00:34:50,958 logs of engine service starting up inside the container. 626 00:34:50,989 --> 00:34:54,159 So these are actually container logs that we see in the console. 627 00:34:54,320 --> 00:34:56,260 So it's launching a couple of scripts, 628 00:34:57,610 --> 00:35:03,669 and right here we have start worker processes and the container is running. 629 00:35:04,060 --> 00:35:05,159 So now 630 00:35:05,379 --> 00:35:07,820 if I open a new terminal session 631 00:35:08,199 --> 00:35:09,030 like this 632 00:35:09,330 --> 00:35:09,939 and 633 00:35:10,580 --> 00:35:11,330 do do 634 00:35:11,679 --> 00:35:12,629 PS, 635 00:35:13,860 --> 00:35:16,699 I should actually see one container, 636 00:35:16,850 --> 00:35:17,840 this one here 637 00:35:18,290 --> 00:35:20,469 in the running container list, 638 00:35:20,820 --> 00:35:23,679 and we have some information about the container. We have the ID. 639 00:35:23,800 --> 00:35:26,709 We have the image that the container is based on, 640 00:35:26,719 --> 00:35:29,409 including the tech when it was created 641 00:35:29,610 --> 00:35:34,689 and also the name of the container. So we have the ID and name of the container. 642 00:35:34,860 --> 00:35:38,729 This is the name which docker actually automatically 643 00:35:38,969 --> 00:35:42,409 generates and assigns to a container when it's created. 644 00:35:42,800 --> 00:35:45,060 So it's some random generated name. 645 00:35:45,669 --> 00:35:50,469 Now, if I go back here, you see that these logs, the container logs, 646 00:35:50,479 --> 00:35:52,780 actually are blocking the terminal. 647 00:35:52,969 --> 00:35:57,879 So if I want to get the terminal back and do control C exit, 648 00:35:57,889 --> 00:36:01,179 the container exits and the process actually dies. 649 00:36:01,189 --> 00:36:02,020 So now if I do do 650 00:36:02,239 --> 00:36:05,739 PS, you will see that there is no container running. 651 00:36:06,219 --> 00:36:08,129 But we can start a container 652 00:36:08,260 --> 00:36:12,209 in the background without it blocking the terminal by adding 653 00:36:13,050 --> 00:36:14,760 a flag called minus D, 654 00:36:15,010 --> 00:36:16,610 which stands for detached. 655 00:36:16,729 --> 00:36:19,810 So it detaches the docker process from terminal. 656 00:36:20,389 --> 00:36:21,600 And if I execute this, 657 00:36:21,840 --> 00:36:25,550 you see that it's not blocking the terminal anymore. 658 00:36:25,699 --> 00:36:29,959 And instead of showing the logs from engine X starting up inside the container, 659 00:36:29,969 --> 00:36:31,020 it just locks out 660 00:36:31,179 --> 00:36:34,780 the full ID of the container. So now if I do do 661 00:36:34,959 --> 00:36:35,689 PS 662 00:36:35,949 --> 00:36:39,219 here in the same terminal, I should see that container 663 00:36:39,439 --> 00:36:40,620 running again. 664 00:36:41,060 --> 00:36:46,729 And that's basically the ID or the part of the this full ID string 665 00:36:46,919 --> 00:36:48,010 shown here. 666 00:36:48,219 --> 00:36:52,209 But when we start a container in the background in a detached mode, 667 00:36:52,239 --> 00:36:56,550 you may still want to see the application logs inside the container, 668 00:36:56,580 --> 00:36:59,030 so you may want to see how did engine next start up? 669 00:36:59,040 --> 00:37:01,129 What did it look, actually, so 670 00:37:01,340 --> 00:37:05,629 for that, you can use another docker command called Docker logs 671 00:37:06,199 --> 00:37:08,489 with the container ID 672 00:37:08,590 --> 00:37:09,370 like this, 673 00:37:10,159 --> 00:37:14,159 and it will print out the application logs from the container. 674 00:37:14,530 --> 00:37:17,229 Now, in order to create the container 675 00:37:17,540 --> 00:37:22,340 container, we first pull the image, and then we created a container from that image. 676 00:37:22,560 --> 00:37:23,199 But 677 00:37:23,429 --> 00:37:26,469 we can actually save ourselves the pull command 678 00:37:26,739 --> 00:37:28,169 and execute 679 00:37:28,360 --> 00:37:33,600 run command directly, even if the image is not available locally. 680 00:37:34,010 --> 00:37:37,169 So right now we have these two images available locally, 681 00:37:37,479 --> 00:37:39,159 But in the Docker run command, 682 00:37:39,169 --> 00:37:43,290 you can actually provide any image that exists on Docker Hub. 683 00:37:43,370 --> 00:37:47,159 It doesn't necessarily have to exist locally on your computer, 684 00:37:47,169 --> 00:37:49,080 so you don't have to pull that first. 685 00:37:49,090 --> 00:37:52,419 So if I go back, we can actually choose a different image version. 686 00:37:52,429 --> 00:37:56,780 Let's choose 1.22 dash alpine, 687 00:37:56,969 --> 00:37:57,489 so 688 00:37:58,780 --> 00:38:00,139 this image tag, 689 00:38:00,639 --> 00:38:02,610 which we don't have locally 690 00:38:03,120 --> 00:38:07,370 or Of course, this can be completely different service. It doesn't matter. 691 00:38:07,489 --> 00:38:10,189 So basically any image that we don't have locally 692 00:38:10,300 --> 00:38:13,729 you can run directly using docker run command. 693 00:38:14,199 --> 00:38:17,159 So what it does is first. It will try to 694 00:38:17,330 --> 00:38:18,879 locate that image 695 00:38:19,050 --> 00:38:19,830 locally, 696 00:38:19,969 --> 00:38:21,439 and if it doesn't find it, 697 00:38:21,610 --> 00:38:24,949 it will go to Docker hub by default 698 00:38:25,129 --> 00:38:29,129 and pull the image from there automatically, which is very convenient. 699 00:38:29,270 --> 00:38:35,590 So it does both in one command, basically. So it downloaded the image with this tag 700 00:38:36,149 --> 00:38:38,169 and started the container. 701 00:38:38,520 --> 00:38:40,989 And now if we do docker PS, 702 00:38:41,129 --> 00:38:44,770 we should have two containers running with different 703 00:38:45,239 --> 00:38:46,169 versions. 704 00:38:46,639 --> 00:38:47,889 And remember, I said, 705 00:38:47,899 --> 00:38:52,239 Docker solves the problem of running different versions of the same application 706 00:38:52,580 --> 00:38:56,159 at once. So that's how simple it is to do that with Docker 707 00:38:56,479 --> 00:38:59,659 so we can actually click this container. 708 00:39:00,030 --> 00:39:00,689 And 709 00:39:00,939 --> 00:39:02,520 now again, we have 710 00:39:02,639 --> 00:39:06,419 that one engine container with this version. 711 00:39:09,929 --> 00:39:14,500 Now the important question is, how do we access this container? 712 00:39:14,510 --> 00:39:16,449 Well, we can't right now 713 00:39:16,770 --> 00:39:19,459 because the container is running in 714 00:39:19,590 --> 00:39:25,659 the closed Docker network, so we can't access it from our local computer browser, 715 00:39:25,669 --> 00:39:26,449 For example, 716 00:39:26,479 --> 00:39:29,780 we need to first expose the container to our 717 00:39:29,790 --> 00:39:33,100 local network which may sound a little bit difficult, 718 00:39:33,110 --> 00:39:34,639 but it's super easy. 719 00:39:34,860 --> 00:39:38,360 So basically, we're gonna do what's called a port binding. 720 00:39:38,870 --> 00:39:42,060 The container is running on some port, right, 721 00:39:42,270 --> 00:39:46,979 and each application has some standard port on which it's running, 722 00:39:47,179 --> 00:39:47,770 like engine 723 00:39:47,969 --> 00:39:48,830 application 724 00:39:48,989 --> 00:39:51,169 always runs on Port 80 Red 725 00:39:51,370 --> 00:39:52,500 runs on Port 726 00:39:52,669 --> 00:39:55,290 6379. 727 00:39:55,439 --> 00:39:58,169 So these are standard ports for these applications. 728 00:39:58,179 --> 00:40:02,169 So that's the port where container is running on. 729 00:40:02,489 --> 00:40:03,020 And for 730 00:40:03,489 --> 00:40:08,179 we see the ports under the list of ports here, application is running on Port A 731 00:40:08,280 --> 00:40:12,159 inside the container. So now if I try to access 732 00:40:12,379 --> 00:40:12,489 engine 733 00:40:12,850 --> 00:40:13,719 container 734 00:40:14,090 --> 00:40:17,409 on this port on Port 80 from the browser 735 00:40:19,100 --> 00:40:20,989 and let's try to do that 736 00:40:21,219 --> 00:40:22,110 Port 80 737 00:40:22,719 --> 00:40:23,620 hit enter. 738 00:40:23,760 --> 00:40:26,689 You see that nothing is available on this port 739 00:40:26,830 --> 00:40:29,969 on local host. So now we can tell Docker 740 00:40:30,360 --> 00:40:33,989 Hey, you know what? Bind that container port 80 741 00:40:34,520 --> 00:40:36,879 to our local host on 742 00:40:37,020 --> 00:40:42,689 any port that I tell you on some specific port like 80 80 or 9000, 743 00:40:42,699 --> 00:40:47,699 it doesn't actually matter so that I can access the container or whatever is running 744 00:40:47,709 --> 00:40:52,860 inside the container as if it was running on my local host port 9000. 745 00:40:53,030 --> 00:40:57,750 And we do that with an additional flag when creating 746 00:40:57,870 --> 00:40:59,290 a darker container. 747 00:40:59,800 --> 00:41:00,379 So 748 00:41:00,729 --> 00:41:04,689 what we're gonna do is first, we're gonna stop this container 749 00:41:05,750 --> 00:41:08,379 and create a new one. So we're gonna do, Doctor, 750 00:41:08,929 --> 00:41:09,800 which 751 00:41:10,489 --> 00:41:13,169 basically stops this running container, 752 00:41:13,550 --> 00:41:15,820 and we're gonna create a new container. 753 00:41:16,570 --> 00:41:17,989 So we're gonna do do 754 00:41:18,169 --> 00:41:18,669 run 755 00:41:19,050 --> 00:41:19,979 engine X 756 00:41:20,949 --> 00:41:21,870 the same version 757 00:41:22,179 --> 00:41:25,520 and we're going to find it in the background in detach mode. 758 00:41:25,530 --> 00:41:31,040 Now we're gonna do the port binding with an additional flick minus P, 759 00:41:31,080 --> 00:41:32,110 and it's super easy. 760 00:41:32,120 --> 00:41:33,290 We're telling Docker 761 00:41:33,689 --> 00:41:34,439 the 762 00:41:34,679 --> 00:41:35,120 engine 763 00:41:35,389 --> 00:41:36,800 application port 764 00:41:37,219 --> 00:41:38,760 inside container, which is a 765 00:41:39,429 --> 00:41:41,699 please take that and bind that 766 00:41:41,969 --> 00:41:44,399 on a host or local host 767 00:41:44,629 --> 00:41:47,929 on port whatever. 9000, for example. Right. 768 00:41:48,149 --> 00:41:49,500 That's the port I'm choosing. 769 00:41:49,830 --> 00:41:52,110 So this flag here 770 00:41:52,330 --> 00:41:58,679 will actually expose the container to our local network or local host. 771 00:41:58,790 --> 00:41:59,560 So this engine 772 00:41:59,780 --> 00:42:04,669 process running in container will be accessible for us on Port 9000. 773 00:42:04,679 --> 00:42:06,840 So now if I execute this, 774 00:42:06,979 --> 00:42:09,219 let's see that container is running, 775 00:42:09,719 --> 00:42:10,370 and 776 00:42:10,550 --> 00:42:15,590 in the port section we see a different value. So instead of just having 80 777 00:42:15,919 --> 00:42:18,330 we have this port binding information. 778 00:42:18,510 --> 00:42:23,510 So if you forgot which port you chose. Or if you have 10 different containers with 779 00:42:23,659 --> 00:42:24,090 PS, 780 00:42:24,100 --> 00:42:29,270 you can actually see on which port each container is accessible on your local host. 781 00:42:29,350 --> 00:42:31,429 So this will be the port. 782 00:42:31,959 --> 00:42:34,629 So now if I go back to the browser 783 00:42:35,000 --> 00:42:40,489 and instead of local host 80 we're gonna type in local host 9000 784 00:42:41,320 --> 00:42:42,310 and hit. Enter. 785 00:42:42,830 --> 00:42:45,870 There you go. We have the welcome to engine 786 00:42:46,000 --> 00:42:50,129 page, so it means we are actually accessing our application. 787 00:42:50,389 --> 00:42:53,820 And we can see that in the logs as well. Talk los 788 00:42:54,070 --> 00:42:55,330 container ID. 789 00:42:55,919 --> 00:42:59,139 And there you go. This is the log. Uh, that engine 790 00:42:59,459 --> 00:43:04,590 application produced that it got a request from Mac or me 791 00:43:04,770 --> 00:43:05,659 OS machine 792 00:43:05,929 --> 00:43:07,300 Chrome browser. 793 00:43:07,739 --> 00:43:11,060 So we see that our request actually reached the 794 00:43:11,330 --> 00:43:11,540 engine 795 00:43:11,750 --> 00:43:14,229 application running inside the container. 796 00:43:14,350 --> 00:43:21,149 So that's how easy it is to run a service inside container and then access it locally. 797 00:43:21,510 --> 00:43:24,159 Now, as I said, you can choose whatever port you want, 798 00:43:24,310 --> 00:43:28,449 but it's also pretty much a standard to use the same 799 00:43:28,459 --> 00:43:33,439 port on your host machine as the container is using. 800 00:43:33,489 --> 00:43:37,320 So if I was running a MySQL container which started at 801 00:43:37,399 --> 00:43:44,310 Port 3306 I would bind it on local host 3306. 802 00:43:44,659 --> 00:43:46,479 So that's kind of a standard. 803 00:43:50,399 --> 00:43:55,300 Now there is one thing I wanna point out here, which is that Docker run 804 00:43:55,770 --> 00:43:59,610 actually creates a new container every time. 805 00:43:59,620 --> 00:44:03,070 It doesn't reuse the container that we created previously. 806 00:44:03,399 --> 00:44:08,080 Which means since we executed Docker run command a couple of times already, 807 00:44:08,110 --> 00:44:11,239 we should actually have multiple containers on our 808 00:44:11,409 --> 00:44:17,530 laptop. However, if I do Docker P SI only see the running container. 809 00:44:17,540 --> 00:44:20,600 I don't see the ones that I created but stopped. 810 00:44:20,610 --> 00:44:22,870 But those containers actually still exist. 811 00:44:23,040 --> 00:44:25,030 So if I do docker PS 812 00:44:26,260 --> 00:44:27,959 with a fleck 813 00:44:28,189 --> 00:44:28,750 E 814 00:44:29,620 --> 00:44:30,669 and execute 815 00:44:30,810 --> 00:44:33,159 this gives you actually a list of all 816 00:44:33,169 --> 00:44:37,159 containers whether they are running or stopped. 817 00:44:37,469 --> 00:44:39,189 So this is the active container 818 00:44:39,659 --> 00:44:40,770 that is still running 819 00:44:40,889 --> 00:44:42,979 and these ones are the stopped ones. 820 00:44:42,989 --> 00:44:47,000 It even says exited 10 minutes ago, six minutes ago. Whatever. 821 00:44:47,149 --> 00:44:50,780 So we have four containers with different configuration 822 00:44:51,340 --> 00:44:53,639 and previously I showed you Docker stop 823 00:44:53,649 --> 00:44:57,679 command which basically stops an actively running container 824 00:44:57,989 --> 00:44:59,399 so we can stop this one. 825 00:45:00,110 --> 00:45:02,399 And now it will show it as 826 00:45:02,540 --> 00:45:05,620 a stopped container as well exited one second ago, 827 00:45:05,860 --> 00:45:06,639 but the same way. 828 00:45:06,649 --> 00:45:10,560 You can also restart a container that you created before 829 00:45:10,570 --> 00:45:12,989 without having to create a new one with docker Run, 830 00:45:13,000 --> 00:45:13,370 commit. 831 00:45:13,639 --> 00:45:16,040 So for that we have darker start 832 00:45:16,659 --> 00:45:17,340 and 833 00:45:17,510 --> 00:45:20,510 that takes the ID of the container 834 00:45:21,360 --> 00:45:25,010 and start the container again and again. You can start multiple 835 00:45:25,439 --> 00:45:27,530 containers at once if you want, 836 00:45:28,959 --> 00:45:29,770 like this. 837 00:45:31,159 --> 00:45:31,679 And 838 00:45:31,919 --> 00:45:33,610 now you have two containers running. 839 00:45:33,620 --> 00:45:37,820 Now you saw that we use ID of the container in various stocker commands. 840 00:45:37,830 --> 00:45:42,459 So to stop the container to restart it, to check the logs etcetera. 841 00:45:42,889 --> 00:45:46,449 But ID is hard to remember and you will have to look it up all the time. 842 00:45:46,639 --> 00:45:46,889 So 843 00:45:47,000 --> 00:45:47,969 as an alternative, 844 00:45:47,979 --> 00:45:51,179 you can also use container name for all these commands 845 00:45:51,189 --> 00:45:54,689 instead of the ID which gets auto generated by Docker. 846 00:45:54,830 --> 00:45:59,340 But we can actually rewrite that and we can give our containers 847 00:45:59,510 --> 00:46:02,729 a more meaningful names when we create them 848 00:46:04,409 --> 00:46:06,399 so we can stop those two containers 849 00:46:06,850 --> 00:46:08,020 using the ID 850 00:46:08,689 --> 00:46:09,659 or the name 851 00:46:10,540 --> 00:46:11,280 like this. 852 00:46:11,459 --> 00:46:13,899 So these are two different containers, one with ID, 853 00:46:13,909 --> 00:46:15,949 one with name and we're gonna stop both of them. 854 00:46:17,629 --> 00:46:18,370 There you go. 855 00:46:18,570 --> 00:46:23,270 Now when we create a new container, we can actually give it a specific name 856 00:46:23,510 --> 00:46:25,459 and there is another flag for that 857 00:46:25,889 --> 00:46:28,659 which is Dash Dash name. And then we provide 858 00:46:28,919 --> 00:46:32,919 the name that we want to give our container. And let's say this is, um, a 859 00:46:33,270 --> 00:46:36,479 Web app. So that's what we're gonna call our container 860 00:46:37,570 --> 00:46:38,780 and let's execute. 861 00:46:39,379 --> 00:46:39,889 If I do do 862 00:46:40,030 --> 00:46:40,719 RPS 863 00:46:41,100 --> 00:46:45,540 you see that the name is not some auto generated random thing, 864 00:46:45,570 --> 00:46:47,350 but instead our container is called Web. 865 00:46:47,959 --> 00:46:48,969 So now we can do doer 866 00:46:49,209 --> 00:46:50,790 locks and 867 00:46:51,040 --> 00:46:52,840 name of our container 868 00:46:53,419 --> 00:46:54,159 like this. 869 00:46:57,540 --> 00:46:58,909 Now we've learned about Do 870 00:46:59,149 --> 00:47:00,840 Hub, which is actually 871 00:47:01,020 --> 00:47:03,760 what's called a public image registry, 872 00:47:04,050 --> 00:47:04,949 which means 873 00:47:05,070 --> 00:47:09,770 those images that we used are visible and available for public. 874 00:47:10,149 --> 00:47:15,250 But when a company creates their own images of their own applications, 875 00:47:15,360 --> 00:47:17,969 of course they don't want it to be available publicly. 876 00:47:18,229 --> 00:47:22,649 So for that there are what's called private docker registries, 877 00:47:22,659 --> 00:47:23,770 and there are many of them. 878 00:47:23,780 --> 00:47:28,689 Almost all cloud providers have a service for private docker registry, 879 00:47:28,699 --> 00:47:35,080 for example, AWS EECR or elastic container registry service, Google Azure. 880 00:47:35,090 --> 00:47:38,050 They all have their own docker registries. 881 00:47:38,080 --> 00:47:43,239 Nexus, which is a popular artefact storage service, has do registry. 882 00:47:43,250 --> 00:47:46,179 Even Docker Hub has a private dock registry 883 00:47:46,310 --> 00:47:51,679 So on the landing page of Dock Hub, you saw this get started form. 884 00:47:52,000 --> 00:47:55,100 So, basically, if you want to store your private docker images on Doer 885 00:47:55,270 --> 00:47:55,729 Hub, 886 00:47:55,739 --> 00:47:59,770 you can actually create a private registry on Docker Hub or 887 00:47:59,780 --> 00:48:02,929 even create a public registry and upload your images there. 888 00:48:02,939 --> 00:48:04,669 So that's why I actually have an account, 889 00:48:04,679 --> 00:48:07,250 because I have uploaded a couple of images on Do 890 00:48:07,419 --> 00:48:11,860 Hub that my students can download for different courses. 891 00:48:11,879 --> 00:48:15,209 And there is one more concept I want to mention related to registry, 892 00:48:15,219 --> 00:48:17,739 which is something called a repository, 893 00:48:17,949 --> 00:48:19,530 which you also often hear. Do 894 00:48:19,639 --> 00:48:20,370 a repository do 895 00:48:20,479 --> 00:48:25,199 registry? So what is the difference between them? Very simply, explained AWS. 896 00:48:25,209 --> 00:48:30,350 ECR is a registry, So basically, that's a service that provides storage for images. 897 00:48:30,379 --> 00:48:31,830 And inside that registry, 898 00:48:31,840 --> 00:48:36,620 you can have multiple repositories for all your different application images. 899 00:48:36,629 --> 00:48:39,429 So each application gets its own repository, 900 00:48:39,439 --> 00:48:43,179 and in that repository you can store different image versions 901 00:48:43,189 --> 00:48:46,300 or tags of that same application the same way. 902 00:48:46,310 --> 00:48:46,429 Do 903 00:48:46,689 --> 00:48:51,070 Hub is a registry. It's a service for storing images and on do 904 00:48:51,250 --> 00:48:51,500 hub, 905 00:48:51,510 --> 00:48:55,699 you can have your public repositories for storing images that will be 906 00:48:55,709 --> 00:48:57,629 accessible publicly or you can have 907 00:48:57,639 --> 00:49:00,110 private repositories for different applications. 908 00:49:00,129 --> 00:49:04,040 And again, you can have repository dedicated for each application. 909 00:49:04,110 --> 00:49:05,459 So that's a side note there. 910 00:49:05,469 --> 00:49:09,770 If you hear these terms and concepts and you know what is the difference between them 911 00:49:13,060 --> 00:49:13,389 now? 912 00:49:13,399 --> 00:49:15,909 I mentioned that companies would want to create 913 00:49:15,989 --> 00:49:18,760 their own custom images for their applications. 914 00:49:19,050 --> 00:49:20,760 So how does that actually work? 915 00:49:20,770 --> 00:49:25,070 How can I create my own docker image for my application? 916 00:49:25,149 --> 00:49:27,580 And the use case for that is, when I'm 917 00:49:27,780 --> 00:49:31,250 done with development, the application is ready. 918 00:49:31,260 --> 00:49:34,850 It has some features, and we want to release it to the end users. 919 00:49:34,860 --> 00:49:36,790 So we want to run it on a deploy 920 00:49:36,969 --> 00:49:39,719 server and to make the deployment process easier. 921 00:49:39,729 --> 00:49:44,479 Want to deploy our application as a docker container along with the database 922 00:49:44,489 --> 00:49:48,399 and other services that are also going to run as docker containers? 923 00:49:48,489 --> 00:49:51,699 So how can we take our created deployed application 924 00:49:51,709 --> 00:49:55,669 code and package it into a docker image? 925 00:49:55,679 --> 00:50:00,659 For that, we need to create a definition of how to build an image 926 00:50:00,760 --> 00:50:02,459 from our application, 927 00:50:02,780 --> 00:50:07,340 and that definition is written in a file called a docker file. 928 00:50:07,350 --> 00:50:11,379 So that's how it should be called creating a simple docker file is very easy. 929 00:50:11,600 --> 00:50:17,080 And in this part we're gonna take a super simple no JAS application that I prepared. 930 00:50:17,090 --> 00:50:19,610 And we're gonna write a docker file for that 931 00:50:19,620 --> 00:50:22,370 application to create a darker image out of it. 932 00:50:22,530 --> 00:50:24,550 And as I said, it's very easy to do. 933 00:50:24,929 --> 00:50:26,469 So this is the application. 934 00:50:26,679 --> 00:50:29,739 It is extremely simple. I just have one 935 00:50:29,939 --> 00:50:34,479 server dot Js file, which basically just starts the application 936 00:50:34,699 --> 00:50:36,659 on Port 3000. And then 937 00:50:36,959 --> 00:50:38,800 it just says, Welcome 938 00:50:39,100 --> 00:50:40,979 when you access it from the browser 939 00:50:41,300 --> 00:50:45,979 and we have one package adjacent file which contains this dependency 940 00:50:46,010 --> 00:50:49,629 for the express library that we use here to start the application 941 00:50:49,820 --> 00:50:52,270 super lean and simple. 942 00:50:52,419 --> 00:50:54,610 And that's the application from which we're gonna create a 943 00:50:54,620 --> 00:50:57,939 docker image and start it as a docker container. 944 00:50:58,419 --> 00:50:59,770 So let's go ahead and do that. 945 00:51:00,459 --> 00:51:06,090 So, in the root of the application, we're gonna create a new file called Docker File. 946 00:51:06,929 --> 00:51:08,870 So that's the name. And you see that, 947 00:51:09,090 --> 00:51:12,110 um, most code editors actually detect 948 00:51:12,290 --> 00:51:15,340 docker file and we get this docker icon here. 949 00:51:15,350 --> 00:51:17,389 So in this docker file, 950 00:51:17,399 --> 00:51:20,229 we're gonna write a definition of how the 951 00:51:20,239 --> 00:51:22,250 image should be built from this application. 952 00:51:22,370 --> 00:51:24,040 So what does our application need? 953 00:51:24,050 --> 00:51:27,709 It needs a node installed because node should run our application. 954 00:51:27,929 --> 00:51:28,389 Right? 955 00:51:29,020 --> 00:51:31,840 So if I wanted to start this application locally 956 00:51:32,020 --> 00:51:36,689 from my terminal, I would execute node SRC. So the source folder 957 00:51:36,860 --> 00:51:38,379 and server dot Js 958 00:51:38,649 --> 00:51:40,939 command to start the application. 959 00:51:41,080 --> 00:51:44,929 So we need that node command available inside the image. 960 00:51:45,250 --> 00:51:48,550 And that's where the concept of base image comes in. 961 00:51:48,560 --> 00:51:52,030 So each docker image is actually based on this base image, 962 00:51:52,320 --> 00:51:58,149 which is mostly a lightweight Linux operating system image that has 963 00:51:58,270 --> 00:52:03,419 the node, N, PM or whatever tool you need for your application installed on top of it. 964 00:52:03,489 --> 00:52:05,719 So for JavaScript application, you would have 965 00:52:05,949 --> 00:52:07,050 node base image. 966 00:52:07,060 --> 00:52:11,409 If you have Java application, we will use an image that has Java runtime installed 967 00:52:11,899 --> 00:52:15,909 again Linux operating system with Java installed on top of it. 968 00:52:16,550 --> 00:52:19,629 And that's the base image. And we define the base image. 969 00:52:19,639 --> 00:52:22,479 Using a directive in docker file called from. 970 00:52:22,649 --> 00:52:25,889 We're saying build this image from the base image and if 971 00:52:25,899 --> 00:52:29,000 I go back to Docker Hub and search for node, 972 00:52:30,110 --> 00:52:35,979 you will see that we have an image which has node and N PM installed inside 973 00:52:36,489 --> 00:52:39,159 and base images are just like other images. 974 00:52:39,189 --> 00:52:43,879 So basically you can pile and build on top of the images in Docker. 975 00:52:44,020 --> 00:52:46,020 So they're just like any other image that we saw. 976 00:52:46,120 --> 00:52:49,310 And they also have text or image versions. 977 00:52:49,340 --> 00:52:54,149 So we're gonna choose node image and a specific version 978 00:52:54,340 --> 00:52:57,459 and let's actually go for 19 dash L pine. 979 00:53:00,429 --> 00:53:04,479 So that's our base image and our first directive in the docker file. 980 00:53:04,489 --> 00:53:06,560 So again, this will just make sure that 981 00:53:06,860 --> 00:53:09,850 when our node Js application starts in a container, 982 00:53:09,860 --> 00:53:14,689 it will have a node and N PM commands available inside to run our application. 983 00:53:14,870 --> 00:53:17,229 Now, if we start our application with this command, 984 00:53:17,689 --> 00:53:19,780 we will see that we get an error because 985 00:53:19,790 --> 00:53:22,580 we need to first install dependencies of an application. 986 00:53:22,760 --> 00:53:25,459 We just have one dependency, which is press library, 987 00:53:25,510 --> 00:53:29,189 which means we would have to execute N PM install, 988 00:53:29,729 --> 00:53:34,239 which will check the package json file, read all the dependencies, 989 00:53:34,250 --> 00:53:36,379 define inside and install them 990 00:53:36,489 --> 00:53:39,215 locally in node modules folder. 991 00:53:39,225 --> 00:53:43,425 So basically, we're mapping the same things that we would do to run the application. 992 00:53:43,435 --> 00:53:46,264 Locally, we're mapping that inside the container, 993 00:53:46,274 --> 00:53:51,594 so we would have to run N PM install command also inside the container. 994 00:53:51,625 --> 00:53:52,195 So, 995 00:53:52,465 --> 00:53:53,594 as I mentioned before, 996 00:53:53,745 --> 00:53:56,205 most of the dark images are Linux based. 997 00:53:56,215 --> 00:53:59,824 Alpine is a Linux, a light wave Linux operating system distribution. 998 00:54:00,050 --> 00:54:00,669 So 999 00:54:00,810 --> 00:54:01,520 in docker file, 1000 00:54:01,530 --> 00:54:05,030 you can write any Linux commands that you want to execute inside the container. 1001 00:54:05,159 --> 00:54:08,820 And whenever we want to run any command inside the container, 1002 00:54:08,830 --> 00:54:12,469 whether it's a Linux command or node command N PM command whatever, 1003 00:54:12,479 --> 00:54:15,600 we execute it using a run directive. 1004 00:54:15,610 --> 00:54:19,840 So that's another directive, and you see that directives are written in all caps 1005 00:54:20,209 --> 00:54:21,770 and then comes the command. 1006 00:54:21,889 --> 00:54:23,659 So N PM install, 1007 00:54:23,699 --> 00:54:27,840 which will download dependencies inside the container and 1008 00:54:27,850 --> 00:54:31,239 create a node modules folder inside the container 1009 00:54:31,570 --> 00:54:33,439 before the application gets started. 1010 00:54:33,800 --> 00:54:38,699 So again, think of a container as its own isolated environment. It has a simple Linux 1011 00:54:39,040 --> 00:54:40,250 operating system 1012 00:54:40,489 --> 00:54:42,520 with node and N PM installed, 1013 00:54:42,629 --> 00:54:44,540 and we're executing N PM install. 1014 00:54:44,550 --> 00:54:48,600 However, we need application code inside the container as well, right? 1015 00:54:48,919 --> 00:54:50,570 So we need the server Js 1016 00:54:50,689 --> 00:54:51,449 inside, 1017 00:54:51,479 --> 00:54:53,889 and we need the package to Jason because that's what 1018 00:54:53,899 --> 00:54:58,149 N PM command will need to actually read the dependencies. 1019 00:54:58,330 --> 00:55:03,020 And that's another directive where we take the files from 1020 00:55:03,189 --> 00:55:09,149 our local computer and we paste them. Copy them into the container. 1021 00:55:09,760 --> 00:55:11,699 And that's a directive called Copy 1022 00:55:11,800 --> 00:55:14,649 and you can copy individual files like package dot 1023 00:55:14,760 --> 00:55:16,399 json from here 1024 00:55:16,679 --> 00:55:22,530 into the container, and we can say where in container on which location 1025 00:55:22,899 --> 00:55:25,760 in the file system it should be copied to. 1026 00:55:26,100 --> 00:55:27,330 And let's say 1027 00:55:27,780 --> 00:55:31,189 it should be copied into a folder called slash 1028 00:55:31,560 --> 00:55:31,889 app 1029 00:55:32,679 --> 00:55:36,280 inside the container. So this is on our machine, 1030 00:55:36,699 --> 00:55:40,639 right? We have packaged adjacent here. This is inside the container. 1031 00:55:40,649 --> 00:55:41,580 It's a completely 1032 00:55:41,689 --> 00:55:45,600 isolated system from our local environment, 1033 00:55:46,139 --> 00:55:51,770 so we can copy individual files and we can also copy the complete directories. 1034 00:55:51,780 --> 00:55:54,510 So we also need our application code inside, obviously, 1035 00:55:54,520 --> 00:55:57,040 to run the application so we can copy this 1036 00:55:57,050 --> 00:56:01,419 whole source directory so we have multiple files inside. 1037 00:56:01,449 --> 00:56:05,020 We can copy the whole directory into the container again 1038 00:56:05,649 --> 00:56:06,669 in slash 1039 00:56:06,820 --> 00:56:07,129 app 1040 00:56:07,709 --> 00:56:08,479 location 1041 00:56:08,639 --> 00:56:11,719 and the slash at the end is also very important. 1042 00:56:11,729 --> 00:56:17,780 So the docker knows to create this folder if it doesn't exist in the container yet, 1043 00:56:17,899 --> 00:56:18,449 so 1044 00:56:18,649 --> 00:56:23,770 the root of Linux file system add folder inside and then slash. 1045 00:56:23,879 --> 00:56:27,800 So now all the relevant application files like package adjacent and the 1046 00:56:27,810 --> 00:56:32,854 whole source directory are copied into the container on this location. 1047 00:56:33,175 --> 00:56:36,014 The next thing we want to do before we can execute 1048 00:56:36,024 --> 00:56:40,125 N PM install command is to actually change into that directory. 1049 00:56:40,135 --> 00:56:40,554 Right? 1050 00:56:40,564 --> 00:56:41,175 So in Linux, 1051 00:56:41,185 --> 00:56:44,834 we have this CD right to change into a directory 1052 00:56:44,844 --> 00:56:48,415 in order to execute the following commands inside the directory 1053 00:56:48,675 --> 00:56:52,965 in docker file. We have a directive for that called work 1054 00:56:53,195 --> 00:56:54,125 Dear. 1055 00:56:54,540 --> 00:56:55,850 So Working directory, 1056 00:56:56,040 --> 00:56:59,870 which is an equivalent of changing into a directory 1057 00:56:59,879 --> 00:57:03,590 to execute all the following commands in that directory 1058 00:57:03,770 --> 00:57:04,510 so we can 1059 00:57:04,810 --> 00:57:06,260 do slash app here. 1060 00:57:06,500 --> 00:57:09,919 So it sets this path as the default location 1061 00:57:10,110 --> 00:57:13,219 for whatever comes afterwards. OK, 1062 00:57:13,489 --> 00:57:16,750 so we're copying everything into the container. 1063 00:57:16,760 --> 00:57:19,639 Then we are setting the working directory 1064 00:57:19,709 --> 00:57:22,149 or the default directory inside the container. 1065 00:57:22,449 --> 00:57:26,500 And then we're executing N PM install again within the container to 1066 00:57:26,510 --> 00:57:30,459 download all the dependencies that application needs that are defined here. 1067 00:57:30,469 --> 00:57:33,929 And finally we need to run the application, right? 1068 00:57:34,179 --> 00:57:37,510 So after NP install the node command should 1069 00:57:37,520 --> 00:57:41,199 be executed and we learn to execute commands. 1070 00:57:41,209 --> 00:57:43,899 We use the run directive. 1071 00:57:44,070 --> 00:57:48,360 However, if this is the last command in the docker file, 1072 00:57:48,379 --> 00:57:52,445 so something that actually starts the process It so the application inside, 1073 00:57:52,455 --> 00:57:56,235 we have a different directive for that called C MD. 1074 00:57:56,435 --> 00:57:58,804 So that's basically the last command in the 1075 00:57:58,814 --> 00:58:01,405 docker file and that starts the application. 1076 00:58:01,614 --> 00:58:03,875 And the syntax for that is the 1077 00:58:04,024 --> 00:58:04,685 command 1078 00:58:04,925 --> 00:58:05,764 which is node 1079 00:58:06,114 --> 00:58:07,564 and the parameter 1080 00:58:08,300 --> 00:58:10,050 G server dot Js. 1081 00:58:10,260 --> 00:58:12,979 So we copied everything into slash app. 1082 00:58:13,010 --> 00:58:15,860 So we have the server Js inside the APP directory 1083 00:58:15,870 --> 00:58:19,229 and we're starting it or running it using node commit. 1084 00:58:19,719 --> 00:58:20,389 That's it. 1085 00:58:20,399 --> 00:58:24,139 That is the complete docker file which will create 1086 00:58:24,149 --> 00:58:27,659 a docker image for our node Js application, 1087 00:58:27,810 --> 00:58:30,989 which we can then start as a container. 1088 00:58:34,239 --> 00:58:39,629 So now we have the definition in docker file. It's time to actually build the image. 1089 00:58:39,639 --> 00:58:40,739 From this definition. 1090 00:58:41,280 --> 00:58:43,840 I'm gonna clear this up and without changing to the terminal, 1091 00:58:43,850 --> 00:58:45,260 we can actually reuse this one. 1092 00:58:45,429 --> 00:58:50,429 We can execute a docker command to build a darker image, which is super easy. 1093 00:58:50,439 --> 00:58:52,389 We just do docker build. 1094 00:58:52,889 --> 00:58:55,560 Then we have a couple of options that we can provide. 1095 00:58:55,780 --> 00:58:58,100 The first one is the name of the image. 1096 00:58:58,110 --> 00:59:03,699 So just like all those images have names, right like node ready et cetera, 1097 00:59:03,979 --> 00:59:05,129 and the tags 1098 00:59:05,689 --> 00:59:06,780 We can also 1099 00:59:07,020 --> 00:59:09,580 name our image and give it some specific tag. 1100 00:59:09,850 --> 00:59:13,459 And we do that using this dash T option 1101 00:59:13,840 --> 00:59:15,429 and we can call our application node 1102 00:59:15,530 --> 00:59:15,840 app 1103 00:59:16,449 --> 00:59:18,159 Maybe with Dash doesn't matter 1104 00:59:18,469 --> 00:59:19,310 and 1105 00:59:19,689 --> 00:59:22,010 we can give it a specific tag 1106 00:59:22,199 --> 00:59:24,590 like 1.0 for example. 1107 00:59:24,840 --> 00:59:25,469 And 1108 00:59:25,719 --> 00:59:28,810 the last parameter is the location of docker file. 1109 00:59:29,010 --> 00:59:31,899 So we are telling Docker build an image 1110 00:59:32,044 --> 00:59:33,764 with this name with this tag 1111 00:59:33,985 --> 00:59:34,945 from 1112 00:59:35,135 --> 00:59:38,375 the definition in this specific docker file, Right? 1113 00:59:38,574 --> 00:59:41,754 So this is a location of docker file in this case, 1114 00:59:41,764 --> 00:59:45,395 we are in the directory where Docker file is located, 1115 00:59:45,405 --> 00:59:47,594 so it's gonna be the current directory. 1116 00:59:47,774 --> 00:59:51,834 So this dot basically refers to the current folder 1117 00:59:51,945 --> 00:59:53,794 where Docker file is located. 1118 00:59:54,040 --> 00:59:56,070 So now if we execute this 1119 00:59:56,320 --> 00:59:57,229 as you see, doer 1120 00:59:57,479 --> 00:59:59,129 is actually building 1121 00:59:59,439 --> 01:00:02,290 the image from our talker file 1122 01:00:04,320 --> 01:00:08,370 and it looks like it succeeded where it started building the image. 1123 01:00:08,379 --> 01:00:11,939 You see those steps, those directives that we defined here. 1124 01:00:11,949 --> 01:00:17,149 So we have the first one from directive got executed. Then we have the copy 1125 01:00:17,350 --> 01:00:22,629 as the second step. Then we have copy the source folder setting work directory 1126 01:00:22,899 --> 01:00:26,939 and running N PM install and then the last one just started the application. 1127 01:00:27,149 --> 01:00:27,929 So now 1128 01:00:28,459 --> 01:00:30,610 if I do docker images 1129 01:00:30,939 --> 01:00:32,070 in addition to those 1130 01:00:32,500 --> 01:00:34,379 images we downloaded 1131 01:00:34,629 --> 01:00:36,060 previously from Docker Hub, 1132 01:00:36,429 --> 01:00:39,250 we should actually see the image that we just created. 1133 01:00:39,260 --> 01:00:42,110 This is the node app image with tag 1134 01:00:42,449 --> 01:00:43,510 1.0 1135 01:00:43,860 --> 01:00:44,810 and some other information. 1136 01:00:45,379 --> 01:00:46,760 So that's our image. 1137 01:00:46,770 --> 01:00:49,870 And now we can start this image and work with it, 1138 01:00:49,879 --> 01:00:53,989 just like we work with any other image downloaded from Docker Hub. 1139 01:00:54,000 --> 01:00:57,540 So we're gonna go ahead and run a container from this node 1140 01:00:57,610 --> 01:01:01,389 app image and make sure that the application inside is actually working. 1141 01:01:01,629 --> 01:01:02,189 So 1142 01:01:02,429 --> 01:01:03,679 we're gonna do docker run 1143 01:01:04,310 --> 01:01:04,949 node 1144 01:01:05,699 --> 01:01:06,159 app 1145 01:01:06,449 --> 01:01:09,550 image with 1.0 10 1146 01:01:10,219 --> 01:01:13,840 and we're gonna pass in parameter to start in detach 1147 01:01:13,850 --> 01:01:17,600 mode and also we want to expose the port right. 1148 01:01:17,860 --> 01:01:18,659 We want to 1149 01:01:18,830 --> 01:01:22,860 be able to access the application, the node application from local host 1150 01:01:23,139 --> 01:01:23,770 and 1151 01:01:24,000 --> 01:01:27,070 we know that the application inside the container will start 1152 01:01:27,080 --> 01:01:30,419 on Port 3000 because that's what we have defined here. 1153 01:01:30,540 --> 01:01:33,899 So the application itself will be running on Port 3000. 1154 01:01:34,179 --> 01:01:41,209 So that's inside container, and we can bind it to whatever port we want on local host 1155 01:01:41,330 --> 01:01:45,010 and we can do 3000, the same as in the container. 1156 01:01:45,209 --> 01:01:48,679 So this is the host port and this is container Port. 1157 01:01:49,000 --> 01:01:50,520 And now if I execute 1158 01:01:51,159 --> 01:01:52,050 is command 1159 01:01:52,550 --> 01:01:54,409 and do docker PS, 1160 01:01:54,909 --> 01:01:59,610 we should see our node app running on Port 3000 1161 01:01:59,800 --> 01:02:01,449 and now the moment of truth 1162 01:02:01,590 --> 01:02:03,270 going back to the browser 1163 01:02:03,850 --> 01:02:06,709 and opening local host 3000 1164 01:02:07,459 --> 01:02:11,429 There is our welcome to my awesome app 1165 01:02:12,320 --> 01:02:14,610 message from our application. 1166 01:02:14,840 --> 01:02:17,060 And we can even check the logs 1167 01:02:17,370 --> 01:02:19,979 by grabbing the ID of our no 1168 01:02:20,169 --> 01:02:20,530 app 1169 01:02:21,189 --> 01:02:23,770 and doing docker blocks with the ID. 1170 01:02:24,239 --> 01:02:24,800 And 1171 01:02:25,080 --> 01:02:28,270 that's the output of our application 1172 01:02:28,459 --> 01:02:29,649 inside the container. 1173 01:02:30,040 --> 01:02:30,600 So 1174 01:02:30,719 --> 01:02:33,040 that's how easy it is to take your application, 1175 01:02:33,050 --> 01:02:38,540 package it into a docker image using docker file and then run it as a container 1176 01:02:42,189 --> 01:02:46,100 and finally going back to this graphically user interface 1177 01:02:46,110 --> 01:02:49,120 client that Docker desktop actually provides us with. 1178 01:02:49,330 --> 01:02:54,560 Now we are able to see all our containers and images here as well. 1179 01:02:54,590 --> 01:02:57,479 And that's how this U I actually looks like it gives you a pretty good 1180 01:02:57,620 --> 01:02:58,219 overview 1181 01:02:58,350 --> 01:03:00,510 of what containers you have. 1182 01:03:00,520 --> 01:03:05,899 Which ones are currently running, which ones are stopped with their names and so on 1183 01:03:06,060 --> 01:03:09,300 and you even have some controls here to start a 1184 01:03:09,320 --> 01:03:12,969 stopped container like this or even stop it again? 1185 01:03:14,110 --> 01:03:16,669 Restart container, deleted whatever. 1186 01:03:16,870 --> 01:03:19,820 And the same way you have a list of images, 1187 01:03:20,250 --> 01:03:21,840 including our own image, 1188 01:03:21,850 --> 01:03:26,570 and you can also create containers directly from here using some controls. 1189 01:03:26,600 --> 01:03:27,159 So 1190 01:03:27,290 --> 01:03:31,040 I personally prefer the command line interface to interact with Docker. 1191 01:03:31,050 --> 01:03:33,560 But some feel more comfortable using 1192 01:03:33,719 --> 01:03:35,149 the visual U. I 1193 01:03:35,320 --> 01:03:39,379 so whichever you prefer, you can actually choose to work with either. 1194 01:03:42,909 --> 01:03:46,879 Now we've learned a lot of basic building blocks of docker. 1195 01:03:47,010 --> 01:03:47,620 However, 1196 01:03:47,629 --> 01:03:52,169 it's also interesting to see how docker actually fits in in the complete 1197 01:03:52,179 --> 01:03:55,320 software development and deployment process with 1198 01:03:55,330 --> 01:03:58,000 lots of other technologies as well. 1199 01:03:58,050 --> 01:04:02,745 So which steps throughout this whole process is darker relevant. 1200 01:04:02,754 --> 01:04:05,125 So in this final part of the crash course, 1201 01:04:05,135 --> 01:04:10,764 we're going to see darker in big picture view of software development life cycle. 1202 01:04:10,774 --> 01:04:15,554 So let's consider a simplified scenario where you're developing a JAVASCRIPT 1203 01:04:15,564 --> 01:04:19,504 application on your laptop right on your local development environment. 1204 01:04:20,379 --> 01:04:23,610 Your JavaScript application uses a Mongo 1205 01:04:23,929 --> 01:04:28,189 DB database, and instead of installing it on your laptop, 1206 01:04:28,199 --> 01:04:31,570 you download a docker container from the Docker hub. 1207 01:04:32,030 --> 01:04:35,159 So you connect your JavaScript application with the mongo 1208 01:04:35,449 --> 01:04:37,050 DB and you start developing. 1209 01:04:37,649 --> 01:04:39,649 So now let's say you develop the 1210 01:04:39,659 --> 01:04:42,739 application first version of the application locally, 1211 01:04:42,750 --> 01:04:47,000 and now you want to test it or you want to deploy it on the, uh, 1212 01:04:47,010 --> 01:04:49,479 development environment where 1213 01:04:49,639 --> 01:04:52,159 a tester in your team is gonna test it. 1214 01:04:52,560 --> 01:04:56,300 So you commit your JavaScript application in git 1215 01:04:56,310 --> 01:04:58,780 or in some other version control system. 1216 01:04:59,169 --> 01:05:03,120 Uh, that will trigger a continuous integration. 1217 01:05:03,129 --> 01:05:06,139 A Jenkins build, or whatever you have configured 1218 01:05:06,389 --> 01:05:10,949 and Jenkins build will produce artefacts from your application. 1219 01:05:11,139 --> 01:05:15,080 So first, you will build your JavaScript application 1220 01:05:15,280 --> 01:05:16,000 and then 1221 01:05:16,229 --> 01:05:21,550 create a docker image out of that JavaScript artefact. Right? 1222 01:05:21,879 --> 01:05:26,919 So what happens to this docker image? Once it gets created by Jenkins build, 1223 01:05:27,229 --> 01:05:28,489 it gets pushed 1224 01:05:28,669 --> 01:05:31,199 to a private docker repository. 1225 01:05:31,209 --> 01:05:35,000 So usually in a company you would have a private repository because 1226 01:05:35,010 --> 01:05:38,620 you don't want other people to have access to your images. 1227 01:05:38,629 --> 01:05:40,060 So you push it there. 1228 01:05:40,280 --> 01:05:41,169 And now, 1229 01:05:41,479 --> 01:05:48,250 as the next step could be configured on Jenkins or some other scripts or tools, that 1230 01:05:48,520 --> 01:05:49,879 docker image 1231 01:05:50,070 --> 01:05:52,620 has to be deployed on a development server. 1232 01:05:53,033 --> 01:05:58,614 So you have a development server that pulls the image from the private repository, 1233 01:05:58,864 --> 01:06:02,743 your JavaScript application image and then pulls the 1234 01:06:03,114 --> 01:06:07,104 DB that your javascript application depends on from a docker hub. 1235 01:06:07,114 --> 01:06:09,233 And now you have two containers, 1236 01:06:09,243 --> 01:06:13,604 one your custom container and a publicly available Mogo 1237 01:06:13,864 --> 01:06:17,874 DB container running on Dev Server and they talk to each other. 1238 01:06:17,884 --> 01:06:18,897 You have to configure it. 1239 01:06:18,907 --> 01:06:23,758 Of course, they talk and communicate to each other and run as an app. 1240 01:06:23,768 --> 01:06:29,167 So now if a tester, for example, or another developer logs in 1241 01:06:29,327 --> 01:06:32,558 to a dev server, they will be able to test the application. 1242 01:06:32,637 --> 01:06:35,847 So this is a simplified workflow how docker 1243 01:06:35,857 --> 01:06:38,887 will work in a real life development process. 1244 01:06:38,897 --> 01:06:42,708 So in the short time, we actually learn all the basic building blocks, 1245 01:06:42,718 --> 01:06:44,781 the most important parts of docker. 1246 01:06:44,971 --> 01:06:47,931 So you understand what images are, how to start containers, 1247 01:06:48,052 --> 01:06:50,181 how they work and how to access them, 1248 01:06:50,191 --> 01:06:54,781 as well as how to actually create your own docker image and run it as a container. 1249 01:06:55,152 --> 01:06:59,812 But if you want to learn more about docker and practise your skills even more 1250 01:06:59,941 --> 01:07:03,152 like how to connect your application to a docker container, 1251 01:07:03,382 --> 01:07:07,132 learn about darker, compose darker volumes, et cetera. 1252 01:07:07,142 --> 01:07:09,325 You can actually watch my full doer 1253 01:07:09,545 --> 01:07:12,075 tutorial. And if you want to learn, do 1254 01:07:12,716 --> 01:07:13,966 in the context of devs 1255 01:07:14,656 --> 01:07:19,756 and really, really master it with things like private registries using doer 1256 01:07:19,986 --> 01:07:21,575 to run Jenkins, 1257 01:07:21,656 --> 01:07:24,895 integrate docker in CS CD pipelines and 1258 01:07:24,906 --> 01:07:28,236 use it with various other technologies like terraform 1259 01:07:28,466 --> 01:07:29,335 enable, et cetera. 1260 01:07:29,345 --> 01:07:31,825 You can check out our complete devops boot camp 1261 01:07:31,835 --> 01:07:34,496 where you learn all this and much more.