Containerizing Python web apps with Docker, Flask, Nginx & uWSGI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up everyone Julian here hope you all goods and welcome to this introductory video to working with - and docker so if you never worked with docker or docker compose before then don't worry I'm going to do my best to explain some of the concepts and principles as we go I'm gonna be building a very simple flask web application which we're going to run in its own container I'm also gonna run nginx in its own container and we're going to do all sorts of interesting things to get them talking to each other and it's actually really quite simple so if you if you want to follow along and then you're going to need to install docker and if you're on Windows or Mac it's super simple it's literally like a one-click install so after I link to this in the docs or in the description below and also you're going to need docker compose installed as well which again I will link in the description so docker as I'm sure you're probably aware is any containerization technology it allows us to create containers from images and you know an image is something like the Python image or the nginx image and you can read more about images just have a read through the docker documentation here and docker compose is a tool that lets us kind of orchestrate things and define our services and connect them together and set things like environment variables and connecting volumes and connecting our containers together or from one file and that's the block of compose Bowl and you guys will see that in action shortly and docker compose you know you don't have to use docker compose to work with docker it's just a really nice tool to be able to write everything in a single file and use some deep docker compose commands so I go ahead and make sure you've got these both installed and I will throw a link to the text-based version of this guide in the description too so let's go ahead and get started so I'm here in a directory that I've just created called flask app and you don't have to use fossick for this you could use Django you could use pylons you could use pyramids you could use quartz any kind of web framework in fact you don't even have to use that tool you could build your own but you know he wants to do that so let's go ahead and get started so here first thing I'm gonna create is a new folder called flask and I'm gonna create a new folder here called nginx and what I'd like to do is create a individual directory for the individual containers that we want to run so in this case we're just running to but you know if you had a database you might want to create a new one here called something like or sequel or Postgres whatever so we're not going to be using a database in this one we're just gonna have two containers so nginx is just going to be an engine X container which is going to be the entry point of our application so requests will come into the nginx container and then they will be proxied to our flask container which will contain our flask application and you whiskey and you whiskey if you've never used it for it and it's actually a massive project but we can use you whisky as an application server so let's start with our Floss container so each container needs to have its own docker file so I'm going to create a new file here called docker file and the docker file is the file that docker will use to actually build the container and the docker file is just a list of instructions of how to build the container and we're going to come back to this file later so let's start out by actually building our flask application so in the terminal I'm going to see the two flasks and what we're going to do is literally just build a very simple flask at like you would normally you know outside of a container and we're going to you know create virtual environment we're going to pick and store some packages and we're going to run it using the flask development server so let's go ahead and - - and the env env to create our virtual environment you can see we created a environment here called n and once that's done we're going to go ahead and activate it so source and then activate and there we go so the first thing we want to do is of course install a nice tool pip pip install flask and you WSGI so go ahead and let them install okay so if we do a quick pit list you can see there we've got flask we've got you risky and got a couple more packages too so the next thing we're going to do is build out our actual application structure so again in the flash directories will create a new file here called run PI that's going to be the entry point to our application again like I said if you're using Django then you just want to have the entry point to your application in this directory somewhere will then create a new folder I'm going to call it app and this is going to be our actual app flask application itself new file very cool dunder init dot pry and then one more file called use by so let's start without in it so this is where we're gonna actually create our flask out so from flask import flask app equals flask done that name and then we need to import our do so from app import views okay that's everything for out in it let's jump into run pi so from our app module that which is crated import the app object that we just created and then if Thunder 9 is equal to Thunder main we'll go ahead and call app run okay so the last thing we need to do is create some views so from app import and then we use the app root decorator root we just set it to the index def index return hello from flask okay so that's everything for our floss app for now like I said super simple I just want to show you guys how to get up and running with docker and dr. compose okay so that's everything for our app we need to generate a requirement txt file so we do that with pip let me just clear the terminal pip freeze right arrow requirements dot txt and there we go we've got our requirements file okay so the only other files that I want to create in our flash directory here are a docker ignore file and a docker ignore works very similar to a git ignore so we could just call it dot docker ignore and what this is going to do is just tell docker to ignore any file or directory names that we put in here now I don't want our virtual environment being copied into our container so I'm going to go ahead and just put in N and also if we we don't have any cached - files but I know that we both so buy cash as well so that's everything for our docker ignore again what this is going to do is just gonna ignore any files or directories found in here and it's not going to copy them into how container so that brings us to docker file and again this is going to contain a list of instructions for docker to actually execute to build our container so I'm just going to copy this in because I want to keep this relatively quick so first things we want to do it is cool from and if you're using vs code then I think there's some kind of docker extension if I miss something out there there we go so we use the from keyword here and we give it an image and what that's going to do is it's going to create the container using a image that we provided and in this case as is python 3 dot 7.2 - stretch so you can find all of these different types of images over at the docker hub so just go ahead and search if you don't want to use this particular image of course there's absolutely loads that you can choose from so the next thing we're doing is the workday and what this is going to do is if we hover over it we can see it's going to set the working directory for any subsequent add copy command entry point or run instructions so we're going to set the working directory here in our container as slash app so there's gonna be at the root of our container we're then going to copy any files in dot and dot will use dot because it's a relative path to the docker file so that means that any files in this directory are going to be copied in to slash in our container we're then going to go ahead and cool a run command so you can see here execute any commands on top of the current image so we're going to go ahead and pip install - our requirements dot txt so that's going to install our Python packages and then finally we're calling command and providing copy Bhagyam - we've got you whiskey and I annoy and in fact we need to create our app tonight let's go ahead and create that now new file app dot finally and again I'm just going to copy in what I've already written here save that and I won't go through everything here but whiskey file is run PI and that's because run dot PI contains our callable which is app so again if we have a quick look at roundup PI we can see here we've got our app object we're going to be listening to any requests coming in on port 8080 and I'll explain more about why we're setting this up later but for now just know that you whiskey is going to be listening on port 8080 for any incoming requests we then got a couple more things processed threads etc but we don't need to worry too much about them so that's everything for our flask application we need to test our app locally so let's just see where we are so we are currently in a flask so let's go ahead and export flask at equals run dot PI export flask and equals development and we'll go ahead and call flask then over in the browser if we come to our development server port 5000 there we go we get hello from flask okay cool so rap is working in the development server and of course this is where you would normally just go ahead and build out your application so it's jump back in here and let's move on to our nginx container so I'm going to create a new file again we need a docker file because each container needs its own docker file and we're gonna create another file as well just called nginx dot-com and that's going to contain some custom configuration for engine X so let's start with the engine ex-con so again I'm just going to copy and paste in what we've got so just like you would normally set up a server block on nginx we we're telling it to listen on port 80 and then we've got this location here and it's going to include the new whiskey params so just like you would on a virtual machine because we're running u whiskey and the important thing to note here is this and it's the new whiskey pass and then we got it set to flask colon 8080 so what this means is that docker when we use docker compose it creates a network and that network allows our containers to communicate freely with each other if we name our containers so we named our flask container flask and our engine can nginx container nginx then those names actually become the host names of their respective containers so this flask container will be called flask and nginx will be called nginx and because they're translates to a hostname we can use the host name here directly in our in our containers so for example here we want to proxy any incoming requests to our flask container on port 8080 so we can literally just use the flask name here and because that's going to be set as a hostname we don't need to do anything else we can just pass it the port that we want to do proxy the requests to so that's why using docker compose is really nice because we can just do it all from one file we can create a name for the container and that's going to create a network which freely allows our containers to communicate with each other so that's pretty cool so that's what we're doing for our nginx comp and if you watch the last video on deploying a flask app to a virtual machine you might remember that we did something along the lines of rather than flask 8080 we had a path to a socket that we created in our I&I file so that's how we can use the names of the container as host names and that's what we're doing here in our nginx Khan so let's come back to our docker file so what do we want to do what instructions do we want to give docker to build our container well we want to use the official nginx image so again we'll just use from in genetics and that's going to pull the image down and create the container using that image we're then going to go ahead and call a run command and what we're going to do is remove the default configuration that comes with this nginx image and then what we're going to do is go ahead and copy our own nginx comp that we just created and we're going to place that in this directory here on our container so that's going to again just copy in this server rock into our into the config of the container so it's quite a simple dockerfile hip for nginx and that's going to finish up everything to here for our nginx container so let's move on let's go ahead and actually create our docker compose file so we do that here in the base of our application so new file docker - compose dot white and L so the docker compose file is what we use to define our services and link them together and do things I expose ports and you know we can we can do so much stuff in docker compose we're just going to be doing a very simple example so I'm going to copy in a taco verbose valve and I'm gonna get rid of all of these comments just so you guys can see what's going on okay so here's our docker compose so let's go through quickly and take a look at what we've got so every docker compose needs to start with a version followed by this services block and then inside of services are all of the individual services that we want to build so we see here we've got flask and we've got nginx and the first argument i've got here is a build or the first instruction and what this is going to do is actually build the container itself so we're giving it a path here a relative path to flask so what this is going to do it's going to follow this path and look for a docker file and we can see here flask contains out of docker file and obviously the docker file like explained contains the instructions of how to build that image so build is going to just build the image following a path that you give it and it's going to find the docker file in there and we've got the same for our nginx course that's just got a doc file inside so we're telling it to build the docker file inside of this nginx directory and we use this dot because it is a relative path we give the containers a name so here we called it floss and hit record it nginx we tell it to always restart up here in floss we've got this environment and what this allows us to do is set any environment variables that we want to pass to the container so here you do we've just got app name equals my flask app but you could do anything here you could you know set DB username equals example and you're going to be able to access these environment variables from the container now the next one is exposed and what expose allows us to do is expose ports on the container but only to internal services and other containers on the same network so exposed isn't going to actually expose imports to the outside world it's purely to explode Forks to other containers and other services on the same network and because we've got our you whisky hit set to listen on port 8080 for any incoming requests we want to go ahead and expose that port on our container so let's take a look at nginx so again we've got everything the same build contain the name and restart always the only difference between the two is the ports and the expose so what ports does is allow us to map ports on the host machine to the container itself so in fact is the host followed by the container so here we're mapping port 80 on the container to port 80 on the host machine so what this means is that a request is going to come in from the side weld to Paul 80 on the post machine on your web server or on any kind of machine that you're running this application on that is then going to be passed to port 80 here on our nginx container and because in our nginx config we're listening here on port 80 this is going to fire up and then proxy that request to our flask container which is then going to have a new whiskey listening there on port 8080 it's going to fire up our app and return a response so that's how we can work with ports so that's everything for our dr. compotes now like I said this is a really quite a basic example there's so many things that we can do here let's go ahead and actually build our containers and we can do that with the clock of compose come on so if we do docker compose should give us a big list of different commands that we can use so we've got build we've got create we've got down we've got Zak we've got kill logs all of these different commands that we can use with docker compose so I definitely recommend having a read-through dogs but to get up and running we're going to go ahead and run docker - compose build what this is going to do is just build our containers you can see here it's running and pip install it's pulled the image it's changed the working directory it's copied everything to the container it's gone ahead and run pip install requirements dot txt we can see that's downloaded then we get messages and successfully built our containers you know and then it's start to build nginx so there we go we can see both containers have been successfully built so how do we find the containers while we do docker - compose up and that's going to go ahead and actually create and start containers so we can see here we get a bit of debug information from you whiskey so that's up and running so if we come to the browser now and we don't need to go to the port 5000 we can just go to our localhost we can see here we're up and running our container is running and if we refresh we can see we're getting some output here in our terminal so that's how you build and launch or start a container all containers using a dolphin pose so running those commands it's gone ahead and built everything here in our docker compose file so what about if we want to make some changes to our app so let's come to our app there's got a views and let's just say hello in flask in a container if we go ahead and save that and rerun we can see nothing's changed and that's because we've already built the containers we've already copied in our code to the container so it's not going to change so what we need to do is go ahead and ctrl C to stop the containers oh come on that we can use is doc OH - compose up - - build and what this you can do it's just going to rebuild the containers so it's just going to run through the docker compose which is then going to look at the daka files it's going to carry out those instructions that we've provided and it's going to rebuild the containers and start them so we let this do its thing and then we should be able to come back to our browser and there we go we can see our changes so obviously you won't want to do this when you're actually developing your app you wouldn't want to keep running it stopping at making changes and re running docker that's where you would just use the local flash development server and start your floss gap with flask run like you normally would so that's pretty much everything about I think I want to cover in this video so we can another command we can use is docker - compose down and what that's going to do is just going to remove the containers and the network so if you want to kind of pull everything down stop everything clear everything out you can do so I definitely recommend having a read through the doctor compose documentation so like I said I do have a text-based version of this tutorial the link is in the description below just make sure you've got docker and docker compose installed and you should be able to follow along just fine and should be able to get something up and running very similar to what we've done in this example so I hope you guys enjoyed the video I hope you found it useful if you've got any questions or comments do leave them below if you enjoyed the video then do feel free to like and subscribe it lets me know that you guys are enjoying these videos and finding them useful so thank you very much for watching and I will see you in the next one
Info
Channel: Julian Nash
Views: 132,891
Rating: undefined out of 5
Keywords: python, programming, tutorials, guides, flask, docker, docker compose, nginx, uwsgi
Id: dVEjSmKFUVI
Channel Id: undefined
Length: 25min 37sec (1537 seconds)
Published: Thu Mar 28 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.