How to Dockerize Django in 5 minutes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so i've been working with django for quite a while now and one of the tools that i've consistently implemented into my projects is docker this is like many other developers that use docker and there's many reasons why you'd want to use it so hopefully in this video you'll be convinced on why you should set up docker for your project but if you're new to docker or you're new to just setting it up in a django project then this video might be useful to you basically what i wanted to do is just show you how you can set up docker really quickly using an existing project which is cookie cutter django and we're going to get into that but basically i thought i would make a video on how you can set up docker in an existing django project and actually understand enough of the docker configuration to really know what's going on and how to configure it or change it slightly in the future plus you'll come out the other side with all the benefits of actually dockerizing the django project so as i said we're going to be using cookie cutter django and if you're not familiar with this cookie cutter is basically a tool that you can use to bootstrap projects using these cookie cutters which are like templates and cookie cutter django is a specific template that you can use to bootstrap a django project and it comes with a lot of things installed for you you can configure it for docker and you can add the django rest framework you can add celery so it's really comprehensive and i really like this tool so a lot of credit needs to go to it and if you haven't used it before i do highly recommend just starting to use this project because it implements a lot of best practices and it just standardizes your workflow so you get a lot quicker and a lot better at making projects with django so i'm going to show you how we can use this project if you have an existing project and really just understand the docker configuration that this project provides you so with that said let's get started now if you prefer reading then you can go to justjango.com and on our blog we've got how to dockerize django in five minutes where you can read everything that i'm going to talk about in this video so if you prefer reading you can come over here and with that said we can get started with the video so to get started you're going to need to download docker so you can head to docker.com and you can go to products docker desktop and then download for your operating system this is a pretty big download so it'll take a while if you don't have it installed already but once you've got this downloaded you'll then be ready to go for this tutorial because you won't need it and the second thing is cookie cutter and cookie cutter django now all the links will be in the description of this video but cookie cutter django is the template whereas you're also going to need a cookie cutter itself installed and basically you can come if you scroll down in the in the docsio powered by cookie cutter if we open this up you can see here it's also another github repository and all you need to do is just install this as a python dependency so you just pip install cookie cutter and you'll have it installed and ready to go and that means you can use cookie cutter django but you can also use all the other cookie cutter templates because once you have cookie cutter installed that's really all you need so i'm going to open up vs code and i'm just going to open up a terminal here so again to start off you're going to need to make sure that you install cookie cutter this is the first package that you need so i'm going to use pop3 and that's already installed right so we don't need to worry about that and now i can use cookie cutter by running cookie cutter in the terminal and then just giving it some arguments to create the project so we'll be using cookie cutter django but before i actually dive into this i'm going to create a django project using the standard django admin start project command and that's going to play the role of our existing project so we've got a django project we've been working with it for however long and now we've decided that we want to dockerize it so what i'm going to do is first i'll change into the correct folder so that we can actually store everything and so inside this project folder i'm going to make a directory which we'll call the let's say our current project so this again this is going to act like the existing project and inside here i'm going to start with a virtual environment just called env once you have that we'll then go and activate it and we can then go install django right so the latest version right now 3.2.5 and we can then use the django admin start project command and we'll just call it let's go with current project i'll also put a dot at the end so that it's created inside that folder and i'm just going to go and open this up in vs code right so we've got current project which has current project there virtual environment right so current project just has the standard django files that we get given when we create a project so settings asgi urls etc and so what i'll do is i'll need to re activate this so let me just get to the right place and i'm going to do the initial things run the migrate command and run the run server right so we have the project running and there it is okay so this is our existing project now we could go and do whatever we want to this project right so that it's got some features and all these different packages but i'm not going to do that because it doesn't really matter at this point we just have an existing project and we want to dockerize it so how do we go about doing this now we could go through all the tutorials that we want on all the specifics of what files you need but you could also just go straight to cookie cutter and basically take all the boilerplate that comes with a generated cookie cutter project so that's what i'm going to do i'm going to create a cookie cutter project here and we'll basically compare what is given to us in that project and what would then be necessary for us to bring into our project to essentially dockerize this so i'm just going to bring up the terminal again and i'm going to deactivate the virtual environment i'll then change out of this so now i'm going to take a look at the documentation so if we scroll down here you can go to the read the docs page which has all the documentation really and you're going to click on getting up and running locally and this has all the steps that we need to follow to generate a project using cookie cutter django so first create the virtual environment activate it and then install cookie cutter django using the cookie cutter utility and passing in this github essentially a argument to cookie cutter which is telling us to use github and it's this repository that we're going to use and then install dependencies etc so let's go and create a separate virtual environment for this project i'll call it the advanced env and we can then say source advanced dnv bin and activate right so this is a separate virtual environment from the current project environment because they will have different dependencies so that's the first step we then run the cookie cutter command like so so i'll come back in run this and i've already downloaded it so i'm not going to redownload it but you'd want to make sure you're on the latest version so hit no and do you want to reuse the existing version i'm just going to say yes and so now we get prompted all these questions for how we want our project to be set up now i'm going to run through basically all the default answers so i'm not going to put my own answers except for in one place so we're going to go through all of them description author name email version of the project mit license windows i'm going to say no use python is also quite convenient if you are using pytron and then we get to use docker so here by default it's no but i'm going to press y which means i do want to use docker select postgres version and everything from this point on you can just go to defaults because it doesn't really matter you also get an option here for using django rest framework which is quite convenient and use celery which is also nice but you can see this is quite a lot so everything else is exactly as the defaults and then we get my awesome project generated from all of that so i can go and clear this out and i'll just bring it down a bit now there's quite a lot that you can go through in this folder just to understand everything but really what we're going to take a look at is the docker configuration so first we have a compose folder this compose folder is made up of a local and a production folder which is basically for the different environments that your project is going to be hosted in or running in so you have local which is for the local environment meaning your dev environment on your local machine and then the production folder which would be when you deploy this project meaning production so the compose folder is the first thing we need to take note of we then have a docker ignore file which essentially is a docker file to take note of but it's not extremely important all it really does is serve exactly the same purpose as a git ignore which means it tells what files and folders need to be removed from the docker image basically we'll get talk more on that in a second so we have this file we can then keep going down and we come to a local.yaml file now this is a very important file now this local.yaml file is called a compose file so it's used by one of the docker services which is called docker compose and in this file we configure all of the services that we want in our multi-container application so basically this is used to build multiple container applications so we have a django service we have a postgres service and we have a docs service docs meaning documentation and really it has to do with the docs folder here you can see there we're not going to pay too much attention to that because that's not that important we're mainly focused on the django stuff so we have a django service and we have a postgres service this is also really basic so if you generated your cookie cutter project with celery then you would have a bunch of other services here as well for celery redis and i believe flower as well so it's a lot more comprehensive but just to understand the basics we have these two services really and so that's the local.yaml file we then keep going down and we have a production.yaml file which is also a docker compose file but due to the naming you can basically deduce that local.yaml is used in your local environment and production.yaml is used in your production environment so they're two different files used in two different environments and so the production yaml file is a little bit more complicated you've got django service postgres service trafic which is basically a reverse proxy and a load balancer similar to nginx and then you've got redis which as i mentioned is handy if you're using celery and then you have aws cli as well so for amazon web services so these are the docker services you then get if you are in production so right now we've got a production yaml local.yaml a docker ignore file and a compose folder those are really all the files or and folders that we need to be concerned about when it comes to configuring docker in the django project so what i'm going to do just to make this easier to work through is i'm going to move these folders and files into our current project so that we're only working with one project going forward so i'm going to bring the compose folder and all of this is going to go into the the main current project folder so not the actual django settings folder so we've got compose we've got docker ignore git ignore would basically be the same so you could copy that over if you wanted as well and we're going to grab the local.yaml file again this goes into the root of the folder and the production.yaml file as well so all of that right now those are the docker configuration folders and files that we needed but the dot envs folder is also going to be necessary and this is just because it contains environment variables which is required for the docker containers to run and it's generally better practice as well so i would grab those and bring that over as well okay so closing everything yeah inside our current project we have dot envs compose current project environment folder docker ignore gitignore local and and the production yaml files at this point if you know anything about docker and you're able to get a project up and running from this point then the tldr is just these are the files and folders that you need for your configuration and all you need to do is just change the names and file paths if it doesn't add up with how your project is currently set up so that would be just going through all the files local we don't need to change there's nothing that needs to change in terms of file and folder paths but inside the compose folder we would need to change some things if we take a look inside our compose folder we have local in production and if we just go into local for now we have django and we have docs i'm not going to take a look at docs because again it's not essential right now but if we go inside the django folder we have two files a docker file and a start file notice there's no extension on that so it's just like a bash script so if we start with the docker file a docker file is used to create a set of instructions on how to build an environment that's going to be used basically for your project to run in but the point is that the environment is exactly the same every single time that it's created so that means that you could use this on a windows machine mac linux any other operating system that supports docker you can run this docker container and because it's set up exactly the same way every time you should expect that your code is being run the same and hence you shouldn't have any issues of installing it or running the code in different places so essentially what we're doing here is just defining how this image because it's basically called an image is going to be built so we specify a python version which is 3.9 slim buster this is an official docker image which is used normally when we want to work with python so we're building a python image and we can then set arguments so for example we're setting a build environment argument which is set to local we install our system dependencies so you can see running apt-get we're installing a bunch of different dependencies for python and for cyclop g2 which is necessary for the database we then copy over the requirements folder in this case because in in this configuration we start with a requirements folder and this is generally better because we split up the dependencies into different environments as well but for the sake of just keeping it simple i'm going to change this to requirements.txt so that it's only copying over the one file that we'll work with and we'll create that file actually right now so first i'll just deactivate this and i'll change into the current project activate the virtual environment and then pip freeze these requirements into requirements.txt right so there's that so we have django and that's it those little dependencies and so that is what will then be copied over the requirements.txt file and we'll later then use that file to install the dependencies so we're running this command next which creates python dependencies and sub dependency wheels now the one thing here is that it's using the build environment argument here which is set to local and we're not going to want to use that over here because we actually can just change this to be requirements.txt right so we're installing that and then from this point we set some more arguments and environment variables we set a working directory install more dependencies copy over some folders run pip install and from here we get to some of the more important stuff so this here's a copy command and it's copying over the compose production django entry point file and it's basically pasting it into this path here slash entry point so if we take a look at this this path here it's compose production so it's actually using the production folder django and then entry point so entry point is a nice little bash script which essentially has our database url which is coming from environment variables and it tries to connect to the database and it echoes which is basically like printing to the terminal waiting for postgresql to become available and then once it does connect it says postgres is available so that's what this script does and we're basically just copying it over and we make sure that it's executable then same thing here we copy over the local django start command and also make sure that's executable if we take a look at the start command it's inside the local django folder and this is what we're used to seeing when we work with django we have a migrate command and then there's this run server plus which in our case we can actually just change to run server because we don't have the run server plus package installed or the package that gives us that functionality so we're just going to go with run server and then right at the end we copy dot which means copy everything over and we set the entry point for the container which is entry point being this file here now one thing to just note is that entry points and commands so in doc you can run cmd which means command those are two ways of starting the container now the reason we're using entry point here so that it basically triggers this entry point to be run but actually the start command is the command that will be used when we start the container but essentially both of these get run but this has something to do with the docker compose configuration which we'll take a look at now so that's what the compose folder does right we have a whole bunch of configuration which is basically a docker file and some bash script to help us run everything that's necessary for django when working with docker in the local.yaml file we have all these different services and if we take a look here inside the django service there's also a bunch of different arguments but a lot of them are quite intuitive to understand so inside build we have a doc file and this points to the specific docker file that we should be using for this container so that points to compose local django dockerfile that's the file we just looked at now dockerfile and now you can see how everything is linked here the service points to a docker file and that's that docker file we can find inside the compose folder you have an image a container name what it depends on volumes environment files so here you can see there are two environment files that are loaded inside these paths right so inside the environments folder here you can see the ports which basically maps port 8000 of the container to port 8000 of the host so this this is important if you actually want to see the project running on your local host but most important here is the command so this is what i was saying about you have commands and you have entry points so the command to actually start this service or this this app is slash start so it's going to run that command which is a script inside the container and that's the script here we know it's inside the container because or inside the image because we added it here start right so it is there and it's really important to understand because the container is being run actually using docker compose and so that's how everything really pieces together when it comes to the postgres side of things it's actually a little bit simpler all we have is a dockerfile which is also found inside of here so production and then postgres and then dockerfile all right and all this does is just use the latest version of postgres so that's a very simple dockerfile and if i just bring this up again we have image container name volumes and the environment file which is using the postgres environment file and if you're wondering what's in there it's basically just everything that you need for a postgres database the host port database user and password and all of this is generated when the project is generated so it's really convenient also that means the database will be created when all the docker containers are run so you don't have to sit on your computer the correct postgres user to have the permissions which can then create the database you don't need to do any of that you just run this and it will spin up the database for you and that same database as long as you don't change any credentials that database will be used going forward which means all the data will also persist so you don't have to worry about losing the data every time you switch off docker or something and so really that's an overview of how this configuration works we have a local.yaml file which creates the services that we want and the services point to the docker files which are the images right the structures of the environments we want to create and we can take a look at all of those docker files and all the corresponding files that are necessary for the container to be run right everything is inside local and exactly the same thing applies to production if you want to look at the production services just come inside here and go to the corresponding docker file and you can break down what these services are what they depend on what the images look like and really get a good understanding of everything that's needed to run django in these docker containers so okay enough talking about how everything is set up how can we actually use this now so if you open up a terminal and you've got docker installed then you're going to have docker compose installed as well this comes when you install docker and this is a nice utility that you can use to build your images and to run your images as containers and this command will be used with local and production.yaml files basically docker compose is used to run multi-container applications and so the first thing that we need to do is provide the file that we want to work with so we do this by saying dash f and then point it to the file which in this case is local.yaml and after that we then provide it with whatever command we want to execute which in this case we want to start off with build and this is going to build the images right so it goes through the local.yaml file and it builds all those services so that's going to be the django service the postgres service and the docs service so this can take a little bit of time in our case and we might need to debug this a little bit you can see it failed here at the end because of this line and that's because we actually don't have a docs folder here so there's a couple different ways that you can handle this either you can just remove the the docs service here if you don't want it because you probably don't have a docs folder so that's what i'm going to do just to make this even simpler but you could also just copy over the docs folder from here if you did want to include that into your project and so we can then just go and try this again we can rebuild the entire image right so there we go that's that's completed and so once we have the images built we then run docker compose dash f local.yaml up and so this will basically just run those images as containers which means that there will be actual apps that have been executed and running now when i run this i get into a little bit of an issue because i already have a docker container that's in use with that name so you can see i've got a container named postgres already being used so to avoid that we can just come down here under the postgres service and here where we have container name we can just call this postgres2 right so it has a different container name now i'm going to do the same thing here for my django container here just so i don't have any conflicts so django 2 and postgres2 but you shouldn't run into this issue if we then run this command it'll then start both of those containers and we can see in this case docker needs access so i'll just click ok and there we go right so we can see some stuff is being outputted here first we have some postgres logs right so it's actually creating the database and we can see that that's fine but as we come down we can then see here no module named cyclopg2 right so what's happening here well you can see waiting for postgresql to become available so that's coming from our entry point so if we just look here at production django entry point we can see here that it echoes waiting for postgres to become available right so we're missing the postgres dependency because postgres wasn't actually installed so i'm going to ctrl c to stop that so it'll stop both of those containers and i'll just close the terminal for now and we're going to need to add postgres or rather cyclop g2 as a dependency to our requirements.txt here and we can grab that dependency from our requirements base no our local.txt so cyclopg2 that version there and i'm just gonna grab it and add it to the file here right so we absolutely need cyclop g2 as a dependency now one thing to note is that once you add a new dependency you need to rebuild your images so we need to run that build command again because we have a new dependency and the images are now needing to be updated as well so you can see here it's running through all the steps again because of that change right so that's done we can try run the containers again with the up command great so we can see all of these logs now and it seems both the services were created successfully we can see the logs here for the django 2 container which gives us those recognizable django logs now even though we can see both these services are running we still need to configure our django project to actually connect to the database so again i'm going to stop these services i'll close that and if we take a look at the generated project if we go into the config folder settings if we take a look at base dot pi you can scroll down here and see databases needs to be configured using the environment variable database url this also would mean we need to start using environment variables in our project if you're not doing this already i recommend that you do start doing it because it's just best practice but it also means that we'll need to install the dependency needed for environ and this is the django environ package django environment so we can actually just grab it and paste it straight into here and then just coming back here we'll need to grab some of the configuration so that's going to be the databases configuration as well as all of this as well as the import now the way that it reads the environment variable files will need to possibly change because it depends on the root directory so we'll just need to see but copy all of that and if we head into our current project settings right here at the top we'll then put the import we configure our environment and we read our env file we can then cut out the databases and actually go replace this entirely right so coming up top we actually can just replace router with base do so we're basically saying that if we were to create a dot env file it would be inside the root of the project just like that this becomes very handy when you want to run the project manually so not actually using docker but it's good to have this configuration anyway because when it's being used in the docker container it is going to need to read the environment variables which are specified in the dot envs folders here so again now that we've made some changes and we've added a dependency we're going to need to build this again right now that we've done that we run the up command now this time we can see something different which confirms that what we did configured the project correctly because we can see all the migrations being applied so because this is the first time the migrations are applied to the correct database we can see that they're all applied there now even though the project is running and we're not getting any kind of issues there actually is one issue at this point and i wanted to include it just so that you could see how easy it is to forget this part so right now you can see the django server is running and if i open it you can see it doesn't return a response in the browser and it's very confusing as to why this is happening but basically if we head back into our compose folder it's all inside the start bash script whenever we run the server we can actually specify the port to map this to and it's important that we do this that's why earlier on we actually saw that it had pointing to port 8000 on the local host and this is important we need to include it because by doing this we'll then actually be able to map port 8000 to port 8000 of the host and we'll actually be able to make requests to the container so because we've made this change you're going to rebuild the image but while we're doing this we can make one last change to our settings.pi and that's to specify the allowed hosts so we can take a look at the my awesome project config and then local.pi and we can see all of the allowed hosts you might as well just copy those and then go and add them into the settings inside the current project so that we absolutely will be able to access on the local host so we're going to build this again and once this is finished building we're then going to run with the up command all right we can see here that the url is actually slightly different it's on 0.0.0 but it's still localhost and if you click to bring this into the browser you can see that it works and actually this on the localhost also works as well so just refreshed by itself so now you can see that the django project has been dockerized and at this point we've made quite a few changes to the current project we had to install postgres we had to install the django environ project so that we could work with environment variables but there's still quite a few things that you'd need to do if you want to get all the best practices alongside the dockerizing because we only have one settings file we could split that up into a local and a production we only have one requirements.txt file we could also split that up into a requirements folder like we saw in this configuration of a django project and really you just want to tend towards the setup that is provided in the cookie cutter django project and it's just because it has a lot of the best practices implemented there'd still be some work to do in terms of improving the configuration here but overall we have docker setup and that was the point of this tutorial just to show you how you can get docker configured now even though this video took much longer than five minutes if you're doing this by yourself and you need to dockerize a project and you don't need to explain it to anybody then you can actually dockerize the project relatively quickly just by looking at the configuration from a cookie cutter django project so if you enjoyed this video then consider liking it and subscribing to the channel and other than that thanks for watching and i'll see you in the next video [Music] mmm [Music]
Info
Channel: JustDjango
Views: 7,353
Rating: undefined out of 5
Keywords: django docker tutorial, dockerize django, dockerize 5 minutes, django tutorial, django, docker, cookiecutter, cookiecutter django
Id: 8c14GBrbglw
Channel Id: undefined
Length: 35min 59sec (2159 seconds)
Published: Tue Jul 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.