Flask Load Balancing Using Nginx and Docker

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
imagine you have a startup and it is hosted on a single application server at the start you are not going to have tons of users but then slowly once you get tons of users there is like tons of traffic in your single server and at one point there will be some users complaining that hey your website is running really slow and like it wasn't this slow before and then when you go to check on the system resources you see that there is so much traffic coming to that single application server that it just can't handle it anymore and that's where scaling comes into play now if you've ever done you know production deployment or maybe studied web maybe started some devops and stuff you probably know what scaling is but basically this concept means that instead of having one single web server or like one single application server for your uh your startup or your application you can have multiple servers and each of those servers will basically allow like more users so that would mean that you know only there won't be like only a single server that handles all the traffic that traffic can be distributed but the thing is since each server has its own port like if the user wants to access one server they need to know the port number of that server now the issue with that is the user will not know the port number and they can't access that server so to do that that's where like load balancing comes in and the concept about load balances is that you have all of those application server maybe if your application is huge you might have you know 50 to 60 even 100 application servers and then you need some sort of master server that will intercept or like receive all of those requests and then distribute those requests to you know like all of those other application servers so like basically it just balances and distributes those requests to different application servers depending on which one has like the lowest amount of you know system resources or lowest amount sorry not system resources the lowest amount of traffic so that's basically what adult balancer does and it's really helpful when you're deploying like a really huge and enterprise level application and startup so in this video i'm going to show you how you can have a really really simple flask app and then scale that splash cap so that if there's like tons of traffic like the application server won't be overwhelmed and then we can use nginx to load balance that so that if someone hits that single domain or that single ip they will you know they will be able to access that server it's like any one of those servers that are running there so at first let's just create a folder called app and in that folder i want to create a server called wsgi.pi now the reason why i'm calling this wsgi.pi is because flask runs on wsgi the uh gateway interface i forgot what it's called actually but anyways i'm just gonna name it wsg dot pi and then i'm gonna import flask so i want this to be a really really simple you know application so we can just make a really simple application and i'm gonna show you why i am creating this application now instead of making it ready before the video so i'm just gonna you know skip on and then come back once this application is done okay so right now we have this really really simple application if i save this and go to my terminal i can just run this python uh app slash wsgi dot pi this will start running the flask application if i go to my browser and if i type localhost 5000 if i go over here you see hello there's an application sorry not applications it should be application so you see this over here now the thing that i want to do is i want to scale this application and the best practice to do something like this is to use docker and if you don't know how to use docker well i'm just going to show you how to do it is really simple you should also check out some docker tutorials so i'm just going to create a docker file here and then in the docker file i want to use python and then i want it to be 3.9 slim and then i want to set the work there to slash app and then copy everything here and then i want to install pip install everything now since we're going to be you know deploying this on production i don't want to use flask default server as you can see it says that you should not use this on production just a development server don't use it in a production environment for that we're going to be using a really really great like production web server aws yeah web server called unicorn and it is widely used with flasks you can also use um waitress or or you know like uh uwsgi but i'm a fan of unicorn so i'm gonna be using unicorn now note that unicorn doesn't run on windows but since we are using docker you know that docker runs on a linux kernel so since it's linux based um we can use unicorn so i'm going to make a requirements.txt file and in here i'm going to have flask and unicorn so once i save this i can do run and then i can do a pip install requirements.txt and once i'm done with that i want to now run the python uh sorry not python i want to run unicorn and i want to bind this to uh port 5000 of the container support 5000 and then the file will be wsgi so this will be the wsgi file over here and then the object that we have here is app so this is our wsgi object we have this here and if i stop this i can now have a docker compose which will basically run this i could just build this container from scratch but i don't want to do that so basically a docker compose is a software like it's it's like an extension to docker and it's like usually it's installed with docker by default on most windows and mac uh you know operating system on linux you probably have to install this but it's not that hard to install so basically docker compose allows you to run multiple services for a single application so i want to set a version of docker compose so version 3 and then services i want this app some of this service we call app this is our web app and then i want the build to have a context of app so this is gonna go like basically this is gonna to try and find a docker file inside this app folder and it has a docker file here now i want ports to be uh 5000 colon 5000 so basically i'm just mapping the port 5000 from the container to port 5000 on my system so now i can just do docker compose up and now it should start building the container so as you can see uh this is now running so unicorn is now running here if i go to this port here if i refresh you see this is running if i go to network if i check the headers it says service unicorn so this is not the flask development server this is the unicorn server that means this is running perfectly on a unicorn server now let us actually try to scale this by scaling i mean we want like not only one instance of this we want a multiple instance of the class application so to do that it's pretty simple i can just stop this docker container here and then i can just add a scale parameter and this will automatically like run an x amount of instances for those so i can do dash dash scale and then i need the name of the service that i want to scale so app and i want to now enter the amount of instances of app that i want i want three instances of app and also i want to do dash d because i don't want to be attached to those containers during the runtime so if we hit enter you see it's going to try this but as you can see it's going to give you this error now i knew this is going to give this error but i still did it and you see it's showing that buying for port 5000 fail port is already allocated now why are we having this issue is because for each container we are mapping the port inside that container to port 5000 on our system now if we run one container it's going to have the port 5000 but if you run another container with the same port it's going to give us an error because that port is being blocked by another container and to solve this it's really really simple we just remove this cool 5000 and just keep it 5000 like this so we can also add dash dash build here or else it will just use the same code and then it's now going to start building and we're going to have that i guess as you can see we have this over here but note that if you now try to go to localhost 5000 it's just gonna like not load here now the reason is if we run docker ps you take a look at this we have three containers running each of them are like an instance of this flash dockerflask uh tutorial thing that i made and it's running unicorn but the issue here is that each container has their own port 5000 this is not like the outside port python this is this container port 5000 but each of these port 5000 since we didn't strictly specify a port that it should be mapped to it is being mapped to this support on my host computer so like over here this one this one now if you try to go to this port on localhost see what happens so if i paste in this you see it says this is an application if i now try to paste in this here it also says this is an application now you see this is what i said before like when you have like multiple servers running the user has to arbitrarily enter those ports in order to access those servers but we want it so that if someone only visits localhost they can like access any of those servers like basically like the traffic will be distributed to any one of those idle servers or the servers with the lowest amount of traffic now this process as i've said before it's called load balancing and for load balancing we're going to be using a web server or reverse proxy also known as a load balancer called nginx now you might know nginx if you don't know well let me fill you in nginx is an amazing piece of software it can be used as a web server it can be used as a reversed proxy it can be used as a load balancer and it is awesome so what i want to do here is i want to create an nginx service so let's actually create an nginx service here service nginx and the image that i want to use is from the nginx image and i want latest so this is like the latest nginx image and for volumes so basically this nginx uh server requires a config file and we need to supply that config file on our own now let us actually create a config file and this should be called ntx.con so let's actually keep it like this and what i want to do is i want to assign this ncx.con to slash etc slash nginx nginx.com colon ro so basically this is where you want to map it to and i also need it to wait till this application starts so like the three or x amount of instances of this application starts so it depends on i want this to be app so it's going to depend on this app so it's not going to start unless this has started and the ports i want this port to be mapped to 80 colon 80. so basically what this will do is this is going to map port 80 on the on my real computer with the port 80 on that docker nginx container so this is what we're going to have here let me actually run docker compose down to stop those running containers over here until that happens let just go to the nginx.conf and now we can start off with the nginx config and what we want to do here is we want to specify a http uh sorry not http we want specifying events block and here we're going to do worker connections and set it to 1000 now worker connections is basically like it will allow you like more connections like more client connections with nginx now since you're going to be scaling your applications uh application you might have tons of users so it's always best to leave it like this so it's like a maximum amount of work connections and now we want a http block and here we want a server block and in the server block we want to listen to port 80 why 80 because we have mapped the port 80 in the container to port 80 of my host machine and here i want to use it as a reverse proxy so i want to do listen slash now this is going to listen for like the slash route so like the home route or any other route and then i want to do proxy pass and the http and then here i want to like since we don't know the ip address of the docker container the way docker discovers hosts is via the uh the name of the service and docker compose so we don't just going to enter app and then the port 5000 because the port 5000 is the one that's being mapped to that container okay so once we finish that nginx.conf we can now start up our docker containers and now it's going to start up our dark containers along with nginx and boom we have that running okay so i actually forgot that instead of using listen you need to use location here and that was the reason why my code was not working so anyways i'm going to build this again and now it should work so if we take a look at this we can go to docker ps and now you see i have multiple containers running here i also have an nginx container now if i go to my browser and then go to localhost you can see instead of using https if you go to normal localhost you see it says hello this is an application if i refresh there's like no way to know which flask server this is hitting so for that what i'm going to do is i'm going to go to my flask server and i'm going to import socket now hear me out this is the the reason why i'm importing socket is i want to access the last application's host name now in docker a container or like in docker container any application uh the host name of that container will be its container id so each container has its own id over here and if i want to you know uniquely identify each container application i can just access their host names and that's going to be the container id so i can import socket here and then over here i can do something like container id and then it can be socket.get hostname so this will return as the container id for this so i can do docker compose down right now and this should now stop all of the containers here once that is done we can now run docker compose build and this will now start to build those containers again and we will have our application running here as you can see this is now running and if we go over here if you refresh you see every time we refresh we have a different container id now if we run docker ps here you can see that the container ids that we get over here example b60 blah blah blah that is one of those applications here so you can see bs6.8844 that means when we hit refresh the application that is receiving or the flask container that is receiving the request has the corresponding id and the port it's running on is this if we refresh again as you can see you have this poor uh this id this is this container here so we can actually have like we can scale our application a lot with this we can also have like 10 servers or maybe five servers now my computer doesn't have a lot of ram so i'm going to only now run this with five servers and then you can see that it still works regardless the amount of servers you have so let's use five instead of using three and now i see it's running here so if we do a docker ps you see we have uh six containers here in total so like including the nginx we have engineering and then we have five flask containers so these are the corresponding ids if i refresh you see this is hitting this one if i refresh again this is now hitting this one now this one and now this one and then this one so every time i refresh it's going to have like its own ip address if i actually go to another one here and then another one here you can see each one of them will be like balance like you know the request or the traffic will be load balanced to a another flask server so that is like the the awesome thing about scaling a flask application and using and load balancing using anginix so i hope you enjoyed this video and if you did please subscribe to my channel and like this video i really work hard for these videos and i'd really appreciate if you guys supported me by liking this video as well as subscribing so anyways have a good one guys peace out
Info
Channel: DevGuyAhnaf
Views: 1,106
Rating: undefined out of 5
Keywords: flask, python, web dev, python web dev, python flask, web development, python website login, python oauth, devguyahnaf, ahnaf zamil, coder's system, k.m ahnaf zamil, coding, programming, python web development, python website, full stack website python, python flask website, docker, nginx, load balancing, flask load balancing, nginx load balancing, docker nginx load balancing, flask docker load balancing, flask nginx load balancing, nginx reverse proxy, flask nginx reverse proxy
Id: 42Q65H8ch7U
Channel Id: undefined
Length: 18min 38sec (1118 seconds)
Published: Sat Jul 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.