ECS-W2: Building and Running Windows Apps in Docker Containers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how you doing my name is elton and welcome to elton's container show so this episode we're continuing the theme for the month which is windows containers so if you saw last week's episode it was all about the basics of how windows containers work and how you need to be running on a windows operating system to run your windows images for windows containers and this we're going to dig a little bit deeper into how you package up your windows applications so you can run them on windows server or windows 10 in windows container mode so we're going to cover some of the basics of kind of how you can take a windows base image so microsoft produce all these windows server images that you can use as the basis of your applications how you can package your apps into a docker image using a format you've already got so you can take something like an msi or a web deploy zip file and inside your docker file you can package those things up on top of the windows based images to run your own applications so we'll see how to do that it's really simple but it's not ideal and the next evolution of that is packaging it from source code so using docker multi-stage builds to package up your source code compile it using the tools the ms build tools which again you get from a docker image that microsoft provide and then packaging up the compiled output into your final image so if you're new to the series the way this works is i get a very short um talking head where i introduce the topics i'm doing four episodes a week um which cover the same theme so this theme for this month is windows containers next month we're moving on to orchestration the month after that something else or something else all the information is up on github and you can get it to um the website which is elton's.show last sort of 30 45 minutes very informal no script no rehearsal um but all the all the demos that i walk through they're all in a markdown file on github so if you want to follow this thing for yourself but list all the prerequisites you can get up and running really quickly if you want to see how this stuff works for yourself okay so i'm going to switch to this camera and switch to my green screen so while i pull that down i'm gonna run my really short boring advert and after that i'll see you in about 20 seconds on that camera over there you're watching elton's container show with your host that's me elton stokeman while i'm fiddling with my green screen you might want to bookmark this page elton.show which is where you'll find all the details of all the episodes i go into quite a lot of depth in these shows so if you want to primer around these technologies i can recommend my books learn docker in a month of lunches and learn kubernetes in a month of lunches and if you just want to see what i'm up to then you can check out my blog blog.sixside.com and now back to the show okay and here i am so um all the all the links and everything that you need are up on github you can follow this stuff along for yourself uh what i'm looking at today is ecs w2 so that's the name of the episode i'm gonna be looking exclusively at windows containers um but of course later on in the series we'll be doing other themes and we'll be covering linux containers too okay we're gonna start with some kind of pure windows applications so um there are a whole bunch of links here for things to follow up if you find today's topics interesting but the thing i'm gonna be looking at mainly is starting with uh the microsoft based images so on docker hub you'll find images for all the linux distributions like ubuntu and alpine debian all those things have their own official images on docker hub and the official images just means that they're curated by the docker team and usually the product team work on those uh the dockerfiles are vetted for best practices they're published every month all that sort of stuff the microsoft images aren't on docker hub they have their own container registry called mci and that's where they host all of their images but you still discover them through docker hub so docker hub is still the discovery mechanism because mci doesn't have a ui so if you follow this here let's open this link here this is for windows server core so there are two windows based images windows server core is effectively windows servers windows server 2019 without any of the ui elements so if you install windows server you get the option to install the what they call server core which is without the gui and that's effectively what you've got in the windows container image not everything because not all the windows features are available but pretty much everything you need to run a containerized workload is in there what you'll see is if you scroll down and have a look at this stuff there's a whole bunch of different tags which all represent different versions of the image and with windows server there's a there's a long term support channel which is which is good for five years worth of support and then there are these six monthly updates which are these image names like 1909 1903. those those are the semi-annual channels the sac channel they're not supported long-term but they're a great way to find out the features that are coming down the line um it's been really useful as containers have evolved since windows server 2016 to get new features quickly and work with them in your containers so you'll find all the details there but if you look right at the top here the docker pull command if my head isn't in the way let's go ahead and zoom in here the docker pull command tells you to get them from mcr.microsoft.com which is the microsoft container registry so if you're if you're new to docker um then the registry is just a place where you go and download your images so you can run your apps in containers registries are all have the same apis as a standard api docker hub is the most popular registry but you can run your own and you probably will in your organization to host your own images all the clients provide a managed service for their registries and microsoft have their own for their container images so that's windows server core which is kind of backwards compatible since kind of forever so you can take your windows server 2003 application pull the binaries off a vm pull them off a server package them up inside a docker file and run them on top of windows server 2019 with the windows server core image you can literally do that because i've done that before and when i was working with docker and the alternative image is called nano server which is a much smaller um windows compatible operating system it's not the full windows server api so you can't run things like um 32-bit applications in there you can only run 64-bit it doesn't support the full windows api so you can't run dot-net framework applications but you can run a lot of cross-platform apps in there so net core go java you can run those on nano server so the basic decision when you're when you're about to package up your windows application is can i run it on nano server if so do because it's a much much smaller operating system much leaner to build those container images and work with them much smaller attack surface when you're running your app in a container and if you can't they're running windows server core which gives you that kind of full backwards compatibility and then nanoserver has the same sort of semi-annual channel release so if i scroll down here we'll see these um we'll see the same the same container image tag so 2004 1903 1909 they're the last few of six monthly releases okay cool and then microsoft used those images as the basis for their own images so they package sql server and they package the document framework and they package um.net core all on top of one of those images and those are the base image that you have to use okay so let's have a look at how this works so i've already downloaded a whole bunch of windows server core images because that's what i work with all the time or a lot of the time if i list out the images that i've got locally so i'm just doing a docker image list to show what i've got and then i'm filtering to look at the um the windows server core image with with any tag and we'll see here i've got the lts 2019 image tag that's the long term support channel that's your five-year support that's the current version of windows server and then because i also work with the semi-annual channel i've got all these pool as well you'll see that these are very big images if you're used to the linux world so compared to say um compared to alpine linux which is about four megabytes the windows server core long-term support branch is five gigabytes now that's because it has that full level of backwards compatibility so you know the price you pay for being able to take your 12 year old application and run it in a container with no changes is the part that's gonna be bundled on top of a large image but remember that windows image docker images are layered the image layers are cached and they're shared between images so so the image format the image structure works exactly the same for windows containers as with linux containers so that windows server core image although it's very big you're going to use that from multiple application images so you really need to download one five gigabyte image and then your layers for each of your applications would just be a few hundred megabytes on top of that okay and they have they have been driving to make those a lot smaller so what you'll see here also is that the most recent one which is the 2004 um 20.04 release is four gigabytes so they've trimmed a whole gigabyte off that so when the very first um windows container images came out the first windows server core images from 2016 uh they were more like eight gigabytes and gradually the team will work really hard to bring those image sizes down to make them more manageable to work with um but not lose that backwards compatibility so they've cut out features that people aren't typically using when they're running things in containers okay but when i run this i get a pretty much a full windows server core experience so if you install windows server core without the gui and then you and then you go and connect and do a remote desktop into that into that that windows server you'll get this effectively you just get the command line interface there is no ui so when you remote desktop and you'll drop into a terminal when i'm inside here i'm inside windows server core it's got i come into the ordinary windows command line so this gives me you know the command line from since this is the beginning of time but it also has powershell so i can run powershell and because it has powershell i can use powershell commands in my docker file to do whatever i need to install you know bits of bits of new windows features or run command lists to set up my application if i run get windows feature here i'm still inside the container i've got all that kind of powershell stuff available to me and it shows me there's a whole bunch of stuff that's already configured so inside here i've already got windows powershell i've got various i've got the wow 64 support if you can see that down there so that gives me 32-bit and 42-bit and 64-bit applications if i roll all the way up here so things like message queueing aren't installed but you can get images that that are configured without you can configure it yourself using your docker file and if i keep going way up here we'll see i've got the.net framework installed so i've got dotnet framework 4.7 but i don't have 3.5 so the windows server core image tends to have the kind of most recently supported.net framework there is also a domain framework 4.8 that's in a separate image and another image that's dotnet framework 3.5 so microsoft maintain all of those images on mcr and when there's a windows update they get rolled into those those docker images too so as long as you're pulling the latest images when you build yours you're always building on top of the most recent patches the most recent releases okay so let's leave this container so i'm going to exit that will take me back to the command line and exit again back to my host okay so nano server is different because it doesn't have that full thing it doesn't also doesn't have powershell so again i've pulled a whole bunch of nano server images and if i look at these uh the ones i've got most recently are um nano server 2004 is 200 megabytes and 1809 was 251 megabytes so they're much smaller they're much much smaller images they're much easier to work with so that's important because when you think about i'm doing my monthly downloads um the download of the new nano server image might be a single layer that's that's only 100 megabytes of updates but the download of the new windows server core image might be a couple of layers that are 700 megabytes or a gigabyte so that's that's why that's important because um although you'll be sharing that image across all of your applications you'll still do those monthly updates you're still gonna be having big big downloads and when you commission like a brand new server if you need to scale up your cluster in production um it'll start with no images so when you first scale up your cluster and you download some images to run your applications it will download that full kind of it's like two gigabytes it's compressed but it'll download that two gigabytes it'll have to decompress it to five gigabytes so that's the cost you pay for working with the windows server core but i can do the same sort of thing so when i'm working in nano server i can run my container from the latest version of nano server and this will drop me into windows command line there is no powershell the early versions of windows server and i'm going back like the nano server container images going back sort of five years they did have powershell the cross-platform powershell but it was just too big you just added too much to the to the container image so as part of that slimming down process and that's all been removed and you don't really need like a complex shell inside your container image because you can take care of that in your docker file anything you need to do you can do in a multi-stage docker file and then just copy the output into your into your final image so i've got the command line here so this is where you're going to exercise all the things you learned about if if you're like me when you're using windows 3.1 at school these are the same commands you're going to use so i can use dirt to see what's going on if i want to see the contents of that text file i can use type to see the contents of that and then when i'm done we're going down a nostalgia trip i can just exit that back out so main things you need to kind of take away from that windows server core gives you pretty much everything but it adds a bit of the maintenance overhead dealing with those big images nano server much lighter to deal with doesn't run every application so you'll need to find the right base image for what you want to use okay so the advantage of those windows server core images is that because they've got powershell and all that sort of stuff inside your dockerfile and you can kind of do anything that you need to do you can package up any windows application provided you can do an unattended install so you know if you're trying to install an application that pops up a window and asks you you know where you want to install it which folder to install it to you can't really do that in a container unless your install artifact lets you kind of have an unattended mode of quiet mode and you can get that with msi so i'm going to spin it over to another window here and the links that i've got um they're all in the same well i don't have to close this down they're all in this all these links here will take you to the github repo but i'm going to open another code window because it's a bit easier to use so let's open this so this is my docker file that i'm going to build i'm not going to upgrade close that down so this is a genuine docker file i can use this to build a windows application that um that is using an msi so imagine i've already packaged my msi with some other processor ci processor i've done it with visual studio or whatever i've got my msi out and that's what i've got here so inside this copy instruction i'm copying the the msi the windows installer that i've already built into my container image the front line is using uh my own version of a microsoft image and all the all that i do is i um i've got my own docker file that starts from the microsoft asp.net 4.8 image so i'm starting from the mcr image and that's the kind of approach we have a golden image so you own your own kind of name spaces for those images you can control when you do the updates all that sort of stuff i switched the shell to powershell so i can run powershell commands and this is where the the real work happens let's clear this down so i've got a single run command in here that's going to start a process the process is msi exec which is how you do an install of an msi file uh without double clicking on it so this is the command line to install it and the arguments are slash i to install the name of the installer file which is the file just copied in and the quiet and the no restart tells the installer do it unattended don't don't pop up any windows don't do an automatic restart even if you think you need to just go and install the msi and do whatever the msi tells you to do but the important bits are at the end here so i'm running this inside a powershell inside a powershell session and i'm saying no new window and wait so it won't pop up a new window for something else to happen in the background it's going to wait and run this msr exec in the foreground so the way the msi installer works they kind of spin up this process that goes somewhere else here and then they look like they finished even though they haven't you need these flags to make sure your msi is fully installed so actually you can this is the pattern that you use to install any msi inside that inside a windows docker file if that's the artifact that you've got and then this just this just deploys it exactly as it was if you were to deploy it manually using using the command line okay so we can look at how that works so i've got this down here if you're interested in doing this yourself then where are we here um you'll find the links to all this stuff up here in this is the repo 6i slash dockerfor.net repo um there's a whole bunch of source code there for a udemy course that i'm working on and that's that's what i'm using for these demos here so i'm going to switch back to the root the root of that repository because i'm going to build that image that we've just seen with the msi so this is just this is just the path where i've got that that repo cloned so that's that's the path around from github and i'm going to change to the directory with the dockerfile so this is the dockerfile we've just looked at i'm going to do a docker image build so building images for windows exactly the same as you do with linux use the docker image build command you give it a tag and you tell it where the context is the folder with all the content i've got i'm adding one extra thing here with which is no cache because i've built these things before but i want you to see what actually happens when you run it without the cache so you can see all the steps executing uh because docker will run them all um explicitly so we see here this is the docker file that i've just been through it's starting from my image it's switching the shell to powershell it's copying the msi and then it's running this start process the start process with the weight flag and make sure the msi is fully installed and there's the screen pulls there while i was doing my highlighting but it took very little time to run and what i've got there is an image with my application deployed inside that msi it copies out a bunch of files it's for a web application it sets up an iis website all the prerequisites that the application needs they're in that asp.net base image so it's got everything that needs to run and now i can just execute it there's nothing particularly um difficult about packaging up windows applications even if they're older windows applications but the the msi approach isn't ideal so i'm going to run this container now if i go and have a look at my container list so if i do a docker ps my containers up and running it all looks kind of good this service monitor exe this is the the process that runs inside the um inside the container image it's a little tiny utility app that microsoft have produced and they bundle it with the windows images what it does is it watches the background with windows service so this is an ios application iis runs in the background docker expects a process running in the foreground that is the container process this is what the container process is this service monitor all it does is make sure that is still running if is falls over this application will end the utility app ends and then the container can the container exits and your container platform can do something about that so that's what that is okay so i can browse to this application here and it won't work so i'm gonna i'm not gonna wait the full amount of time because i know it will fall over what this application does is it looks for a sql server database when the application starts up to to deploy the database if it doesn't already exist there is none because i'm not running a sql server so it's just going to fall over and it will show me a big yellow uh error screen so we'll come back to that in a second and make sure that it really has failed but the big problem with with packaging this msi is that i've got a whole bunch of stuff in my in my container image that i don't need so the msi format is a packaging and distribution format but so is the docker image and the docker image is a much nicer way of doing that packaging so if i open my browser here and i'll show you uh how i was building that msi so if you're familiar with net and you've done these sort of things before and there's a very popular library called wix or or a system called wix which you can use to do these installers and it works based on xml this is the xml that builds the the msi so it creates the iis website copies in a whole bunch of stuff and then it copies in because of the way msis work every single file needs to have a kind of unique id and so this is all the content that's gone into my msi and it has that because msi's allow you to do an install and do an uninstall and to do an upgrade and all that sort of stuff which i'm never going to do inside my container when i've got a new version of my application i'll package a new container image i'll throw away the old container and start a new one so all this extra stuff which makes it harder to maintain it means i have to have two sets of tools so i need to have this wix tool set installed to be able to build the msi and then i need the docker installed to package it all up and then finally inside my container image i've got all this stuff inside the msi database how to do an upgrade and how to do an uninstall that i'm never going to do so it adds all that overhead which we don't actually need if i go back to my application here it's failed and i can't really find out why it's failed so my dockerfile doesn't tell me anything useful remember your dockerfile really is the installation steps for your application component but all it does it says run the msi so i can't see which folder my application has been deployed to so i can't go and look at the config files i need to step back to that msi stuff in order to find my way through so this is why it's not ideal now the alternative is to go directly to source code so with source code you can you can compile your application inside one image and then package it up inside on top of another image so if you're not familiar with this this is the whole idea of multi-stage docker files and again you're using images that are going to be provided by microsoft and supported by microsoft so if we're going to look at an alternative version here it's much more stuff in this docker file but it gives me an image that's much easier to work with i'm doing without the msi all together here and what i'm doing is i've got two uh two from lines that's how you can tell this is a multi-stage docker file which means it's gonna compile one image but in separate stages the first stage there is called the builder stage this is using the net framework sdk so this is an image from microsoft it's built on top of windows server core so there's a windows server core image then there's the net 4.8 image on top of that is the sdk image which includes ms build and nuget and the whole software developer kit so everything you need to package up your application so this has got effectively this is my build server i no longer need to have any of that stuff installed on the server somewhere i don't need a windows server machine with visual studio installed because everything i need to build my app is inside this sdk image and then what i do is i copy in a building two steps so i copy in all the files which describe the dependencies for my application so all those new get dependencies some of my libraries are.net core and in.net core it's the cs proj file that lists out the dependencies some of my application components are.net framework and don't know framework they have packages.config i copy those individual files one at a time and then i run the new get restore and the reason i do that is to make use of the docker cache so as you're building up your docker images it uses the layer cache every instruction that comes in the docker file docker generates a hash to see whether there's an exact match for that image layer already and if there is then it doesn't need to go and execute the instruction it can just reuse the layer from the cache so i change code a lot more frequently than i change dependencies so as i'm working on my application i'm doing a docker build locally and i'm not going to go and do it the new get restore step every single time unless one of these files has changed so if one of these files changes then the cache gets broken and the new get step will run again but if they're all unchanged then we come down to this section here the new get restored comes from the cache so i don't need to go and do that two minute or five minute download to get on my dependencies i copy in the rest of the source code folder and i run the ms build and so these are just the same sort of commands you'll run inside your build batch script files or your whatever ci scripts you've got but we're putting them inside the docker file here which means i don't have any dependencies to build this application i just need to clone the repo and have docker installed i don't even need the net framework i can just package everything up using the container images they've got all the things that i need so that's the first stage which is the builder stage now the second stage starts from a completely different image which is the runtime image so i've talked before at great length about picking the right runtime image for your application that gives you all your prerequisites but nothing extra no additional stuff that brings its own security potential security flaws and adds to download times and build times so the minimum i need for this application is the asp.net which gives me iis and asp.net 4.8 and everything configured ready to run so i'm switching to powershell again so i can run my commands in powershell and then i'm just tidying things up a little bit so i'm capturing an environment variable which is the the folder where my application is going to live rather than hard coding that and using it in several places i've got a variable that i use in here so i create that directory and then i run a powershell command to create the iis website so i'm saying i'm creating myself a new web application inside the default website this is going to be called slash app and the physical path that's where you're going to find the content which is that application root variable and then i copy in all that content from the builder stage so it's the same copy command but the from flag tells me i'm getting it from a different stage in my docker image or it could be completely different docker image i can have from and then name an image on docker hub and i copy the compiled output into my web application route so stage one compiles and builds the app using the sdk stage two is packaged on top of the runtime and it just copies in the binaries and the content from the builder stage so my final application image will only have what's in the final stage it doesn't bring in any of the ms build tools or anything like that that's only used in the first stage and the final stage only has what's explicitly brought in here okay so that kind of works in the same way and it's still going to build it's actually the same source code as my msi but now i don't need all that chunks of xml describing the bits and pieces i don't need the msi i don't need a separate tool set to build the msi i just need docker to run all this stuff so i'm going to switch back to the root of that repo and i'm going to do a docker image build command let's make this a little bit bigger same image build command effectively but i'm using the docker file that we've just looked at and i'm pointing to um to the i'm starting at the root so i'm using i'm using the whole root directory that contains the source folder and i'm pointing docker to the docker file i'm using no cache again so we can see how all this runs through so it's going to send all my docker contacts over you can see each individual file being copied in there so all the package.config all the cs proj files and then it's going to run the new get restore step this is the bit that takes a while this is the bit that i want to take advantage of the cache so it takes the kind of couple of minutes maybe to do a download of all the dependencies for a bigish application um and that will happen every time you run your build unless you structure your docker file correctly to make the best use of the cache and this is all this is about optimizing your dockerfile to make sure that when you run your builds they run as quickly as possible so that when you run them on your in your automated environment they finish as quickly as possible the image size is as small as possible and you're sharing as many layers with the previous build as possible so the goal is that every time someone pushes a change you can run your automated build it finishes quickly and you can store those images for every single build because the diff between images the size difference between images is very small because it's only the the binaries that have changed between each application build okay so now we're getting to the ms build software scroll up here you'll see this is all the output you would get from visual studio when you when you built a web project and ultimately it produces that published websites folder with all my content and all my binaries and everything to run my app and then we get to the second stage here where it's starting from the the asp.net image it sets up all my application route and all that sort of stuff and finally it's completed and everything's ready to go so it took a few minutes while i was talking around it but actually it was still pretty fast i've got my complete application packaged and built all i needed was the source code and docker desktop because i'm running on windows 10 but this also works on windows server so i can have a windows server machine doing exactly the same thing okay so let's clear this down we'll run it again run my windows container but we'll run a run the sql server this time so i'm going to run my sql server that the application will use inside the app config it's using this uh this sign up db dev01 is the expected sql name so imagine that inside my source code i was using the shared dev server the shared dev database i can create a container with that name and my application container will find it so i'm going to run my application container this is the one i've just built nothing special here detached publishing the port i'm giving it a name and this is the application image that i've just built so that's going to run in the background now so one difference between windows containers and linux containers is that by default when you run a windows container it will connect to the docker network called nat network address translation which is created by default when you install docker on windows so if i clear this down and have a look at a docker network list and i haven't got the notes for this you can deliver me typing i'll see this nat network which you always find on on windows so windows containers will always be attached to one network um at least it'll be the nat network if you don't specify now if you run in a linux container mode you need to kind of specify the network you want things to connect to so if i look at that network docker network here we go network inspect i didn't expect to be doing this otherwise i would have the cheat sheet inspecting that what we'll see here when my containers are listed so i've got my sign up web container that i've just run i've got my database container so by default they're attached to that network so they can find each other by the container name okay so let's clear this down and now if i browse to this this time it will work it'll take a few seconds because it's going to connect to sql server it'll find it this time because they're on that same docker network um but it finds it's an empty database so when i create that sql server container it's a completely empty initialized version of sql server and this app connects um it creates the the database schema using the entity framework when i go and click this button um these drop downs come from reference data in the database so this must be working correctly and this is all up and running now so this could be you can use the same approach to build older applications because that dotnet sdk image that microsoft provide it has the targeting packs for older versions of.net framework so i can have a net framework 3.5 app or a 2 application from source code and build inside here if i don't have the source code i can use the alternative of taking my zip file or my msi and deploying it in the way that we saw previously okay so that's my.net framework out really quick tour of the fact that microsoft produced those sdk images and those runtime images you can use that multi-stage build pattern uh for whatever kind of flavor of application you've got really a net application so there are like 3.5 images there's wcf images you can take pretty much anything and package it up in the same in the same sort of way and the same pattern applies to dot net core so again microsoft provide the sdk image with the build tools and the runtime image which you can use to package your application on top of so if i switch back to my other screen and here's a similar docker file this is for a net core application same deal for net five which is which is coming very shortly this is dotnet.net 3.1 which is the long term support version and again it's from mcr.microsoft.com it's the.net core sdk this is version 3.1 pattern is exactly the same so i'm copying in my cs proj files which contain all my reference data lists all my all my dependency lists and then i'm running my dot net restore so different tools for dot net core same practice same principles and then i'm going to copy the rest of the source code and do my.net publish so in the builder stage there are two steps to do the dependency fetching and then the compilation so that i can i can take advantage of the cache and make it nice and nice and fast for repeat builds and then the final stage here excuse me it starts from the the.net core asp.net image so this has got the net core framework the runtime and also the web runtime so i can run asp.net core web applications or web apis based on this image uh exposes the port so i know that docker knows that there's something listing on port 80 sets up the entry point to be net so net core applications always run as a console app so the docnet application runs and you give it the binary you want it to run and i'm copying everything from the builder stage i'm copying a specific configuration file so i'm packaging up this application container image with a different config file that's in the one that's in source code so my image can run differently when i run it locally when i run it in a container so same pattern works in the same way these images these dot net core images they're multi architecture images so i can run i can run exactly the same docker file on my linux machine when i'm running or linux container mode if i'm on windows 10 i'll get a linux container image with my.net core app exactly the same docker file same docker build command if i'm on a windows server or i'm in windows container mode then i'll get a windows image out so it's really nice if you're moving to dot net core or dot five um and you want to have cross platform support you don't change your code you don't change your docker files you don't change your build tools you just build the same thing on different servers and you get linux and windows variants okay so let's go build that and we'll see exactly the same thing so i'm going to build my reference data api so this this application really it's just a it connects to the same database um and it will pull out just the reference data that we've seen in those drop-downs so i'm building with no cache again so you can see everything happening i'm getting to that.net restore stage so it's doing the kind of download of all the dependencies it's a much smaller application smaller dependency list much more lean technology stack because you know.net core has been built from the ground up to be more or less compatible with net and work in the same way but to have all the modern approaches to building applications so it does the restore now it's doing the compilation and then we got to the final runtime image and it's all built and it's all ready to go so let me clear this down one of the things that we get with with dot net core is that it behaves the way that docker expects an application in a container to behave so when i run this i can give it an environment variable and that can override a section of the conflict that's built into the application image so dot net core has this kind of hierarchy of config you can have these json files and then environment variables and you can set the settings at different points and and then the the framework merges them all together for one set of config and what that gives me is i can with a with an environment variable i can take my image which is packaged with a config file that's expecting to point to some other database and point it to my local database which is this signup db dev01 container okay so i can run this it'll connect to that network again because it's a windows container it'll find my database i can curl the endpoint to make sure that it's reading that data and that's the data that i get out so it works in the same way docker file multi-stage build i've got my sdk with the build tools copy in my source code compile the application and then take the compiled binaries into the final image that's built on the runtime image so a nice small final image we just what my application needs to run okay if i clear this down so what we'll see here the other thing about.netcore.net framework is they're very different approaches to running applications so net core is kind of the same the same the same pattern that you get from a modern application framework like node.js or go they run as console applications they run in the foreground uh the output that comes from logs comes out into the standard output stream which is where docker is looking so docker you can see those container logs so if i look at the logs from my api and i can see this is this is what comes out of my application so it's actually using the sql query it shows me the debug level logs and the info level logs and also if i look at the top to see what the processes are then what i'll see is there's a whole bunch of stuff in here let me expand this uh there's a whole bunch of stuff here which is background processes so windows this is built on nanoserver.net core um runtime images it's built on nanoserver in windows it's built on on debian slim if you use the linux variant um i've got these background windows services that are bringing parts of the operating system but the dotnet xe is what's actually running my application that's where the logs are coming out that's where docker's looking for the logs so it works the way that the docker expects the application to work the dot-net framework app is different because if i look at the logs here for my web application there's nothing there because it's an iis application so the foreground process isn't my actual application process that's the asp.net worker process that's buried somewhere that's writing logs into it it happens to write logs into a file so if i look at the top again here there are a few more service hosts because there are a lot more background processes in the windows server core image and then i've got my w3wp process which is what's actually running my application now there's no there's no standard output stream there's no console coming from that application process because that's just the host for my own application my app is configured to write log entries to a log file and docker knows nothing about that now you can package up your docker file in a kind of more advanced way to go and pull those log entries out and reload them back to docker and that's all kind of the next stage of advancing your docker file and extending it so that your net framework applications work in the same way as your.net core applications so you don't need to change code to make that happen to make your applications uh good citizens for docker you just need to change the way you package them up in your docker file so your dockerfile gets a little bit more complex there are a few more moving parts in your application image but what that means is um at least the complexities is within your docker file so you can see exactly what's happening exactly how your app's being compiled and it's not super complicated you just you can just start your application uh with the script and inside that script it monitors your log file and relays the logs back out to docker so i'm making it sound more complex than it actually is okay so these multi-stage builds are really good because they are super portable so all you need is something that can run docker so um for these applications i've got some builds set up using github actions github actions are kind of free unless you unless you need tons and tons of hours of builds uh when you when you run your github actions when you run your workflow you specify the machine you need it to run on so in this case this is building some windows windows container images um it the build will run every time i push a file so up to github and it will also run on a schedule during the day so this will run kind of whenever i need it to and it's using windows windows 2019 and this windows 29 um runner has got docker installed it's got docker for windows installed so inside my build all i do is i do a docker compose build uh with a compose file that lists out all of my windows images that i want to build and then a docker compose push and then to in order to authenticate with docker hub i've got some secrets that are set up in my github actions and that's literally it so if i was using jenkins instead of github then i would just have a jenkins file which looked pretty much exactly the same the structure is different because jenkins files have a different um syntax but i would still use everything's all the logics inside my docker compose files and my docker files and the same with the linux variant here so i built some linux images from.net oh so this is the docker compose file so the docker compose part here that's being used uh inside that github workflow uh it's just got it's just got um for each of these images that i build it's got the image name and the the build instructions tell docker where to go and find the docker file and where to find the folder that builds everything the docker contacts so that's the same for for windows and linux as well so docker compose the syntax is the same i can put on all those build details so i can do a docker compose build and it will compile all my applications package them all up doesn't need to have anything installed on the server you don't need a specific version of net or visual studio everything you need is packaged inside those docker images okay so let's go back here to my notes okay and that's about it so hopefully that's kind of that's giving you a flavor of what you can do here so you can pretty much take any old applications and you can package them up to run in windows you just got to make the right choice of what your base image is so um when i back when i worked for docker we had a tool that we used to use with clients that would scrape a whole bunch of binaries from your windows virtual machines and package them up to run in a in a generated docker file for you to package them up to run into an image and that's used in a lot of clients so we know that you can take things like windows server 2008 applications if you don't have the source code and you want to take that app from the data center and run it in the cloud you can just pull out all the binaries and put them into a docker file build into a docker image and run it on top of windows server 2019 and you've gone straight from an old unsupported version of windows to the latest supported version which every time you build your docker image using that same automated workflow you'll get all the latest patches all the latest updates so it's really nice way to kind of bring that application into the future and run it in the cloud running kubernetes without having to without having to to rewrite the application and go back to the source code okay that's what we'll be talking about next week so next week ecs w3 excuse me we're going to look at how we can take these applications that we've built and packaged up in windows images and see what we can do with them see how we run them in the cloud and that's what a lot of people that's the end goal that a lot of the clients that i work with now they know they've got applications that are that are kind of running on an unsupported platform so either their own data center or a hosted data center and that doesn't really give them what they need they want the flexibility of running them in the cloud and they want to maybe run these old applications in kubernetes or in a managed container platform and that's exactly what you can do so when you've packaged up your applications to running uh windows images you can spin up the kubernetes cluster of the house of windows servers or you can run them directly in as you're using it as your container instances and run those containers directly without having to to manage the machines yourself and that's what we're going to be looking at next week so um hopefully that's that's going to be that's been useful for you so remember i'm doing these every week now and each month there's a different theme i've got two more episodes about windows containers so we're going to look at how you run these things in the cloud next week and then the final we're going to go a bit more detail into how the versioning works and how the runtime works around windows containers so i hope today's been useful hope to see you again next week and thanks so much for joining you
Info
Channel: Elton Stoneman
Views: 3,617
Rating: undefined out of 5
Keywords:
Id: ylYke4A1frw
Channel Id: undefined
Length: 40min 5sec (2405 seconds)
Published: Tue Oct 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.