Python Web Application Deployment Tutorial - Docker Compose with Gunicorn, NGINX, Postgres - Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome to an exciting part of this web application development series so in this part we are going to see how we can use docker compose to connect together multiple containers so in the first episode we saw how it should be done with the flask application but this flask application needs to connect with a database and we are going to use the postgres database for that purpose and also we need to connect our application with a reverse proxy so this means that now we have three containers that needs to be spin up so it is going to be very exciting to see how we can use docker compose to grab all the containers together and fire them in just one command so let's get started [Music] all right so now that we have done everything that we need to have the flask application running in a container then there are two more services that we have to spin up that are considered as a best practice when we host an application in production and i'm talking about the database instance which is postgres that we already know that we have to set up but i also talked about the reverse proxy service that we need to execute now a reverse proxy is a dedicated http service that is going to be responsible to handle all the requests that are going to arrive from your clients and actually when it comes to production environments leaving this task to the flask g unicorn itself is not considered as a great idea and it is more confident to use a service like nginx to basically handle all the requests that are coming from different clients so this is why we have to spin up a database and as well as in nginx which is a reverse proxy service that needs to be running in our production environment now that means that we now have three containers that needs to execute in production so first is the flask application and then we got db and also the reverse proxy that i talked about so now we have a kind of problem because we have to figure out how we are going to connect those three services together and for this purpose docker comes with a special utility that is called docker compose and it helps you to define services and connect them with each other basically by creating a basic yaml file and in that file you can specify what are the services that you want to execute in one shot and then basically we will be able to execute those three services with only one command so let's go and see how we can set up docker compose by writing a basic yaml file which will be responsible to define those three services that i talked about all right so let's get started now first of first i will start by creating three directories and each directory will represent a container that needs to be created now each container is going to have its own and unique configurations so this is why having them in separated directories could be a great idea so first let's go and create the web directory which will be basically everything that needs to be included for our flask application only so let's say web and then i will create two more and the other one will be db so we might also include some necessary configurations about the database itself and the third one will be the configurations for the nginx so let's call it something like proxy like that okay so now that we have done this we have to move the market directory and then the docker file requirements and then run that py everything that is pretty much related to flask under the web directory now i'm not going to do this with pycharm because it will automatically do this by refactoring the imports and all the libraries and this is just going to screw up everything so besides i'm going to open my file explorer in windows and complete it from there and now let's open this directory and here we'd like to move again the docker file requirements run that py and the market under the web directory like the following and now that i have done this then the pycharm should automatically synchronize with these changes without really changing the code of the python itself so if i go back to pycharm then you can see that everything now looks okay all right so let's start with the proxy directory and really design the engineering service now first of first we'd like to create a docker file to really include some information about the future container that needs to be spin up based on the nginx image so i will go here and basically create a docker file like that now remember that its name has to be docker file and really not just a random name that you want to come with so remember to name your file exactly like that okay so now we have the docker file and the other file that we'd like to create in this stage is another configuration file that the nginx is going to use so i will only go here again and create a new file and let's just name it conf like that and let's go and first work with our docker file and write some docker syntax code that will be responsible to create an nginx container all right so inside this docker file of nginx i'm going to specify several lines that will be responsible to override the default configuration that the nginx service comes with so when we spin up a default nginx service that we pull its image from docker hub then we will end up by pulling a default configuration that this service has and we are interested to change it a little bit to really support running the flask application with this reverse proxy so first of first i will specify that i'd like to pull a specific nginx image by using the from keyword which we are very familiar with so i will say from nginx and i will use the column now and it will be version 1.19 and then i like to say hyphen alpine like that and that will be the image that i interested to pull now so the next line will be responsible to basically grab the custom configuration and override the default configuration that is located at a specific directory within this container that i already know so the directory might look a little bit confusing for you but this is just a basic linux directory that comes in with this alpine image so i'm going to use copy and i'm going to copy my configuration which i named conf and the destination of that will be for slash etc and again forward slash nginx so this is now a directory within the nginx container that is going to spin up in the future and the location of the default conf would be at conf dot d so this is another directory and then we'd like to say that we like to override this with default dot conf like that so this line will give us full control of the configuration of the nginx service all right so now let's see what configuration engine x will support and its unique syntax that sometimes could look very confusing but i will really try to explain line by line what i'm doing so the configuration should start with a default keyword that is named server like that and then since the rest of the configurations are going to be related to the nginx service itself then now we have to open up and close the curly brackets and press enter and then continue including some more configuration within these curly brackets so now i'm going to say that i'd like to listen to port 80 within this reverse proxy so it will be as easy as saying listen and then we will have to go here and say something like 80 like that now this configuration needs to be created with a semi columns so i will type in here semicolon to really specify that this is the end of that specific line and the next thing that i'm going to say here is the server name so i'm going to say server underscore name and that will be basically localhost like that okay so now that we have those configurations then i didn't do anything too much complex till now basically i just said that i'd like to listen to port 80 and then my server name will be localhost and that's it okay so the next configuration that we want to set up now is a specific configuration that will be responsible to take all the requests that comes from a client and to pass it to the running flask application now if you think about it when me as a client that tries to access that expected running flash service first of first i'm going to meet with this engineering service because i am not going to specify the port number when i'm navigating to a random website so for example if you think about it even in my website you only specify that you would like to navigate to a specific domain name like gymshapecoding.com but you'll never specify the port 5000 because it is a flask instance that executes and that is why we first meet with this engineering service which is being hosted in port 80 but this is exactly the place where we'd like to specify that all the requests should be processed and then passed in to the running flask application inside that server so this is why i'm going to write the following configuration in here as well so i will say location and then i will say forward slash like that to specify that the location is at the root directory and then i'm going to say curly brackets like that and go inside these curly brackets one more time and then here is the location that i'd like to specify where we want to pass in the request so i will say proxy underscore pass and then i will say something http comma and then two times for slashes just to basically create a url and then i will say web colon 5000 like that now this is where the location should be passed in port 5000 now i know that you ask yourself why the hell you specified web now this is something that i want to leave you curious with but you are going to see that just in a few minutes because our docker container is going to recognize the web keyword as a reference to the running flask application so we will see that just in a few minutes when i connect those two applications with the docker compose and when i basically execute those two containers together the entire picture will look very clean to you and i just realized that i forgot the semi colon so we'd like to specify that here as well because it is very important otherwise the configuration will fail and we will not be able to spin up an nginx all right so now that we have the proxy set up then let's see how we are going to connect the flash container with that nginx container that we did not build and spin up yet so for this purpose as i said earlier we are going to use something that is called docker compose and by defining a basic yaml file then we can basically spin up two or even more containers together and to really have a connection between them so to get starting with docker compose then there is one unique convent file that we need to create which needs to be called docker compose so i'm going to go to the root directory of our entire project and i'm going to create a file and i will name it docker dash compose dot yaml like that now again this is one of the files that you only need to name it in that way and be sure that you don't name it something else rather than what i wrote now so i will create that and now basically we need to include some basic yaml syntax to really describe that we need to spin up those two containers together now for sure in the future i will also include the database itself but let's just start with the nginx and with the flask okay so first we need to specify which version of docker compose we'd like to work with so this is why we should say version 3.7 like that now don't get worried if you don't have the auto completion like i do because basically this is a plug-in that you can install if you use pycharm and for sure this is something that you can install as well and if you watch the tutorial of docker as i suggested in the beginning of this tutorial then you should already have this plugin okay so once i specified the version then we should open a new object that should be named services like that because we want to specify what kind of services we'd like to use so this is why we create this object and then once we will press enter then we need to make sure that we have two spaces for the indentation like that all right so the first service is going to be the flask service and we'd like to name this service something like web so i will do that and then once i declare this then we need to now think like we spin up this container but we kind of define it with yaml syntax so okay we have a service named web and then we want to say to that web service where is the docker file that needs to be built so the docker file of the flask application is inside the web directory so this is why i will say build and i will use column sign and i will say web like that and this line just says something like okay go to the web directory from here and build the docker file within this directory so this is what this line does and once i have done this then there are going to be more pieces of information that i'd like to specify under the web here and the next piece of information could be something like restart always like that and this line will be responsible to always try to spin up a container even if there is some generic failure so this is a great idea to add this line here and the next thing that we'd like to say now is the information that we probably use within the command when we spin up this container throughout this tutorial so if you remember i already had a documentation of that long comment that we wrote to run a container based on the flask image so let me open the run.py command and actually let me split the panes so you can really see the comparisons of how you can spin up a single container or to combine multiple and then declare it with yaml file okay so i'm going to do something like that and i will open the docker compose in this side and then this one in the right side okay so if you remember we had this piece of information about dash p 5000 to 5000 so this line was responsible to expose the port from the container to our local machine so i'm going to again specify the same information but this time this is going to be with yaml syntax so we can say ports and then i will say colon and i will enter within this block and then since this expects for a list object then i can just say dash space and basically use the same value of this one so i will copy that and paste this in like that and the next piece of information that we'd like to specify is the additional environment variables that we'd like to have in this container so this will be as easy as environment column and then the key values that you'd like to specify again with a list object so it will be dash and we can basically now say that it should include debug equals to 1. now i don't know if you are too familiar with yaml syntax or not but i just forgot to specify that i have a video which is 50 minute long that you can watch on my channel that really covers everything that you need to know about yaml syntax so this is a great idea to maybe take a look even a few minutes should do the job for you and actually this is great now because now we have control if we'd like to run the application in debug mode or not and it will be as easy as to change it to something like zero in case that we'd not like to run this in debug mode so let me revert this now to one because we want to use the sqliter database then this is why i have debug equals to one okay so the next piece of information should be about the network of this application now this is a new docker topic that we did not talk but when it comes to docker you can create your inner networks and you can include containers in them so i will just say networks and i will now create a random network so i will name it flask network like that and the reason i am doing this it is because in the future that i'm going to also declare the proxy which is the nginx then i'm also going to include it in the same network as this flask application and then those applications will know how to connect to each other so this is perfect and this is why you have to use this docker network utility and this is a great idea to specify those key values in here as well okay so now that we have done everything that needs to be declared in the web block then i'm going to enter and indent out a couple of times until i reach here and i want to make sure that i'm in the same indentation as this web and that is perfect so now we'd like to spin up the nginx and this is why it is a great idea to now say that we'd like to have one more container and we can now name it proxy like that and the process now is pretty much going to be the same like we have done previously for the web because we now like to say that we want to build the docker file within the proxy directory so i will say build and then column proxy like that and we'd also like to say that restart equals to always because this is a great idea and now about the ports of the nginx so if you remember we said that we'd like to have our application in port 80 because this is the common port in all web applications unless you have certificates then the port is going to be 443 but in our case we are not going to include certificate in our deployment so this is why we like to use port 80 which is http so we can say ports and we can basically say that 80 should be mapped to 80 inside the container exactly like we have done here so this is pretty much the same process okay so the last piece of information should be the network itself so again this will be something like networks and i'm just going to grab the same value of here so let me just delete that and paste this in like that because we want those containers in the same network so this is why i have done this copying and pasting and now i think we are pretty much ready and let's press enter and basically indent to the latest line that is possible i mean the first line okay so as you see now we have two services which this one being the flask application and this one being the nginx service that we'd also like to spin up so now the last value that we should specify at the first index in the next line is the networks that this compose file needs to use so i'm going to say networks like that and let me add an enter so we will have a nice separation and then i will only say that the network that this compose file should use is the exact same network that we have used throughout the definitions of those two services so i'm going to say flask underscore network and you need to specify a column here like that and this should really be it and now we should be ready to spin up those two containers in one command and to really test out the results of it okay so let me close this run.py from here and close this one from here as well and zoom this up a little bit and open up our terminal within the root directory of that project all right so now that we have opened our terminal then we should understand how we are going to spin up those containers in one command referring to the yaml file that we have just completed to write so when you install docker desktop on windows then it is basically going to come with another docker command line interface that is called docker dash compose like that so if you have really followed at least the first 50 minutes of my docker tutorial which i suggested to watch then you probably installed docker desktop on your windows machine so this is why if you try to use docker dash compose in your terminal then you should receive some result and not error but if you want to basically install docker compose on any kind of machine that you use then you can follow this documentation which i will provide the link of that in the description itself so just to really prove you my point then you can see that inside this documentation we have some reference about install compose and you can see that under this paragraph it says to us docker desktop for windows includes compose along with docker apps so most windows users do not need to install compose separately so this really means that you should have it on your computer but if not then you can follow this documentation which i will provide the link of that in the description and really install this specific cli of docker compose and really to follow along with me so let me go back to terminal and continue from here and i will clean the screen now the only thing that you need to do is basically say docker dash compose up like that and that's it that's it then you will have your two containers spin up and if i press enter in here then you can see that we got some errors so it says to us that version in docker compose is invalid it should be a string so i think that the version up top in the first line should be fixed and yeah we should go here and fix that basically by using double quotes and this should be it and now if i open back our terminal and clean the screen and really try to execute this one more time then you can see that we have the first image being built like we expected and now the nginx image should be get ready as well so let's wait a minute and see the results okay so we can also see that we have the nginx let me clean this smaller round and you can also see so this is the completion of the flask image and here we see that we got also the web and we also got the proxy itself so this really means that we have both of the services installed correctly now you can see that we kind of have an interactive mode within this docker compose but before we fix that let me open my chrome browser and really test the results so let me bring back our browser and change this location to our local host and to basically say that 127.001 and now i don't really have to specify any port because all the browsers are trying to connect to an application with the http which is port 80. so now if i press this ip then you can see that we are inside our application and that is perfect because we were able to create the nginx instance as expected and it redirects our request to the inner flask application that runs together so this is really nice and we are getting close to having a ready production project all right so now that we were able to spin this docker compose then i want to show you something that is related to the configuration of nginx that i said that i will explain later so let me open pycharm here and let's split the panes with the configuration file like the following okay so on the left pane we got the docker compose file and on the right pane we got the configuration file that the nginx uses now if you pay attention on the right side i used as the proxy pass value this url and you might be confused about this value because i automatically said that we should go to web but we did not quite understood from where this web comes from so this actually comes from the value of our service name so you see when we create services within docker compose under the services block then it means that that is the domain name that we could access it by referring it so this means that if i was to change the service name from a web to something like my underscore service then this means that now i change the inner domain name that makes this container accessible so this will mean that i should also change this to my underscore service because in that case i only refer to a domain name of another container and since they are in the same network which we have declared here and as well as here then i have the access to basically point to that domain name by using the value of web or my service if i was to leave it like it is but actually it is a greater idea to change this back to web so i just wanted to talk about the idea of the value in this configuration file and this is really comes from the fact that i can access it basically by referring to the services name okay so there's actually one final thing that we have to customize before we go ahead and create the database instance within this docker compose file so i just want to revert this environment variable back to zero to not having a debug equals to true situation so i'm going to just change it to something that is not one and now i'm going to go back to our terminal and i will say docker compose up like the following so let's zoom out a bit and see the results now i did not talk about this yet but actually when we execute our application in debug equals to false then there are still some warnings about how this flask application is still not running in production mode so this actually comes from this warning that says us this is a development server and we need to use a production server and for that purpose we need to use a wsgi server now when it comes to a web framework like jingle then it already has some files that deals with wsgi servers but when we talk about flask we need to spin a wsgi server on our own so what that means it means that we cannot allow ourselves to leave the docker file as it is because it will keep running our application in this development mode like it says here in the warning now i know that this is something that we could change from the very beginning of this entire series but i just wanted to wait with it because it is important to differentiate between what an nginx does to what a candidate for wgi server could do so we need to create wsgi server to handle python code meaning the python request that are going to basically do stuff like interacting with database so this is the stuff that python does but when it comes to nginx then it is mostly going to deal with style files which are so called static files that we rarely use in this project so this is why we have to have nginx for handling styling and we have to have wgi server for handling python code better and this will basically allow us to have a production server and not a development mode server like we have now now leaving this like it is it's just not a great idea because this is not designed for production purposes so we are going to use a wgi server that is called g unicorn and for that we need to go back to our requirements.txt file and actually add this as a library and then do a few of customizations to our dockerfile so let's go ahead and see what we should do so i'm going to open our pycharm here and now i'm going to go back to our requirements.txt which is inside the web framework and i'm just going to include one more library within this requirements.txt file and it will be the g unicorn wsgi server now this will go ahead and install this package within our container and it actually comes with a built-in cli so it means that we can now use commands with the prefix of g unicorn so we are going to customize our cmd commands within the docker file because now g unicorn is going to be recognized as a built-in command in our command line interface so this means that we can go to our docker file and actually change the method that we execute our application now this is the exact line that causes the warning that we saw where it says us that this is a development mode server so besides we need to change it to being run with g unicorn and it will be a command that will look like the following so i will say g unicorn and then i have to point to the module where our application executes so if you remember our application executes in run.py files so i can say run and then it expects for the instance of the flask application right after the colon sign so i'm going to say app here like that now before we go ahead and execute this actually in g unicorn documentations there are recommendations about running this with different workers when it comes to executing so we can actually create multiple workers that will be responsible to manage the traffic from everywhere so we can say that we'd like to create three workers and actually this is a convention when it comes to running servers in a minimal server so we are not going to spin up this fancy server with like 32 gigabytes of ram and multiple cores besides we are going to do that with a minimal server with one core and with servers that having one core it is recommended to spin up the g unicorn with three workers according to their documentations so i'm going to say here dash w and specify the argument of 3 like that all right so there is actually one final argument that we have to pass in to really spin up this unicorn successfully now if you remember if i go now to the run dot py then we actually controlled the host with this ip and this port so what that means it means that we also have to pass in similar arguments to the g unicorn itself so i'm going to go back to our docker file and say here dash dash bind and i will pass in 0.0.0.0 colon 5000 as the port and this should really be it and go ahead and spin up our flask application with g unicorn so one final thing i'd actually like to comment this comment in here to really remember that i have the option to later comment this out and uncomment this out when it comes to basically running our application in debug mode when we need to so i'm going to comment this out and open this up to test if everything now works properly with the g unicorn so i'm going to go to our terminal and basically execute docker compose down now so you can do this just to basically get rid of all the previous executions and now before we go and say docker compose up we should go and rebuild the images because we had some changes so i'm going to say dash dash build and now if i run this then now we can see that the logs are quite different right now because we execute the flask application with g unicorn and you can see that it says us listening at zero zero zero zero five thousand and actually there are three workers so it means that everything really works properly now to test this out we need to go to our chrome browser and see if everything works properly when we go to our localhost ip because like i said when it comes to handling the request we are first going to meet against the nginx and the nginx is hosted with port 80. so i'm going to bring our browser here and try to see if everything works and you can see that everything works properly like expected and now we actually got the debug mode equals to one if you remember i changed this to one to have the sqlite3 database so it means that i can register to that website so it is a great idea to test if everything works as expected before we go ahead and proceed with some more things so i'm going to create a new account like jsc 10 and i'm going to mismatch the email so i'm going to use a not valid email and now i will try to create account and you can see that we got the email error and now let's try to do this with valid email so i'm going to say something like that and if we create account then you can see that it says us email already exists and actually this is great because i forgot that we used it so i'm going to change this to something else and test this out and if we create account then you can see that everything works as expected and it means that the g unicorn did not really affect the functionality of our website so it means that we can continue on from here spinning our postgres database all right so i know that we covered a lot of new information and if there is something that you did not understand till now then feel free to comment this out in the comment section because i know that i discussed about a lot of new technologies that i did not have any tutorials on them and pretty much each thing that i'm doing here is new to you so feel free to comment out if you have any questions okay so now that we were able to spin up this container and as well as this one now it is about time to work on our database now this will be the last step of the design that we are going to complete to the docker compose and then we are going to grab the entire project and move it to some production server that we will create on linux which is a comfortable cloud provider that we are going to use okay so now the third service it makes sense to name it something like db and then we are going to see how we are going to spin up a postgres container now there is also the option to pull directly the image from docker hub without really referring to some docker file unlike we did with web and proxy so if you remember i said that we should build the docker file within the docker within the web directory excuse me which is here so in that case i can also specify the image name and it will pull it directly from docker hub so i will say image and that will be equal to postgres like that now since i want to work with a specific image then i will say column 13 like the following and from here we are good to go so let me minimize this back so it won't confuse us too much okay so like before i like to say that we always like to restart this container if there are going to be any failures so i will leave it as it is and now let's talk about the ports so the port of the postgres container by default is going to be 5432 so i will say ports and then i will say dash space and then i will map the container port to the local port of my computer so it will be five four three two column five four three two again like that now this is by convention something that you want to do because postgres service by default is designed in a way that it runs on this port so just write this value and nothing different than that okay so now that we have this set up then we also like to specify some environment variables and as well as the network so the network is again going to be the same as the web and the proxy so i'm just going to copy that and paste this in like the following okay so from here we also like to specify several environment variables that the postgres is asking from us and actually those are mandatory environment variables that you have to fill in otherwise the postgres container is not going to spin up properly because again this is how the postgres itself is designed from their site so this is not something that is dependent on us this is the way that the image is designed so we have to say here environment and then we will fill in several environment variables under this environment block now if you remember we already have information about the specific information because we already wrote a production configuration in the flask application itself because if you remember this is the production database that we should spin up and from the very beginning of this entire tutorial we wrote a config.py file that includes those pieces of information so i'm just going to look for that and this should be under web market and then the config.py file so let me split the panes here and let's go back to our docker compose so let's write down the environment variables that the postgres image expects from us so first one should be postgres underscore user like that and i'm going to duplicate those lines by ctrl d a couple of times and then i will change this to pass so we got username password and we also need to specify the database name so i will change this to db now i'm going to pass on this one because i thought that we also need to specify the port like that but we actually not need to do that because we already exposed the default port so i can give up on this value okay so the environment variables are going to be passed in by separating them with an equal sign so i'm going to say that this should be equal to admin and the password is going to be equal to admin as well and the database needs to be marked like that so i know that we have a duplicated values in here and as well as there now as i said i don't really want to focus too much on securing things up and i just want to go forward with some deployment example with docker compose and i already feel like i explained a lot of new things that might be the first time that you see this so i don't really want to make everything in the most best practice way sometimes i might leave things a little bit more simple and if you like to change the behavior of the way that you store passwords in this config.py file that we created then you already know how to do that because you can change this to something like os.nviron dot get and you can read an environment variable that is going to be passed in from the docker compose file so just for your information there is always a room to improve things up so i will remove that and continue from here okay so there is one final thing that the database container needs in order to store information for a long time now when it comes to containers basically the containers are not designed by default to maintain information for a long time so what that means it means that if i was now to spin up a postgres container and to exit this container in some time from now then i will end up by losing my information in that database because the containers are not designed in a way that they are just going to keep information forever so when it is exited then you basically lost all your data but actually docker comes with a feature that is called docker volumes so a volume is a logic you need that you can point to your container and then this volume will be responsible to maintain your information and then you will have persisted info that is going to be stored for whatever time you like to even if you close your service or even if it's crashed in some time so the way that this should be defined in the yaml file is by the following way so let's see that one so i'm going to go outside of the environment variables and i'm just going to say volumes column and then i will just say that we'd like to create a new darker volume and mount it to some directory inside the postgres container and this way i will grab the information that is stored inside the container to a volume that i can have it persistent and the information will there will always remain so i will say postgres data so this is just a random name that i wanted to create and i will mount it to this directory so i already know that this directory is a very unique directory within the postgres where all the information is going to be stored so it will be var and lib postgresql forward slash data like that so those lines are very critical if you don't want to lose data so make sure that you add this in your db section okay so now that we have this up in here then we also need to say that this docker compose is actually dependent on some volume like we did with the networks so it will be as easy as saying volumes and then i will go here and say postgres underscore data like that and i will add the column sign because this is mandatory and now our docker compose file is ready and let's test the results in the terminal now before we really get into the terminal i just forgot that the environment variable of debug within the flask application is set to one and we probably want to change that to something that is not one because actually it is a great time to test if the connection to our postgres database will work as expected so i'm going to go to our pycharm very quickly and revert this back to zero like that because we want to test the connection to our postgres database so now i'm going to go back here and say docker compose down once again and actually i know that i used a lot of docker compose commands throughout this tutorial and i did not show you this useful command so actually if you go ahead and say docker compose dash dash help then you will get a list of all the available commands that you can use with docker compose so just know that this is a great option and you'll get a wonderful list with all the options out there so this is actually a great utility when you want to remember some command that you forgot okay so i'm going to now say again docker compose up dash dash build like the following now there's actually a great reason that i'm doing this because we want to build the postgres image now i'm also going to say here something that will look like dash d now dash d will run the composed applications in detach mode and this means that we are going to execute all three containers and then we are going to go back to our terminal session like we expected and we are not going to receive this interactive logs when we execute the command because the containers are going to run in the background so it means that we don't need to be interrupted with the logs so i'm going to say something like the following and let's wait for the results now okay so as you can see creating db web and proxy and now we are back at our terminal so now if we want to see if everything is up and running then we can say docker compose ps like that and this will display the status of all the containers that we spin up so i'm going to say enter and you can see that db is up and proxy is up and the web is up as well so now we want to test if we can again register to that website with some account because we want to test if the interaction against postgres database will work as expected so now i'm going to go back to our web browser again and i'm going to refresh this page and you can see that we got some arrows so now we can ask ourselves what we should do to figure out what the errors are so it will be as easy as going back to our terminal and say something like docker compose logs and if i press enter in here then you can see that i see each log about each application and i actually can see now the exception in the web container so i'm going to scroll down and you can see that it says in here is the running host localhost and accepting tcp ip connections on port 5432 so it means that we have a connection error and we have to figure out where it comes from so now i'm going to go back to our docker compose and i am going to make a kind reminder about what we have done to the config file when we created this nginx container so if you remember i will open the config.py in proxy and if you remember let me splint the panes in here like that okay so if you remember we use the domain name of web to actually connect the nginx to the flask application and the reason we have done that it is because we have to send the traffic coming to this nginx back to 5000 port on the host of flask and the domain name of that container of this flask host was web and its name is web because we call it web so it means that we have to refer to our database with its domain name which is db because it is just the same as we have done with this configuration file where we pointed to this domain name which is called web so now the error is actually coming from web market and config so now you can see that the host is localhost and that is incorrect because it needs to be db because this is the domain name of this database so once i will change this to the same value like this one then everything should really work so i'm going to take down everything and spin them up again okay so in the terminal as usual i'm going to first say darker compose down like that and let's wait till everything really gets down here perfect so now we should go ahead and basically bring this up again so i can say again docker compose up dash dash build and then use the detach mode so i'm going to run that and now once we got this let's test if everything works well so it will be docker compose ps and i can actually see that the db is trying to restart itself so let's try to hotfix that so i'm going to say docker compose um logs and basically let's see what is going on here and let's zoom out the log a little bit and it actually complains about the password is not specified so i probably know this issue but you can see that it asks for the postgres password environment variable and not postgres pass so i'm going to change this in the docker compose file but i'm actually not sure why this error occurs because in some cases when i passed in environment variable as equals to pat postgres pass then it worked great so i will try to go back to pycharm and change this out so i will go here and i will change this to being password like that now i'm going to be honest i'm not sure why we did see this error now but if pass doesn't work for you then just try this out with password so i'm going to save our changes and try to rebuild this one again so it will be clean screen docker compose down and i will say docker compose up build and dash d like before all right so now if we clean the screen and try to do docker compose ps then you can see that now everything works properly so again i'm not sure about the environment variable thing but i believe that this might be related to versions so sometimes try to pass in pass or password but actually it is a great idea to check this out and if i will find the answer for that then i will comment this in the comment section all right so now that we have the database spin up then let's test the results so again it will be just going to our web browser and try to see if everything functions so now if i go to here then again we see some errors but i think this should be expected because we don't have the tables of the database created yet so i assume that this is the error that is going to pop up now and i will show how to fix that as well so if i go again to docker compose logs and see the logs about web then we can see that it really complains about undefined the table so it means that we have to execute this db dot create all command that will really be responsible to create all the tables that we have defined back in the tutorial in our modules so actually to show you this up if i go to our project and visit the models.py file now i will allow myself to ignore those because it happens from the pycharm and this is not related to really syntax errors and this actually comes from this user that did not really migrate as a table and as well as this one so it means that we have to figure out how we are going to execute the database table creation commands so to do this i'm going to go to our terminal and clean the screen now i did not talk about this before but there is actually an option to execute some commands inside running containers and it will be by using the docker exec command so to do this then i'm going to bring the name of our container and i can do that by using docker compose ps so this is actually the name of our flask container and i can say now docker exit and i can do this with interactive mode so i will really kind of do like an ssh session with my container and this goes something like the following so i can say docker exec and we'd like to do this by dash dash i t so this stands for interactive mode and then i will specify that the container that i'd like to execute some commands in is actually flask market underscore web underscore one so this is exactly like this one and to actually execute in interactive commands within our containers then we have to open the bash terminal so it will be forward slash bin and forward slash bash like that and as soon as i can do this and i think this should be one dash in here so sorry about that and now if i run this then you can see that i'm totally inside a different sort of machine in quotes but i'm inside a container so now i can say something like dir for example and you can see that i see everything like in our flask project so it means that i'm inside the container now i can basically go and say here python and basically execute the commands that we used to execute in our flask tutorial to migrate the tables so it will be from market import db and now that i have done this then i can allow myself to execute db dot create all and it will go and create the tables for us so if i run that and i don't receive any errors like the following so it means that we are good so now i can exit from the python and i can actually get out from this container by writing exit again and just to verify that everything runs we can use again docker compose ps and everything is really up and running so now it is about time to test our changes one final time and it will be again by trying to create a new account because this is how the flask will try to interact with the postgres database so in our browser i can basically try to go here again and i will try to register and let's create now jsc 20 and i will use this email and let's try to also create this password and if i click on create account then you can see that now it works okay so it means that the flask application knows how to connect with the postgres database and our docker compose file is pretty much complete and now we have to kind of organize what we have to do in the destination server where we will move this project so now we only need a server with docker compose command line interface and we need to go inside the flask container and create our tables and that will be it that will be basically everything that we need to do to come up with our organized docker compose application and those steps will be something that i will be completing in the third and the last part of this tutorial all right so i know this might be a lot of information that needs to sink in so if you have any questions about this second part then feel free to ask in the comment section and i really hope that you enjoyed this part of the series as well and if you enjoyed it please hit the like button and as well as consider subscribing to my channel this will really help me to spread this video across more people alright so see you very soon in the third part of this series you
Info
Channel: JimShapedCoding
Views: 1,597
Rating: undefined out of 5
Keywords: docker, docker with python, python with docker, python docker, docker python, flask, python flask, python, docker compose, flask with docker compose, flask docker deployment, flask deployment to production
Id: vTVnAm8VNbM
Channel Id: undefined
Length: 60min 0sec (3600 seconds)
Published: Thu Mar 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.