Day-10/16 Getting Started With Docker Container | Azure DevOps CICD for Azure Container Instances

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone welcome back to my channel my name is PE and this is video number 10 in the series Azure devop 02 hero in this video we be focusing on containers and Azure container instance so without wasting any time further let me jump into the GitHub repository and show you the agenda for today's video all right so I am in my GitHub repository I'm sure you would have the link by now if not you know where to find it so I have scrolled down to the section where it says day 10 managing containers with aure devop and and the first topic will be what is exactly a container and then we'll look into the difference between virtual machines and containers so this will make it more clear like why do we need containers and how it is different from virtual machines then we'll briefly discuss a few challenges with the non containerized application and then we'll look into Docker architecture we'll containerize a sample to-do list web app WR in reactjs and this uh dockerization will be with the help of multi-stage Docker file which is is a production best practice of writing a Docker file and it will have different advantages as well so we'll discuss those benefits as well then we'll look into what exactly is azure container instance and then we'll use Azure devop cicd pipeline end to endend written in yaml and will use that to perform cicd into Azure container so without any further Ado let's start with the video before we start containers let's talk about how a virtual machine is provisioned so you have your physical server that sits somewhere in the data center in case of a public cloud or your personal desktop on top of that you have an operating system that lets you interact with the physical machine such as Windows or Linux then you have your hypervisor which makes this virtualization possible now what exactly is virtualization well it allows you to run multiple operating system instances concurrently on a sing single computer that means you can run Ubuntu pedora sentos all at the same time on top of your Windows machine with the help of virtualization in case of a public Cloud your physical server over here is a shared hardware that is being used by multiple organizations and users at the same time when you request provisioning a virtual machine through a cloud console it lets you provision a guest VM on top of the hypervisor but at the same time other users and organizations are also using the same physical Hardware underneath with a separate guest VM each user install binaries and libraries on top of it and then your application a virtual machine is a software emulation of a physical machine which allows multiple operating system to run on a single physical machine virtual machines are also isolated from each other and and from the host machine which provide security and stability now if we talk about containers it has the same physical server underneath and host operating system on top of that but instead of a hypervisor it has something called as container engine well container engine allows you to run multiple container instances on a single operating system kernel it works the same way as hypervisor but for containers as hyper visor is for running multiple virtual machines on a single operating system container engine allows you to run multiple container instances on a single operating system container has a lot of advantages like they are lightweight alternative to Virtual machines with all the required libraries and binaries packed within containers share the host operating system kernel which makes them more efficient and portable than virtual machine so let's start with looking at the build promotion challenges in the traditional way that means before we introduce container into the picture right so let's say you had a Dev environment where the code was working fine and you know end to endend testing and everything was working smoothly then you use that code to build using some build tool Maven grel or any other tool then you promote the build to the upper environment let's say a test environment it is working fine there as well but as soon as you promote the build to a production environment or a higher environment it start failing there could be some issues at the application Level or at the infrastructure level or at the configuration level and it is hard to identify the root cause of the problem and it takes a lot of time to actually troubleshoot the issue and to fix the issue and this particular phrase we have heard a lot of time if we have worked in the production environment the developer often complains I'm sorry if you are a developer but I had to say this developers often complains that it works on my machine while it's not working in production and this question has always been raised and there is no straightforward answer to this right because in most of the traditional environments production test Dev all environments are built on different infrastructure for Dev environment we might be using two servers without a load balancer for test we might be using three servers with the load balancer for production we might be using you know 20 servers and with a load balancer in front of that or there could be many other infrastructure discrepancies between these environments so this issue often occurs that it works on one environment but the same code does not work in another environment so this is the major problem that Docker or the container solves the container images are immutable that means it packages everything including dependencies libraries application code everything into one single image and you basically ship that image from one environment to another so there is no dependency on the configuration or the environment itself if it is working in one environment there are really less chances that it will fail in the other environment right and this particular problem will not be there so developer will be happy operations will be happy everyone will be happy now let's have a look at the docker architecture so please do not feel overwhelmed with this diagram I'm going to explain it to you everything and it'll be pretty straightforward once you start working with it once we you know create the docker file once we start implementing cicd this whole diagram will be pretty clear to you I'm I'm pretty sure about that so let's start with this so you have basically three major components actually four major components first is a client so this client on the left side if you see this client is nothing but the way you are interacting with the docker so it could be either Docker desktop it could be a Docker CLI or it could be an extension within Visual Studio code anything that is helping you run the docker commands against the docker then we have a Docker host Docker host is the actual environment uh virtual machine or an actual environment where your doer commands are running where the application is hosted and whatever commands you are running like Docker build Push Pull run anything any Docker command that you are running it's basically instructing Docker demon to interact with the docker containers and it will basically make all those changes like it will pull those images it will uh push those images to the repositories it will run the containers for you so everything will be done with the help of Docker demon so this is the actual worker who does all the things all the instructions that is being passed by the docker commands then we have Docker registry so this is nothing but Docker image repository where you store all your images so that you can use it further in multiple environments or you can share it across within organization or if it is a Public Image uh registry then it will be available to everyone so these are the main components so you start with writing a Docker file so if you see over here there is a Docker file so you write the docker file which has stepbystep instructions of what needs to be done and how it needs to be done like what operating system to use as the base image but commands to run what all files dependencies libraries to be copied inside that image right all those files are the set of instructions return in a Docker file in a predefined format and then once the docker file is done you run basically Docker build command to instruct Docker demen to use this file and to build an image image is nothing but packaged version of a container so you create an image with the help of locker file we will see that once once we dockerize an application I will show you how to create that uh Docker image and what is the exact process but for now just understand this I'm trying to explain it that is why I'm repeating myself so um once you have the docker file return you actually build the docker image using the docker file which has all the instructions written and once that image is built you basically store the images locally so by default it stores the images for you locally or you can push the image to a Docker registry this Docker registry could be dockerhub or any artifact registry or in Azure devops we also have artifacts and there could be many other Docker based Registries so once that is done and by the way you push that with the help of Docker push command so Docker build command is to build the image Docker push command is to push the image to the repository then once the image is pushed now you go to your environment where you want to deploy the that image you basically pull that image with the help of a Docker pull command pull the image from the repository from the registry and then you run Docker run command so this Docker run command is actually create the docker container from the image so Docker container is a running instance of a container so Docker file then you build it then you push the image to a repository then you pull the image to the environment then you actually run the docker run command to build the container which is a running instance of the docker image so this is the overall workflow of a Docker container so in the next step I will show you how we can dockerize a file from script okay so this is the sample to-do application that I will be dockerizing it first and then I'll be using the same in the cicd pipeline so I will also share this link in the description and like in the read me file as well in the day 10 folder so you'll get it from there so first what I'll do is I'll create a new project in my Azure devops so I'll go ahead click on new project give it a name day 10 containers okay let's keep it private and I'll keep everything as default hit create okay the project is created now I'll go to my repos and I will go here where it says import a repository and I'll click import and I'll enter the GitHub repository URL over here so let me copy the URL from this repository copy and then going to paste it over here then hit import because this is a public repository it won't ask you for credentials so it will take a couple of seconds and then the repository will be imported over here okay it says it's imported so let me go over here and yeah it is there so now we'll create the docker file so let me just do it right over here click new and then file and give it a name by default Docker file is with this naming convention D capital and then F small without any space without any special character in between create Now to create a Docker file we need to understand the manual steps of building and compiling the source code from the scratch because Docker file is nothing but we are actually converting the manual steps of compiling and building the code and packaging it with the help of Docker containers so we need to know the manual steps before that right so let me just uh start writing the docker file because let's assume that I know uh what all steps are needed to actually build this particular application so this application is written in reactjs and I know I need package.json package log. Json file within the directory I need the source code I need the dependencies using npm and all those things so I have all the steps with me so I'm going to write all the steps I'm going to explain it to you uh what are we doing and once that is done I'll explain it to you why are we doing it so I'll start writing with the basics so first is we'll start with from let me uh zoom in a little bit I hope this is visible now right so I'll start with from keyword and basically here we enter the base image of the operating system that we need to use to build this particular Docker image so let's start with the node image I'm going to use node 18 and then I will use Alpine as the operating system now Alpine if you have not heard this name before Alpine is the lightweight Linux based operating system and it does not take a lot of memory it does not uh take a lot of space and your docker file size will be also less and startup time will also be good right so that's why most of the application are compatible with it and for most of the application we uses this particular OS distribut now uh in this Docker file we'll be using a concept of multi-stage file and I will explain it to you but for now let's just consider um this particular stage as installer so this is the first stage and we'll use a second stage as well later in this but for now the first stage in this first line we are just using a base image which is based on Alpine operating system and it has no datin already installed so that's what we are using and let's um go to the next step now we need to initialize a working directory so we write this keyword work directory and Slash the name of the directory right so this is nothing but changing the directory inside the container the container will have this directory SL app so we are just doing CD SL app at this time right let's go to the next line and now the next part is we'll copy uh the package.json file right so let's do this copy package.json and we'll copy it to the current directory right so this command will copy the package.json file in the current working directory which is/ app so let's go down and now now uh we'll actually install the dependencies with the help of npm install right so if you are looking at the commands from is to use the base image work directory is to change the directory copy is to copy the files it is self-explanatory and then we have run to execute the command or to run the command so there we are using npm install now let's go down now we'll copy after the npm install is done we'll copy all the files like all the files generated by npm install all the dependencies and libraries we are using this copy dot dot that means we are copying everything to the working D now we are doing run npm run build to actually build the application source code I made a mistake so this is how it should be run npm build and then we'll use the next stage so the next stage we'll use another image which is engine X this is what we need to run the application so we'll call from enginex and the latest image and then we'll use we'll call it a deployer stage now why we are doing this I will explain you just in a bit but let me just complete it first so we'll use this image and then we'll use copy from installer we'll copy it from the installer stage and then what we are copying we are copying everything inside the app build user share I'm sure uh this will be enginex HTML this particular directory right so everything will be copied in this particular directory now why have we used this because you know when we ran npm install command it generated some files in fact it generated a lot of files after that which we don't need as part of the docker image right so this will unnecessarily occupy a lot of space and this will make our container slow and the docker image size will be huge so that is why we are dividing this into multiple stage so that when we are using the next stage which is installer stage we are directly copying the files that we need as part of the build and we are excluding all the irrelevant files right so that's why we are copying directly from the stage and into the enginex working directory okay so this is this completes our Docker file let me commit the changes and then we try to build this file maybe we'll build this as part of cicd pipeline but this is the multi-stage docker file that we have built and I have already explained to you each and every steps that you need it has some additional commands that we could use maybe we'll use that in the later videos so it has uh it has entry point it has a few other commands that we can use but um these are the main commands right so let me hit commit okay so if there are any errors in this file we'll we'll fix it when we run the cicd pipeline so which is what I'm going to do next now let's quickly see how container instances work and then we will jump into the demo your development team packages your application along with binaries libraries and configuration into a container image these images are then uploaded or pushed to a container repository it could be a private repository such as Azure container instances or a public repository such as Docker Hub then using the Azure portal you deploy these images from the repository to Azure container instances which is a platform as a service that means all the admin work such as upgrading patching and infrastructure management will be done by Azure for you and you just have to worry about your code and containers Azure container instances allow you to upload your containers and then the service will run the containers for you without you worrying about the underly infrastructure okay so now that we have dockerized the file let me once again verify it actually I made a a few mistakes over here so let me just quickly edit it so it should be package star. Json so that it'll copy the log file as well and we don't need this and over here as well it should be the source directory which is app build so when you run npm run build command inside for a reactjs project so it will create this particular directory and store the compiled code in this directory right so this is what we are copying to to the engx directory to serve it right so now it looks good um let me just commit this file and after that we'll create the Azure devop CI pipeline but before that as a prerequisite we'll create an Azure container registry so if you go over here you search for ACR or Azure container registry in the Azure portal if I was not clear earlier so yeah does not show anything with ACR so let me search container Registries okay so here it is okay now hit create okay subscription let me use the default subscription and create a new Resource Group dat and demo hit okay and give this registry a unique name it has to be unique not just for your subscription but it has to be unique globally right because you will be accessing your registry with this fully qualified domain name with the suffix as aurec doii so it has to be unique so um let me give this a name let me call it date demo okay I hope no one else is using it and I guess this is good now use the location that is closest to you fine pricing plan let me use use the basic one meet will upgrade it to the standard plan right then um let's go next networking it says private access is only available in Premium plan so I will be using the public access for now because I'm using the basic plan but this is what we use in most of the cases the private access so that it is not accessible outside your subscription or your inv encryption tags that's okay now let's review and create okay okay registry is almost created it will take maybe a couple of more seconds and once it is created we'll have to enable a few more settings and we have to gather the access keys and then we'll uh move on okay so it's created now let's go to the resource and over here on the settings where it says access keys go over here and you enable the admin user right it will generate the username and password for the admin user which will be using in the Azure devops pipeline so this is the username this is the password I'm just um I'm just going to copy it from here or maybe I'll copy it later on I'll just keep this page as open so this is a username and this is a registry name the full registry name and this is the registry name date and demo so now that our registry is created let's go back and go to pipelines I will create a new pipeline okay and asure repos G I'm doing this fast forward because I have explained this multiple times so I'm not just repeating it now so select the repository and this time like most of the times we have started with the starter pipeline or existing pipeline or we have used the template multi-stage template but for now we'll just use this one uh Docker build and push image to an Azure container registry the second option so this is what we're going to use okay on the right side it will ask you to select the subscription so that it will create the service connection for you so I'm going to select this subscription hit continue and it might ask me to log in so let me just log in with my credentials the prints as the biometric Authentication okay and I the password as well okay it has authenticated successfully and now it should show me the container registry that I have created in this particular subscription so date and demo which is just recreated and then you give this image a name so let me call it too app okay and a Docker file will be there in the source directory and the name is this this is the default name if you have used some other name so make sure you update this over here so this looks good now click on validate and configure on the bottom right side and it will generate a template yaml for you and we'll make some changes in that yl afterward so I'll just let it generate all right so the first few things are basic like trigger on the main branch repo itself then we have this service connection that was created for us with the help of uh you know the Azure subscription image repository is this container registry is this these are all the variables that we can reuse in the later section of the pipeline we have Docker file path and the tag right so first stage is build and push right so before that actually this is not the correct command that it generated because we need some extra steps so let me go over here here which says steps and over here we'll write a new step with the help of show assistant will create Azure CLI command for easy login because we have to first authenticate with the Azure container registry so let's search for Azure CLI and this is the one click on that now select the service connection click on authorize okay it will create the service connection for you okay so now select the script type as shell script part let's use inline script and let's enter the script over here let me just zoom in a little bit so I'll enter the script aacr login hyphen hyphen name and then name of the container registry so we have already used the environment variable so I'm going to use this brackets and let me copy the environment variable from here okay over here so it was container registry I suppose this one so copy it and I'll paste it over here right so this is our a CLI login command Okay so let's hit add there are some indentation issues I'm going to cut it from here and I guess I accidentally uh deleted the variable from here so it was container registry this one okay so I need to paste it as part of the first step over here okay I'm going to add it okay now this task has been add add it this will do the a login to the Azure container registry that we have created now we have to build the image so to build the image the the command is there build and push it has the repository name as well which is image repository too app and then the docker file path this is good and then it has the container registry service connection details as well and the tag as well okay so tag is nothing but the build ID I guess this is what it is let me just go up and yeah tag is build. build ID so this is also good now we have created two steps already one is we have authenticated ourself to the ACR and then we have build the docker image now the next step is to create the Azure container instance and deploy the image into that to run as a container so I'll create a new task for a CLI again again to actually provision the container instance and to deploy the container on that so just get this and let me select the service connection that we have created in the previous tab and this time also we'll use a shell script and the inline script now let me just paste the inline script over here so the inline script would be ay container create and then we'll pass some parameters such as the name name was dat app let's call it that and then the resource Group name with hyphen G so it was date and demo I believe that was it and then um add the image name we can add the environment variable as well so let me choose the image name because we'll pick the it has to be the complete path container name it should be um dollar sign and then inside the brackets which is the container registry name which is dat and demo. asure cr. and then the name of the app which is too app um this one with the repository name so let me copy the repository variable as well and then the tag name tag name was we al already had the tag so let me do this I'm sure it will be visible now but if it is not so the command will be there in the read me repository now I have added the image name now the next is We'll add a few more details such as registry login server registry login username so let me copy the commands and I'll make the changes accordingly right so registry login server date and demo this is fine registry login username I'll copy it from here was date and demo this one is the same now I'll copy the password as well from here and I'll replace the password all right and the DNS name label this would be fully qualified domain name on which our app will be accessible so this is what we have used and I believe this is completed now so let me just click on ADD so that it will generate the yaml from it for that I have to put my cursor on the line where I want the yaml to be generated so it has to be after this stage so let's click add and it has added the task let me verify it once again so that there shouldn't be any indentation issues or anything let me move this a little back registry username registry password we'll try to run it if there are any uh changes that needs to be done uh we'll do that we hit any error okay so there are few other variables that you can can replace such as container registry this one so let me just do that all right and uh this username can also be changed but it's fine for now so this is not really a good practice to keep your registry password or any password at all even though it is in encrypted or encoded format it's not a good practice to keep it within the source code within yl or within the pipeline so we basically use Azure keyword for those purpose but we have not covered keyword yet we'll cover that in the later video so that is why I have kept it right like this for now so our pipeline is completed right we have done the a login to the ACR we did build and push so that the docker container image will be buil and push to the Azure container registry which we have created beforehand and then we'll create an azure container instance by pulling the image from the registry with the help of registry credentials um let's hit save and run and let's see if we hit any error or if it gets successful okay now let's go to the build it says pipeline it permission so let me give it the permission to execute the build okay by the way this step you can run in your self hosted agent as well we already have covered self hosted agent in the previous video I forgot to use that for this video that's why I'm using the Microsoft hosted agent but I would suggest uh if you have completed the previous video I would suggest to you know use that for this video as well okay while it is doing its work I'm just going to pause the recording for a few seconds and then we'll come back and see before that it failed so let me see why it is failing on the build command so it says Docker file pass error copy require at least two arguments but only one was provided okay so there is an issue at this particular step in the docker file uh line five where we are doing the copy so let's go ahead and quickly have a look at the repo Docker file uh five copy dot dot I missed a space space in between that so let me space so this is Source this is destination then hit commit okay now it should trigger the pipeline again let's go to the pipeline so we did the checkout okay now it is building the image it has proceeded further after step five I guess so let's see if it is able to build the image successfully now it is running npm install which will take few seconds so I'm going to pause the recording now okay now it has successfully build the image so let's see U these are all the steps it performed um you can have a look at the logs to see what all things it has done to build the image once that is done it actually pushed the image and added a build tag as well to the repository okay so my image should be pushed to the ACR now and it has completed all the steps but it failed at the next step which is to create the ACI now let's see what error is throwing it is saying that the following argument are required which is Resource Group I remember remember I added Resource Group in the command itself but I guess there is some mistake with the command so let me open the repo in the new tab all right and let's go to Azure pipelines and here's a command which says a container create name then hyph G which is the resource Group name so let me see if this is the exact Resource Group name that we have created um Resource Group is date and hyphen demo yes this is the correct one okay let me quickly check the command so AZ container create CLI okay go down a container create hyen hyphen no this is the container group so ay container create hyper Hyer Resource Group and then Resource Group name then the name of the container name of the image and DNS label and the few other things so instead of iph G let Me replace it with minus iph I Resource Group um I guess this has been changed recently I'm not really sure but let me try doing that so instead of hyph G uh let's use this and let me check the error once again if if there was anything else so in this uh there was this error and then it shows basically the command that you can use and then it is also saying hyphen hyph name command not found um this shouldn't be the issue ay container create yeah iPhone iPhone name should be good so submit the changes and let me trigger it again okay there was actually a silly mistake there was some extra spaces at the end of the command that's why it was not able to recognize hyphen G or Resource Group and the name parameter so I have removed that and it is working fine now and it is showing the command or this particular task as well as completed and I don't see any error so let me go to my Azure portal and see if it actually created the container instance so I'll search for ACI container instances and I do see my date and app over here which is in running state so click over that and let's go to container ERS I see one container running and you can check the logs from this particular tab okay and there are some because we have not done anything this is just some on you know some verbos messages you can also do SSH into the container with the help of this Command right and all the events will be generated like it pulled the image it started pulling the image then it pulled the image then it started the container so all the workflow of the docker um you can see it over here so now let's go to overview and here is the fqdn the fully qualified domain name ACI demo P11 and then your region and then aure container so it's a long name just copy it or you can copy the public IP address open in a new tab it is showing the enginex page but it is not showing the actual application I guess there is still some mistake in this so let me go back go to the container and we can actually log into the Container so let's do that let's connect and connect from here as well okay I am inside the sandbox which is a part of the container so let me LS and we actually we have to look for the file um the build file so it should be inside the app directory this is the work directory that we have initialized so let's go inside that let's go inside build user here engine X and then HTML I'm not sure if this is the app created by our application so let let me just uh C into index yeah this is a react app but I'm not sure why it is not showing over there maybe taking some time to deploy the app let me hit Refresh on this page so this looks okay but um again okay so let me go to app build user share enginex tml so our files are here which is correct oh wait wait wait wait I guess I know the issue is so it shouldn't be SL app SLU user share it should be only user share HTM enginex HTML so it should be inside user share engine X HTML so now it is serving the default enginex page now if you remember the step in which we have made these changes like in which Step we had copied the files from one directory to this particular directory yes if you have guessed Docker file you are correct so we made these changes in the docker file so let me go to my Docker file hit edit so I added this path by mistake I'll just remove this it should be user share engine X HTML I just commit the changes and when I'll unpause the video after the build is completed after the pipeline is successfully deployed you should see the changes in the web browser itself so I'm going to pause the video now and I'll come back again okay so the pipeline has been completed once again um I'm sure this will work this time because we have made the necessary changes to it so let me go back to my app I'll copy the fqdn and I'll open this in a new browser so yes finally our to-do app is now listening on Port 80 of the Azure container instance and it is running as a container so if you make any changes like let's say add some item and PR two I can delete the items I can edit this and basically this is a fully functioning app and you can make the changes once you make the changes in the source code it will build the docker container once again and then it will do all the steps and then it will push the image to the ACR as your container repository with the new tag which is the build ID and you can basically deploy this image in multiple environments and yeah that's that's all about it right thank you so much for watching the video I hope you have learned something out of it and you would have enjoyed the video so if you did gives it a thumbs up share with with your friends family and colleagues and if you're new here don't forget to subscribe the channel I will see you soon with the next video till then take care and happy learning by the way if you have any questions any comments any queries you know how to reach out to me there is a comment section below and I also have a Discord server where everyone is there to help you out so do not hesitate to ask for help we are here to help you so thank you so much and I will see you soon
Info
Channel: Tech Tutorials with Piyush
Views: 6,298
Rating: undefined out of 5
Keywords: azure container instances docker, azure container registry devops, azure container instances, aci, docker tutorial, azure container registry, docker containers, docker multistage build, dockerize react app, azure devops tutorial for beginners, azure devops ci cd, docker, azure container instance, azure devops, azure devops pipeline, azure devops containers, azure devops concepts, azure devops zero to hero, azure devops full course, azure devops full course for beginners
Id: 6DJfhwG3DGQ
Channel Id: undefined
Length: 44min 56sec (2696 seconds)
Published: Mon Jan 01 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.