How to (correctly) Create docker from NestJS / NodeJS application | Multi stage build

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you created usual docker with just using uh your node-based image and your code you will end up with having a 1.5 gb docker right but since we use this technique we got only 381 mb exercise to the docker hello everyone you guys are awesome now i can see most of you are engaging with my content i can see you click on the like button i can see you put comments and i can see you subscribing also i hope you're clicking on that bell icon as well it's really great because that is a feedback i'm getting from my content so when i see that it's encouraging me to do more and more so if you're learning something from these videos please be kind enough to click on that thumbs up button and add a comment if you like because that give me really encouragement as well as that's nothing cos for you right it doesn't cost anything so i hope you will do that today we are going to talk about a topic which we didn't discuss before right so i'm going to demonstrate this using sjs but this is exactly uh same for the node js as well right so you can even you're working not just project you can use exactly this as it is without any change right so i know most of you aware and know how to create a docker from a nodejs project and if you google that you can find tons of articles if you come to youtube you can find the youtube videos as well also you can apply that to the nexus as well but here what the difference is we are going to discuss how we can create a docker in the enterprise level the production ready docker using um uh nesj or the not on on top of the sj's or not yes project right so this video is kind of a first video then the second video i will explain you how to do the vulnerability checks and um kind of for adding more uh restriction to the docker but this video i'm going to show you how we can do this with a layered uh structure if you google about this if you search some articles you can see they will ask you to get the node.js base image and put your content and build it and uh deploy it and run it so why we shouldn't do that because when you create a docker if you get the base image and if you adding your contents and the npm packages and everything it will be huge right so you need to allow docker runtime to docker environment in the even doing the rebuild to uh make it easy to keep your docker image is a minimum as much as possible because if you have if you're maintaining a huge containers when you push it when you store in the container registries it takes a lot of spaces as well as it it takes a lot of your bandwidth to push and the pull right so it's not easy so as well as your container is light it is easy to load uh it is easy to pull by your container run time or a kubernetes cluster so whatever uh you're going to use and also it is really easy to store and maintain right so the ah strategy we are going to use here we are going to use a separate image as a base image right so this base image will carrying all your dependencies sometimes because this is a golden image it depends on how you call it but in in the ground in the nutshell what this has is just your packages your npm packages right so now what we're going to do is we take that image and put your updated source code into that image and we are going to build it right so we know when you build a npm not js project or an sjs project the output you will go to this folder especially the sjs project it goes to this folder right so now what you're going to do is we have a separate other image called the production image right the image one is a development image or the build image the image 2 is your production image for the production you don't need the entire full uh node image you can use something like alpine or some some minimal image where you just need just a runtime to run your code right so what we're going to do is we create a other production image using the minimal container minimal base image and then you move your build javascript code into this image you don't need your typescript code if it's an sjs project you don't need your typescript code anymore right because you know end of the day what happens is when you compile your project the nexus runtime which is compiler transcompile your project actually said it's a typescript compiler com transcompile your project into javascript right so now you copy your javascript into your production image and then you're setting some security and permission level access and then you run this so when you do that end of the day what you push into your container registry or your kubernetes or whatever your runtime what you what you do is what you push it just your image with your javascript code right you don't move your development dependencies you don't move your entire node based image or anything so your orchestration uh orchestration engine just get the minimal base image you need when you recompile it when you change something when you want to uh recompile and create a new image that will be super fast because it's a very layered docker and then so therefore it will be very past really fast right so i'm this video i'm not going to go into technical detail about the docker but rather i'm going to show how we are going to do this here i'm going to use a base project right uh our employee graphql service as usual but i uh remove the database dependencies from this project and this just hard coded response from this one right so that is what we are going to do as usual um i'm going to first run the project and see uh whether this is working fine right npm and start there okay good so let's move here localhost 3000 graphql and we get graphql playground and then we get the results right so our project is work fine right so now i'm going to stop the project now if you check this it's not there anymore okay so now what we are going to do is we are going to create these base images first and then add the docker files to our project right so since when i push this uh code into my github since you can follow along i'm going to use maintain all these docker files within my project but keep in mind in the real world in the real scenario you need to maybe create about two projects so uh three projects depend on how you need it ideally one project for your base image other project for your production image uh and other project other this is the usual project right but usually what i do is i get two projects one project for base image and the production image because both are dockers it makes sense and then another one for the nesters right right so let's go and create a first docker file so that i'm going to name docker file dev right so this is my development docker file or else the local file what i'm going to use for uh deploy build this project right so i'm going to mark this this is coming from node 14 let's say 0.17.5 right so let's see what's the version i have yeah 14 17 5 so that's i'm going to use i'm going to tell as base right so if you need a syntax highlighting you can use this as a docker file so then it will do the syntax idealizing for you then you can rename your dev image right so then i'm going to create a work directory so i'm not the create i'm going to consider the usr src app as my work directory okay and then i'm going to uh check what is my npm version here right so since my project is eight project i need at least npm server version because it need uh it is like kind of a recommended in and on if officially recommended even with npm six you can work but uh you have uh share dependencies right so then um this npm seven which automatically can deploy uh download us it is not the shared dependency peer dependencies i was for the name okay right so now uh of course this is npm six i know that so then i'm going to install uh npm uh seven here right npm install i'm going to globally install this i'm going to say npm 7.20 right so you can use x if you want and then i'm going to run npm version command again and now what i'm going to do is i'm going to copy this package file here right package.json file here okay so hear me where because i set this user src app as my work directory so it will copy there so now i'm going to uh run npm i so now what will happens is i just copy my uh package.json file now it will install all those dependencies here right so uh you may notice this in the next case they are using a different package different npm package to delete this already or created this folder so i'm going to install that as well and npm i that's also i'm going to install globally right and it is called r i m r a f okay so now i am going to remove my package.json file because i don't want to keep this this with the image right not a big deal but sometimes it considers a security vulnerability you keeping the email the packages and within the image then again even though you remove it if someone wants you he can go and see within your uh node module directly not a big deal but yeah it made sense because when you have like packages and within your image it's like you're giving a manifesto a key right okay that's fine i hope my uh docker file is fine so now i'm going to do is i'm going to create the base image right so docker build so i'm going to give the name as code labs base image right and okay so i think it's time to uh rename this file as a document dev right so now i'm going to tell my file name is docker file dev and my context path is this so looks like so you can see here it tells the default uh version of the npm is 6.1.6.14.40 right so now it's installing uh 7.2 so here what happens is it's uh download all the packages which is in this package.json file right because this is the file we copied right so install everything so don't worry about these red color things because it's usually usually your warning messages since it is coming through this docker installation it's come as a red don't worry about this those are not errors though just warning it's completed so now let's go and see docker images so now we can see here our codelabs base image is created right you can see that is 1.55 gb right so you can see uh what is the difference i'm explaining here by having a multiple docker images right so now we can use this image to build our project right but this is not a good image to run our project because i mean it's not bad but we don't need this much of resources to run our project right so i'm going to create a new docker file for that right so i'm going to create a new docker file for that it is almost identical to the previous one so i'm going to just type it you don't have to wait then but i will explain then uh how this docker file works i i created the local file so let me to explain uh how this works so here i'm using node 1475 same uh version but i'll find image here you can see the nodes 1417 5 not always image it's a full image so this is alpine image alpine image mean on any image usually is kind of a standard practice alpine image mean it has minimum resources to run the image right so we tag this as a prod and then i'm going to uh install my npm again usually here i'm going to set inver variable call node env this argument co-production right so why this is important because node environment is a good environment variable usually in the node application use right so therefore i'm going to set that as a production in that case within your code if you're born you can see what is the environment if you need to set any other environment variables you can do this here right whatever the environment variable you want to set you can put those into here okay so and because this is the image which is really going to run on your co in the production with your code and then as usual we go to uh app and then we copy the package json this time we install only production right if you see here here we just say npm install right but here we says install but only production why because this is my production image i don't need any of these development dependencies right you can see a lot of development dependencies i don't need those on a reduction so i'm going to say production right and then we are going to remove the package.json file okay so let's uh build this as well right so it's you can use the same command but here this will be doc uh sorry let's rename this as a docker file prod okay so this will be docker file rod and this is also i'm going to use as a prod okay i'm going to use as a plot that's also completed let's go and see now images now you can see we have code left base as well as ghost labs plot right so there's a small uh typing error here like um typo with the packages and i fixed that offline okay now we need to do is we need to use these images and create a docker uh file for our project right this is the our docker okay so if you check here if you check these images one image is this prod image is 381 megabytes and then a development image or a base image is 1.5 gb right now we are going to do is we are going to use these two and create new image for our project for that i am going to use a docker file in a real project this is the only docker file which stay on your project because we don't have to creep your docker file or a production docker file on your project of course you shouldn't and this is just for demonstration purposes in the real project only thing what you need to do is move these to protect their docker files to different project that's it right everything is same so this docker file i'm going to create along with you because i have few things to explain here okay first what what is the docker file we need to this one as a from file you would say it's a production image right because you need the production image to run this but before you put it into production you need to build compile your whatever changes you have done and then that is the code you need to move to the production so therefore the first docker image we need is code labs base right because this is the docker file we need to build our project i'm going to tell here latest if you not tag that it will take the latest anyway as build and i'm going to type this as a bill because this is the docker image i'm going to use as a build here work dir i'm going to set as usual use a src app right so why i do this because that is the uh working directory to the app on the not image so that's why i'm doing that so my code left base coming from main node image now i'm going to run so now first i need to move my code to this image right this this docker for that i'm going to copy everything from my current logo directory to my docker current directory so what is the local current directory user src app right so this will copy everything from my current directory to my docker current directory now i'm going to build my project run npm run build so when you do this what's going to happen it go to this package.json right because the package.json is right there right i copied that and then it's going to run this one that means it's going to run next build okay why why it is going to work because i copied everything here i sent the book directly to the user usr src app and then i copy my package.json so now this is run next to the packages now once everything is done i'm going to get my code labs prod image as prod okay understand what i'm doing here i got my base image i uh move my entire code to the base image and then i build it now i'm going to take my production image front image right this is what it's become the layer right so from there onwards this will be a new image right so this will forget completely but we need to copy whatever the build output to this docker right so here i'm going to set work directory to again usr src app okay so now i'm going to copy this folder from my previous image the build image to the prod image how we can do that i'm going to tell copy from right from where build what is the bill is this tag right the bill from the build usr src app right slash dist okay because we got the uh first image as the base images build and we moved to this directory and we built it here so that means this folder this directory should be inside this usr src app directory so i'm saying hey go to build docker this one and go to usr src app this directory and take everything and copy here as a dist right so now what's going to happen it will copy entire disk directory from my build image to my current image which is the uh the plot image now right now this is important i'm going to tell permission set to node user and the node group recursively of usr src app dist right so now usually docker everything this docker runs as a root user right because i don't want to give root privileges to my directory this directory why because this is my entire executable things right if someone is managed to get into my access to my docker subsecurity vulnerability i don't know uh in my code right if some sort of security vulnerability allows someone to come into my image still i that user will have a known privileges but the user will not have a root privilege so this is a very important step to do okay so now also i'm going to set this running user as a node right and finally if everything is right run node command into this main okay so this is what we are going to do right so here i hope you understand i got the base image i move my code and i build it and then i got my production image and then i set the work directly i copy build files artifact from build docker build image to my plot image and then i set the permission then i said the user and then i'm going to tell it run okay so now i'm going to build this saying docker build employee service right so get the file from here the docker file from the current location so now it will be super fast right because there is no downloads happen anything because everything is already downloaded in these images we have three images right so if you go docker images now you will see we have three images so this is very important if you created usual docker with just using uh your node based image and your code you will end up with having a 1.5 gb talker right but since we use this uh technique we got only 381 mb exercise to the docker this is quite important why as i said the orchestration uh engine you're going to use plan b kubernetes so whatever you're going to use it's very easy to pull the new images when they want to uh spin up on your pods or like you restart whatever you're going to do it will be super easy and the registry also will be the space will be less to store this right so you can see from 1.5 gb we move into uh 381 uh mb right so let's see how we can run this now okay so docker run i'm going to set the port 3000 to the docker 3000 and then i'm going to give the name as employee and docker name is employee service right i'm not going to use the demon mode for now um or detach mode let's go and see now our playground oops now it says get queries missing the reason is usually uh apollo server of course nest also doesn't allow you to run the playground in the production since we use the next build command now it is run on the production mode right so it doesn't allow us to run the playground on the production mode unless you asked to do right you can check this uh easily using uh any graphql client right so let's create a simple um client this post query and the payload is graphql query right so i'm going to use here query get all employees and let's say first name uh designation and city let's run this query uh so we need to give localhost 3000 graphql and you will see i get the responses right though this is doesn't work but it's good right so now we can go and customize our code and see how this works right so if you go to f module we can make and here uh playground is true right playground is true i need to mention something else also here if you had a physical file here let's say something like uh so create your schema file on list the src somewhere as a employee services gquer then you will get an error saying you cannot do that the permission is you don't have a permission because remember we set the permission to note so if you have a physical file to create you need to make sure you set your permission accordingly but this will be good right so sitting like this okay so now um let's stop our uh docker local stop employee and docker remove employee so now see how how fast we can rebuild it right so now we are going to uh rebuild it see it built super fast right it built super fast so now and then let's run this again now our playground should work technically yeah so now playground is working right so playground is working but still okay so the problem is though playground is working we just enable the playground right so it cannot uh do the introspection right so if you do this it's working but you can see here hopefully you don't have a schema why because we didn't enable the uh introspection so what we can do is here you can go here and enable introspection also to true so in that case you will get your uh introspection uh a lot also in the playground right so um i think you learn everything what you need to know how to create correctly the create a docker to unsjs or a nodejs project so in the next video i'm going to not the not the next next video but in upcoming video on upcoming video i'll show you uh two other things because now the problem is it is good to use uh the note this version from from your repository but sometime i don't know whether not doing this they may push new images under the same tank right in that case you may expecting something different but you are getting something different so we can restrict the digest to the exact current docker what you have right so in that case uh you won't get a different docker at later point right that is not much important but it's some good practice to do and also do some security vulnerability check on your image to make sure your images don't image don't have any security vulnerability let's discuss that in the next video okay till that um to make sure you subscribe and also share this video with your friends and i'll see you soon with next video stay safe take care you
Info
Channel: Krish Dinesh
Views: 597
Rating: undefined out of 5
Keywords: nestjs docker compose, nestjs dockerfile production, nestjs dockerfile github, nestjs docker build, nestjs docker deploy, docker nextjs, nestjs docker postgres, nodejs docker microservices, nodejs docker tutorial, nodejs docker multi stage build, node js typescript docker, microservicios nodejs docker, docker and node js, docker node js express, docker for nodejs, nodejs on docker, docker node js react, docker with nodejs, krish, krishantha, codelabs, krish dinesh
Id: YGGSApjwT7E
Channel Id: undefined
Length: 29min 14sec (1754 seconds)
Published: Thu Oct 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.