.NET 7 💥 -- How to containerise Web API with Docker & use PostgreSQL

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign thank you for watching this video I am Muhammad and today we're gonna be discussing something really interesting we're going to be seeing how we can actually containerize our web API we're going to be seeing how we can connect to postgres running on a container as well we're going to be seeing how we can connect them both of them utilizing Docker compose how we can do the configuration do the networking between them so on so forth if you like this video please like share and subscribe it will really help the channel as well if you'd like to support me please consider supporting me on patreon or buying me a coffee now grab your cup of coffee and let's get started so before we actually get started we want to understand one thing here so currently whenever we run our web application our overall API is running actually inside our machine and in order for us to deploy this we can actually just publish it and upload it to the server but in order for us to make our application Much More Much More agile in order for us to make our application much more easier for us to manage on the long run and to have such a continuous deployment process the ICD pipelines it's always better to have it running inside a container and in order for us to do that what we need to do is we need to containerize our application and to achieve this we're going to be utilizing Docker and Docker basically it's a tool where we're actually able to create a published production version of our application that runs directly and basically what happens here is we're going to be able to publish our application and to an application file which is going to be called a Docker image and whenever we need to run it anywhere within the world that able to support Docker we're just going to take a copy of that image and run it directly and the nice thing about it is when then that Docker image all of the information that we need in order for our application to run is going to be there or the configuration all of the libraries all of the dependencies everything is going to be there if you want to learn more about Docker I have a video here somewhere where I'm gonna be linked but I'll dive more deep about Dock and how it works but for now we're just gonna be basically trying to go on a high level on all of these different topics in order for us to understand what's what we're doing but again if you have any questions please feel free to put them in the comments down below so now again let's get started so the first thing that we're going to be doing is we're going to be seeing some of the software that we need to install on our machine in order for us to run Docker as well we're going to be seeing the SDK and maybe as well the code.2 that we're going to be utilizing so here as we can see I went to the docker website so all you need to do is to go to Google type Docker downloads and they're gonna get to this website and once you go to this download the docker desktop based on your own machine type and once you do that make sure that you log into Docker just an easy way for uh for you to keep track of all of your container if you want to push them to a Docker hub and on the other ones that we need is basically we're gonna be needing uh SDK so you can go here and you can basically download the SDK based on your own machine as well and we're going to be utilizing a visual studio code and you can download it as well it's a free code editor that you can actually utilize so once you have all of this downloaded we're going to be basically opening up our terminal once you actually have our terminal output we're going to be checking which version of that.net SDK that we're gonna we're having so we're gonna put dotnet dash dash version and as you can see here I have on the latest version which is going to be 7.0 Point oops 7.0.102 so once we have done that the other thing that I need to do is once you have installed Docker desktop if you want to check if it's actually working on the top right hand side you're going to be able to see like a small rail icon and once you open it up you're going to be seeing on top the docker desktop is running you should see a green uh bubble next to it as well if you open up the dashboard let's open up the dashboard you're going to be able to see it here as well as a green icon and says engine is running which is exactly what we want so now that we have that open all we need to do right now is just go and create our web application so we're gonna go to desktop work learning uh not and let's create a folder called container containers and inside this containers folder let's create a web application let's make a.net new web API we'll call it does name demo app and that should be it so now if we go to demo app and we can open it up okay now that we have opened up visual studio code so now that we have created our application now it's time for us to install some packages which is going to be allowing us to connect our web API into postgres so let's open up terminal within Visual Studio code and let's make this a bit bigger okay that looks good and here what we're gonna put is going to put dot nut add package Microsoft Dot entity framework core dot tools so that's going to be the first package that we're going to be installing perfect now the second one is going to be.net package NP SQL dot entity framework code Dot first grass okay perfect uh uh now let's check if it has been installed successfully if we go to our demo app.cs Pros we should be able to see both of them and we only have one uh let's try it again maybe I mistyped something but not DOT add package dot NP SQL and Entity framework code entity oh I mistyped framework still Entity framework core Dot postgres okay let's just check it out in Google maybe I missed some of my stifle so just go to nuget and let's see what we're going to be getting let's zoom in and I'm just gonna copy this and let's put it here okay so it's installed let's see what's the difference was just out of curiosity oh I forgot the G okay that's fine so now that I have installed it let's double check if it's installed successfully and now we can see that it has been installed successfully which is great and the next step for us is inside our root directory I'm gonna be creating a folder and this folder is we're going to call it models and inside the models folder what I'm going to be doing is I'm going to be actually creating my database model that I'm going to be utilizing and that within my postgres so I'm going to create first my model that I'm gonna create my API DB context and then once that API DB context is created successfully and I'm going to be creating the first migration script but I'm not going to be implementing it because my database server is not existing yet I'm gonna be needing until I create my Docker compose file and then once I create my Docker compose file I'm going to be able to actually connect to my post class but for now because I don't have passwords available I will not be able to do anything so let's get started so now what I'm going to be doing is inside my models folder I'm gonna just create a new class I'm going to call the driver.cs and here I'm just going to put the namespace first and I'm just going to say demo app dot models and then we're gonna put public class driver it's gonna be a very simple one so we're just going to pop and ID and then we're gonna just put the name of the driver so it's going to be a string name and let's make it not now and then lastly I'm just going to put my driver number okay that's going to be the simple model that I'm going to have and this is going to be representative of our table at the moment and once I have done that inside my root directory again I'm going to be getting a folder called Data and I'm going to create inside of it a DB contacts a class so I'm going to say API DB context and now that I have created my API DB contacts the next step is again I need to create the namespace and then create an initialize my class so a namespace uh demo app dot data public class API DB oops DB context and I'm gonna be inheriting from the DB context class which basically I have access to it because I have installed the Entity framework core packages so once I have done that let's fix those references here okay perfect now I need to create my Constructor I'm just gonna put Constructor and here all I'm going to be doing is just pass the DB context options and it's going to take the API DB context and it's going to be options and we're gonna pass this to base class okay perfect and now once I have created this I'm just gonna initialize my table so I'm gonna put public DB set and it's going to be The Driver table that I have and I'm gonna call the table drivers and just us to get it on a Setter and let's fix those references here okay perfect and now all we need to do is just do a notebook make sure we're not messing anything up build succeeded exactly what you want and now once we have done all of that uh what we need to do right now is we need to actually inject our DB contacts into our program.cs and once we inject our DB contacts into our program.cs we're going to be basically injecting our connection string as well so it will be able to actually utilize it but for the sake of this application uh we're gonna put a like a representative or like a placeholder for our conduction string because our connection sync is going to be dynamically propagated through our Docker compose file so the main goal here is we're gonna make the connection string dynamically available for our application rather than being hard coded inside our app settings so in order for us to do that we're going to be basically just creating like a placeholder inside our app settings which is going to be referring to from our Star topic or sorry from our program.crs class but once we create our Docker compose file uh that Docker compose files can inject automatically the connection string that we're going to be needing for our web API into the application so inside our app setting.json here we're just going to create a new section where then let's call it the action strings and we're going to just create our default connection we're gonna leave it empty for now and that should be it from here and then we're gonna go to our program.cs and we're gonna start adding the interaction here so first of all we're going to create VAR this is going to be the conduction string that we're going to be reading and it's going to go to Builder dot configuration dot conduction strings and here all we're going to say is going to get the default connection let's just copy paste it okay perfect and now we need to basically initialize our uh DB contacts so also it's going to be very simple then open Builder dot Services dot add DB context and then here we're gonna specify which dtb contacts API TV context and then once we have done that we're going to specify the options and I'm just going to say let's put them on the new line options Dot services actually options.service.use and B G SQL which is going to be for our uh for our postgres and here I'm just gonna pass the conduction string and let's fix those references and this is the first reference and this is going to be the second reference okay perfect again just make sure everything is running but not build okay great so now what the what we have done so far we basically created a model we created our API DB context we created an empty connection string because we're not going to be hard coding it uh we updated our program.cs and order for it to refer to this and then basically we injected our API DB context inside our program.cs so it's available for across the application so now what we're going to be doing is we're going to be creating an amp uh the first migration which is going to be responsible for creating that database and once we do that we're basically able to once we create our database server to actually update the database server with all of the information that we need which is exactly what we want uh this is the first thing the second thing that we need to do here is uh we need to actually to make sure that our migration script is actually generating correctly so okay so now in order for us to create the migration we're just going to put.net EF migrations uh we're gonna call it initial migration and enter okay perfect so now all I'm Gonna Be Seeing here is I have a new folder which is called migrations and if I open it up and I check here basically what I see I have my initial migration here and then basically I can see that I have my table drivers and here I can see that I have my ID which is going to be the primary key as we can see here and we have my name and then we have my driver and as we can see we can it's not notable the name okay great so once we have done that the next step for us is to create our controller so let's create our controller now so inside the controllers folder we're going to be creating a new file and we're going to call it the drivers oops drivers controller .cs and it's going to be pretty straightforward so again clearly what was copy this all of this and we'll update it so we don't really need this so remove this let's update the name of this controller so the further forecast then according drivers controller and let's update the logger here and some data Constructor and that should be it we don't really need this we're going to be created our own let's see right now okay perfect so now that we have clear a cleaned up our controller that basically we have copy pasted from someone else what we're going to be doing is we're just going to be creating a single endpoint uh this is just a demonstration of course if we're going to have a full-fledged application you're going to have a full Cloud operation but just for simplicity's sake we're just going to be creating one on point which is going to be the get endpoint and while we're going uh I get we're just going to be adding a record to our database again this is all for demo purposes and the real life scenario we need to create a full floods of the current actions for your controller in order for you to have the full functionality because for now this is uh for just for demo purposes so first of all what we're going to be doing is we want to inject the API DB context so I'm gonna put private read only API DB context and I'm just going to say context it's going to ask me to fix those references and then I'm gonna inject it here so it's going to be API DB context context and then it's gonna be underscore context equal contacts now that we have injected it the next step is for me to start creating my action and this is going to be very simple I'm just going to put HP get and I'm going to give it a name and let's say we're gonna call it get all drivers pretty straightforward oops so once I have created uh once uh once I've created this here I'm just gonna be creating the function itself which is going to be public async task I action resolved get not gonna take anything and from here all I'm gonna put just so the first thing is as we start I'm just going to be creating a driver and and then we're gonna just basically get it so it's very simple endpoint so I'm going to open four driver equal a new driver let's fix these references and here the ID is going to be Auto generated so the driver number we're just going to say it's going to be 44 and the driver name is going to be sir Lewis Hamilton okay perfect so now that we have done that the next step is we're just going to be adding it to our contacts so we're just gonna say await actually it's going to be underscore contacts dot add and we're just going to add the driver and then we're just going to say await underscore contacts dot save changes anything because we're going to be saving these into the database and now once we have done that we're just going to get all of the drivers so we're gonna say far all drivers equal underscore context dot actually let's make it as an await underscore contacts dot drivers Dot uh to list async foreign and lastly what we're going to be doing here is just going to be returning it so I'm going to return okay with all drivers again this is not the way to do it but again it's all for demo purposes so all I have done here is whenever I call just to populate the database and I don't have to create a entire set of actions I don't have to create a full migration on Startup I just basically I'm just adding random people to the database whenever I'm calling the I got function so now that we have done that the next step for me is to actually start creating my Docker file so again before we actually create a Docker file here I just want to explain one thing so if you don't know anything about Docker basically what happens is within Docker is when creating a container or an image of our application is we're taking the source code we are publishing it we can imagine of it like creating a program and sending it and shipping it off to different people or basically to our customers so what we're doing here is weekly uh we're the source code of our application right now that we have we're gonna publish it into like dll files which is going to be like the end version we're just going to put it inside a container which means like we're going to put it inside the box that we can actually ship it anywhere we want and we can utilize it anywhere we want and whenever for example we want to have a version of our application running on the cloud on our different machine on our custom servers so on and so forth we can just take the Stocker Docker image that we have on the runx so it's a way to easily share the content between different servers make sure it's even it's easy for us to keep updating our application as we go so on so forth and in order for us to do that we're going to be needing a Docker file and the docker file here is going to be basically the instruction set in order for us to convert our source code for the application into an actual uh Docker image that we're going to be able to utilize and that's what we're going to be creating so let's do it so inside the root directory again let's close this uh before we do that I'm just going to do out of nut build make sure everything is building okay great so inside the root directory I'm just going to create a new file which is going to be calling a docker file very simple so the first thing here in order for me to create a Docker file is I'm just going to be specifying the base image and the base image stand for here is what type of requirement that I'm going to be needing in order for my application to start and to actually run and because it's a lot of application I'm going to be utilizing a.net SDK uh I have a different video which I'm gonna be linking here somewhere where I'll delve more deep into the foundation of Docker and how it works and how the base image works so on so forth so if you are interested I'm sure I'm going to be linking it anywhere here but uh just for simplicity's sake we can think about the base image as basically the foundation for the libraries that we're going to be needing in order for top not to actually able to run so uh we're gonna save from and it's going to be from MCR dot Microsoft dot com forward slash.net forward slash SDK we're going to be utilizing version seven so this is going to be the latest version and I'm gonna say as build environment very simple and if you're wondering where I got this from so let me just uh copy this and I'll show you exactly where I found this so if we go back to my web browser and here I'm just gonna go to uh say google.com all right let me just attract all thank you and I'm just gonna say dot not not SDK Docker hub and basically Docker Hub is a set of uh it's a repository where you can find a lot of different images that you can actually utilize within our application and basically Microsoft provided for free so here you can see it's not SDK provided by Microsoft and here we'll give you the full URL in order for you utilize it and it's going to be the same thing that we have so we can see MCL or microsoft.com forward slash.net forward slash SDK version 7.0 so now if I go back here uh let me just copy paste it to make sure it's the same thing and yep it's the same one then what I'm gonna do is I'm going to create a work directory and I'm just going to call it up and I'm going to be exposing to expose oops expose Port 80 as well I'm gonna be exposing 443 okay so let's see what's happening here so inside my application what I'm doing is I took this uh I took this base image which is going to be the main libraries that I need another four meter I might have not application and once I took this base image I created a folder inside of it was going to be I'm telling it basically inside this folder I'm going to be putting all of my source code which is going to be run and build and create a new image for me and then I told that that because we're going to be connecting to this web application I'm guy told that you're going to be utilizing Port 80 and port for nomad HTTP and Port 443 for https so but for now for this application I'm going to be disabling https so inside my program.cs I'm just going to disable this one for now we can go into a different video where we can actually go through the a different implementation of https within Docker but that's not going to be the topic of this video so now that we have exposed this the next step is we want to copy all of our source code from our root directory into inside this container so we're gonna just copy first of all we need to copy the Cs brush sorry and then I'm just gonna copy it to the root directory that I have which is going to be up and once I do that I'm just gonna run dot not restore okay and what's that what's happening right now so what I'm doing is I'm just copying my Macy as brush because it's going to contain all of the new get packages that I need and basically all of that reference for the.net SDK so once I copy it I'm running a.net restore it so in case there is any missing packages I'll be first be notified on that there's something is not right when I'm doing the restore it's always a good idea to do that before you copy your entire source code that way you basically break down the steps in order if there's any problems you'll be able to debug it a better so once I run the dot not restore the next step is I'm gonna copy the rest of my application to my container so basically when I put a dot here I'm telling it I'll copy everything from my local file to my new container similarly here I'm copying the Cs flows from my local folder to this in your folder here which is called app so once I have done that I'm just gonna run .net publish was going to publishing the application so I see we're gonna publish it and release mode and I'm going to be creating a folder called out which we're gonna be publishing this release into it pop normal similar to the normal uh not command that we can utilize within our terminal if we want to publish all applications if not publish so on so forth similarly when we give this command to Docker to be able to pick it up and execute it uh all applications inside that folder so once we have done that now what we're going to be doing is we're going to take in create a final build image so I'm just going to take this and I don't need to call it anything I can call it final environment whatever I want and once I have that I'm just going to specify a new work directory again I'm gonna call it up and I'm just gonna copy from my first container to another so I'm gonna put from and it's not going to be staged it's going to be from build Dash environment into forward slash app sorry from it's going to be from up out to the root directory so let's expand this command a bit in details so what I did here is so this is I considered this first image container that I have here it's just like a development version because basically what I want here is I I'm going through the initial setup of just creating everything like creating uh my application copying my application publishing it making sure everything is running and here is because it's not going to be the final version it's going to contain the row source code of my application I'm gonna have a lot of stuff which is going to make the image size of my container really big and because the image size of my content is going to be really big it's not going to be really well optimized if I want to basically download it fast enough so what I do here is I just take the publish outcome of that and why do I and you might think yourself okay why can't I just publish this outside the container and copy it and and the reason that we publish it inside the container and then inside then an image and then push into another image is because once we publish it within the image all of the requirement that's needed for our application to run it's going to be coming from that image itself what I mean here is it's going to be relying on the SDK that lives inside that image it's going to be like on all of the references from the dot dot not restore that we did inside that image on the other hand if we do it on our machine on publish it we could have like a library on our machine which is installed which is not available [Music] development machine environment to be copied we want to actually have the docker image to be as minimal as possible and to have the same configuration across so it's always best to have it inside a Docker image and then copy the published out from that development or build environment image into the uh the final final version of our image so that's why we're doing it and the command to do this is quite simple we're just telling it that you need to go to that first default image that we have you need to look inside the folder forward slash uh forward slash out which is going to be the public section take everything there and just copy it to the root directory and that's it because when we publish an image to publish the full list of the LL with all of the dependencies and with all of the elephants which is needed which is exactly what we want so now that we have done this the last thing that we need to do is just when I specify the entry point and the entry point mean here it's what is going to be executing when the application start and basically we're going to be referring to the main dll that the applications cannot produce so let's delete all of this and I'm just going to say dot not and this is going to be the main command I'm just going to say run demo up dot yellow very simple so here what I have is basically the docker version of my application and because I have this Docker version here what I'm going to be doing is I'm going to build that image to see if it actually built successfully so let's try it out and so inside my terminal here I'm just gonna type the docker command which is going to be responsible for creating this image for me so here we're gonna put just.net run actually but not build dot basically what it means first of all but that's not the right word so yeah dot nuts is always on my mind so we're gonna be utilizing the docker command line a tool in order for me to build this image so here we're gonna put Docker and then we're gonna say we're gonna build and then we're gonna build what we're gonna build uh we're gonna put a dot and Dot here it's going to look for a Docker file inside the directory where I'm in so before we do that if I look at the directory so it's going to be a loss if I look within the directory here I have a Docker file which is exactly what we want so if when I put docker build and I put dot it's going to basically take this Docker file here and what I'm going to be doing is just let's do one thing here so now I'm gonna do a normal build my Docker application is running as we can see on from the top right and what we're seeing here is basically it's doing all of the builds and we can see that it actually build it successfully we can see that writing image and you give it this random ID and as you can tell from this ID it's going to be really hard for me to memorize this ID because it's very long but what I can do I can tag this ID with something more manageable so if I go back Docker build I just put tag I call it demo app and run it again oh you shouldn't have uppercase okay so now you can see that this image that had that ID is now being tagged with demo up which makes it really easy for me to utilize so what I'm gonna be doing right now I'm gonna run my application uh through Docker but it's not gonna work because I don't have a database conducted but at least I'll be able to see that is actually able to see that the normal.net ROM that is listening to the sport and it's running so let's see this right now how can I run this through Docker so I'm just gonna put docker run basically and then I'm going to specify the port that I'm going to be connecting with my application I'm just gonna connect through Port Port 8081 and I'm just going to specify the environment variable which is going to be the ASP not core underscore urls and I'm going to tell it that it needs to listen to Port 80 inside the container because if we know when the container is actually running or not it's gonna pick up a port 5000 something plus so that way we're actually attending it that it needs to listen to Port 80 and that way I don't have to hard code that inside my application and then all I'm going to say is going to specify the uh application tag that I have just add for my Docker image and now we can see that my application is actually running on port 8080 8081 so if I go right now to my web browser it's not gonna work but let's see what's gonna happen if I go here and put localhost Port 8081 we're not going to see anything it's specifically if I'm going to put drivers we're not going to see it says unable to establish connection if I come back to my uh we're gonna see nothing has happened here and something else I want to mention Oops I did something wrong before that's why it's not working I needed to map this to the port 80 which I didn't do okay now let's run this I can first of all before we check it again I just want to I want to emphasize that this environment is running in production so this means that we're not going to be able to see doc Swagger because here what we have done is if application is only in development mode we are able to see Swagger and so I tell you all right because this in production we're not going to be able to see it I can disable this and build this image again if I want to see Swagger but we can do this data if we want so right now I'm just going to go back to my application and I'm gonna call this again and now we can see we got a different response with but if I go back to my application we're going to see a lot of Errors because basically there is no database conducted which is exactly what we want the application is running but whenever we do any connection it's not gonna work and we can take a look at what's what's saying here it says that there is no database connection because if you remember we left the app settings uh the connection string inside our apps I think is empty because we want to inject inject this through Docker Hub so once we have done that now what we're going to be doing is we're going to be creating something called a Docker compose file and a Docker compose file here we can think about it as an orchestra orchestration file what does this mean because right now we have a web API a web application and then we're gonna having a database server that we want to run so instead of putting every single one by itself and trying to manage it remotely not remotely independently a Docker Hub sorry a Docker compost file will allow us to put all of these Services inside a single folder and run it with a single command which basically allow us to actually do some dependencies between different containers with each other and basically it allow us to actually have uh different Services running simultaneously and we're talking to each other in a way that we want to and that's what we want to achieve here we want basically create a Docker compose file which is going to first create our database server and create a database that we want and once we have done all of that we want to actually connect to it through our uh through from our web API so let's stop this here now we can see it has stopped and what I want to do right now is let's create our Docker Hub sorry our Docker compose so inside the root directory we're going to create a Docker that is compose dot yaml file and here we can see that I have a new Docker compose five and here we're going to be actually creating it so first thing that I'm going to be doing inside my Docker compose file I'm going to specify the version and I'm going to be utilizing version 3 3.4 and then I'm gonna start by specifying and it works and then we're gonna be sourcing what networks are and then I'm going to specify the driver and we're gonna say it's a bridge okay so what did I do here so first of all I specified the version of my document similar to everything uh Docker has different Docker compost has different uh docker similar to everything Docker compost have different version they can have two 2.5 2.3 3.0 3.1 3.2 3.4 Etc so we're going to visualizing version 3.4 of our Docker compose file and then what we're doing is uh we're telling Docker that it needs to create a network between itself and basically that network is going to be responsible for having all of the containers running simultaneously inside this network so it allows those containers to communicate much more easier with each other so instead of having the every single because by default the containers are sealed from each other they live in their own small world garden and they are not able to see any other containers unless we specifically tell them that you're going to be on the same network as this other container so you are able to communicate with it and that's what we're doing here we're telling basically our returning basically our application that uh or basically our Docker file to create this network so our database application database server and our web API will be able to see each other and communicate with each other so that's the network we're calling the network dove and this is yaml so please pay close attention to the spacing because if you mess up the spacing it will not work so make sure you follow exact same spacing so now we're going to be going through the surfaces and the first service is going to be our demo app and we're going to specify the image that I want and basically if we remember when we built it so let's do it again here docker build dots and we're gonna Dash T and it's kind of called a demo app and once it does all of the builds there we can see this is the image that we have we can copy it we can just hold them up I'd rather always take the full name so first of all we're going to put the image name I'm gonna put it here and then we're gonna specify it depends on what so here uh we're gonna say it's gonna depends on a database service which have not which we did not create yet but we're going to be creating it so it depends under the score on and here we're just gonna say it's going to depend on our app DB which is going to be our database server which is going to be another service that we're going to be creating and then we're going to specify the container name and we're just going to call it up demo the services we can call it whatever we want uh let's call it them up because it's all double up demo app the services and then once we have done that we need to specify the ports that we're going to be connecting to it and I can utilize any ports so I'm just going to say I'm going to connect through port 80. 88 to Port 80. and then once I have done that I'm just gonna build the context here I'm gonna say for in order for it to build you can find a Docker uh the docker file in the loot directory and then I can say it like the name of it is going to be Docker file so Docker file is kind of called Docker file because if we have multiple Docker files we can have a Docker file we can file have docker excuse me I have dockerfile.gov dot plot.staging dot whatever we want but because here we only have one Docker file we're just calling it Docker file and this is for build now we want to specify the environment variable and here we're going to specify first the connection string because as we saw the previously the connections thing is going to be automatically injected into our application so here we are injecting it from and here we're going to say connection oops strings underscore underscore default connection and then we need to specify the normal uh postgres connection string so we're going to start by user ID all of this we're going to be creating so don't worry we're going to put equal postgres then we're going to specify the password which is also going to be postgres of course on your real life scenario you can change these but for now just to make it easy for us what we're doing is we're just gonna change with uh really taking the default implementation towards it so then once we have that done uh what we're going to be doing now we need to specify the service that we're going to be connecting to so we're going to say server equal and as we can see here it depends on FDB so that's the server that we're going to be utilizing up underscore DB and then we need to specify the port on the default excuse me the default port for postgres it's going to be 5432 and then once we specify the port we're going to specify the database that you want to connect to data base and we're just going to call it sample driver as a sample DB driver anything we want and then I'm gonna say Integrated Security equal through and lastly if we're going to specify the polling mechanism that we have I'm gonna say it's going to be equal true okay so now that I have created all of this uh if we're just gonna take a full review on this so we can see here that I'm doing is I'm creating the connection string and if we notice it's going to be the same structure so I have connections here as a higher level and have default connection underneath so that's what exactly what I'm doing here is I have the conduction string here on top and then I have the underscore underscore it means that we're going one step lower and I have my default connection then I'm specifying my user id excuse me and then I'm specifying the password then the postgres as the server which is going to be the server that I'm going to be creating the ports the database and the Integrated Security and the pulling so the next one is I'm going to be specifying is the environment or actually the port that my application is going to be running on and it's going to be asp.net core underscore URLs it's going to be equal to http false forward slash plus I'm gonna say it's going to be on Port 80. so now that I have specified the environment lastly I want to specify the networks that is going to be utilizing uh it's going to be utilizing the dev Network that I have created on top here so now this is our first application our first service the second service that I'm gonna be creating is going to be my database service so scallion is kind of called up underscore DB and here I'm just gonna first of all specify the image and the image is going to be the postgres image and it's going to be the latest one and then what I'm going to be doing is I'm going to specify the container name because basically we're going to have the container of our application running and then we're gonna have the process container running so we're gonna have two containers running one as a data database server the other one is going to be our web API and we're just going to call this app underscore DB and then we're going to specify the environment variable and here we're going to specify the username the password so on and so forth so we're going to just say postgres underscore user is going to be equal to postgres and then we're going to specify the password equal again post address and lastly we're gonna specify the database I think we called that sample what did we call the database let's see sample DB driver and then I'm just going to specify the ports that I want so if I want to connect to it from outside my container I'm going to connect through five four three three but inside my container I'm gonna write I connect to it through five four three two so that's a way for me to connect through different ports and uh let's see what asks me to do need to put restart as always in case the database server fails when I restarted and now we want to specify volumes and before we jump into that let me explain what volumes are so when I when a container runs uh basically whatever information it stores inside that container whatever that container shutdown is lost forever and basically containers do not uh don't have long-term storage of our data so as long as the content are running whatever information contain is going to be safe but as long if it shut Downs or it fails or there's any problem or it crashes all of this data is going to go it's gonna be disappearing and we're not going to have access to it so what's the solution here luckily for us within uh containers we're going to have something called volumes and volumes is basically like a outside storage that the container can actually utilize in order for it to store all of the required information inside of it so let's say I'm building a database server and I have created databases inside so the actual servers actual program is running inside the container but the storage where it's actually communicating and stories all of this information is outside that container and these storages outside the containers called volumes so it's a way that we can actually communicate from that container into uh outside it could be our machine if it's on the server we can put a storage like a blob storage or we can put an S3 file we can put whatever we want for example and once we do all of that what we're doing is we're basically we are storing this information outside so in case that container runs whenever we pick it back up with the same configuration it will be able to find those files and utilize it so that's one aspect second it's in case it crashes it can always find this information and we don't not gonna have any data loss because we're starting it outside the containers so whatever the lifespan of a container is is not affected within the data that is actually utilizing so in order for us to utilize volumes gonna be pretty straightforward so we're just going to specify the path for it I'm just going to put up underscore data forward slash for forward slash slip and that's a local storage on my machine I'm gonna play postgres ql and I'm going to forward it lastly I'm going to save some data so the last thing last step here I just need to specify my network and it's going to be similar to the one before it's going to be on dove and now what I need to specify is I need to actually Define that I have this uh this volume outside so all I'm going to be doing here is I'm going to put volumes and I'm going to specify or basically I'm telling you that there is a volume here that you need to be aware of and this volume name is gonna be updata as simple as that so here what I'm doing is I'm just specifying my volumes I'm telling it that's going to be updata uh why is it not happy oh I think a star yeah so spacing is really crucial as we can see here so let's do a quick recap before we do anything else so first things first is I created a version for my Docker file Docker compulsory then I specify the network where these two services are going to be able to communicate then I specify the service instruction what I defined first my web application double up I thought that where it can find the docker image that it needs well it depends on it depends on the database server I specify the container name what's actually run the ports that I'm going to be utilizing to connect to it then I'm gonna hold it if you're going to build it if you don't want to use this image and you're going to build it again just use this context which is in the local directory and if you look for a file called Docker fiber you're going to file all of the instruction for you to build this image then we have specified the environment variable where we have dynamically passed the connection string so it will be able to be picked up by our program.cs inside our application and I specify the default port number that the application we're going to be able to listen to so it will match this one and then I told it that it needs to live inside this network that I've created previously the second one here is going to be my appdb which is going to be my database server I just told that it needs to utilize postgres version I gave it a name appdb specified the environment environment in order for us to set up this database server the username password and the database then I specified the ports in order for me to connect to it I specified uh what is that it needs to restart always in case it fails specify the volume that it needs to use in order for it to stir the data and lastly the network that it needs to live on and here we can see finally specified the volume it's very simple so now that I have done all of that you might think yourself okay how can I run this very simple so all I need to inside my terminal is clear this up a bit inside my terminal see how it's looking yeah that should be fine let's make it a bit higher see okay if I want to run it or I'm the docker that's compose up as simple as that and we can see here it started doing a lot of stuff we can see that it started to run we can see that my appdb is processed and we can see the process is complete if I go up up what is in yellow we can see that my application is also running but right now we have a bit of a problem why because right now what I have is I have a database I have a database server running great I have my applique I have my application running great but I don't have a migration script inside my database which is exactly what we need so what I can do here there's two options what we can do is you can actually create update your web API in order for it to do all of these checks manually and whenever the application is running it will check if the database exists or not if it exists it will check the latest version of the migration and if it does if it does not contain the its version it automatically apply them so that's one version otherwise we can do it manually so if you're interested in learning how to do the first option please comment down in the comments down below and we'll create a video to cover it up but for now we're just going to do it manually where we're going to be updating the connection string of our application to connect to this new server that we have and then from there what we're going to be doing is we're gonna Implement a database update command manually so first of all I'm going to open my database server uh I'm going to connect through it through one of my favorite apps uh let me close this let me bring it here and let's close all of these so inside my database server I'm not sure if it's clean uh fortunately I cannot zoom in in this it's a bit too far awkward application but if I connect right now to that postgres instance I think you can see it I'm just gonna specify here the port for it which is going to be 5443 and the password be specified I think it was postgres yeah and now if I put best connection it says it's connecting to that database server and if I click on finish and if I open it up we can see that I don't have any database except a default database server that postgres has provided so what I'm going to be doing right now is all I'm going to take is take this default connection string that I had before I'm just going to copy it here open my app settings update the old one here that we have and update this port so here is gonna be a localhost because it's going to be connecting through our application and I'm just going to update the sport save it create a new version of my terminal and then I'm gonna so now that I have updated my connection string all I'm just going to be doing is I'm going to put dot not build so now my application is bending successfully I'm just going to put.net EF database update and that should basically allow me to create my database inside my database server perfect now if I go back to dbweaver and if I refresh here I should be able to see my database now if I go back to edit again added connection and put the new database name test connection to it it exists if I click on OK yes if I come here and open this up I can see my database table if I open this up I'm able to see the tables here driver if I open it up view table I'm able to see it okay perfect so now that I have I was able to do that the next step is I need to just delete this I don't need it anymore let's stop my application stopped okay now let's go back to my Docker compost file and all I'm gonna do is stop the application I'm gonna put Docker Dash compose down now it's being completely removed and I'm gonna debug the entire thing so I'm just gonna put Docker compose up Dash Dash build which means gonna reboot everything for me and it's gonna make sure everything is running so if we can see it's building it's running and now if else goes to plan if I open up my API testing tool which is going to be insomnia and inside insomnia I'm just going to make sure that I'm connecting to the right uh endpoints if we got our daughter compose let's see here what was the uh it was 8080 so I'm gonna take this I'm gonna go to Port 8080. 8088 sorry I'm gonna click on send I should be able now to get my address here perfect if I could send that again I should see another driver perfect third one and so on so forth and we can see here that everything is being executed correctly against my database and if I go back here to my database table and if I click on view all data I should be able to see three records so if I click on data I'm able to see three records now the big test is if I stop this and as we can see it stopped and let me see if I want to make it turn it all down so I put it down post down we can see everything is removed and now if I run this again and let's see what happens if I do the same I should be able to see four now perfect which means the data is being consistently safe so let's do a quick update a quick summary of what we have done so far so first of all what I have done is I basically I created my web API I have configured it to work with postgres I created my migration folder uh sorry I hit my API DB contacts and then I get my migration but I did not connect it on a database then what I did is I created Docker file for my application where basically I'm able to containerize it and utilize it inside my Docker compose then I have configured I created my Docker compose file where I have specified all of the steps that I need in order for me to use it to run my application inside Docker and then I created originalized a version of postgraphs inside my Docker file uh Docker compose file so I will be able to connect to it through my API ID because so my web API and then what I did after that I did the manual setup of setting up the database and creating it so once all of that has been done I was able to dust it and make sure that the web API which is running inside Docker and my podcast which is running also inside Docker able to connect with each other and basically I'm able to actually have these two working simultaneously together so that's what I have done here so the docker compose file was basically able to have orchestrate my web API I my postgrad so they were able to communicate so I hope you like this video uh please like share and subscribe if you do and if you talk about foreign support me on patreon and if you'd like me to jump into any topics further in much more details regarding to postgres regarding Docker regarding.net and Docker so on so forth please let me know in the comments down below as well please ask any question that you might have in the comments down below thank you very much for watching this video and have a great day
Info
Channel: Mohamad Lawand
Views: 11,209
Rating: undefined out of 5
Keywords: .net 7, .net, api, beginner guide, step by step, csharp, c#, dotnet, dependency injection, code with me, coding, ef core, sqlite, database normalization, database, entity framework c#, entity framework core, entity framework, asp.net core tutorial, rest api, crud, minimal api dotnet 7, dotnet data, dotnet services, .net core, asp.net core, docker compose, docker explained, dotnet docker, dotnet dockerfile, dotnet docker tutorial, postgresql tutorial, postgresql, postgresql docker
Id: 9ZEbJT36-Uk
Channel Id: undefined
Length: 58min 6sec (3486 seconds)
Published: Mon Jan 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.