Deploying Django with Docker Compose, Gunicorn and Nginx

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Any reason to use Gunicorn over uWSGI or the other way around?

👍︎︎ 1 👤︎︎ u/trybik 📅︎︎ Nov 20 2020 🗫︎ replies

Thank you so much for this! I've been building something similar with this same exact stack.

I have zero knowledge on nginx so I just copied yours (and so far it works).

May I have a question, though?

I only have one static file which is main.css and it is located in /mydjangoapp/static/

The application works just fine when I run via python manage.py runserver but using docker-compose up --build, the main.css does not load. The terminal says:

web_1    | Not Found: /static/main.css

What do I need to change to fix this?

I tried changing the yaml file to have static: /mydjangoapp/static but it didn't work. I also have no idea how to configure the nginx conf file.

For reference, if I do docker exec -it container-name ls, the directory /mydjangoapp/static/ is existing.

👍︎︎ 1 👤︎︎ u/tagapagtuos 📅︎︎ Nov 20 2020 🗫︎ replies

Thanks for the tutorial!

👍︎︎ 1 👤︎︎ u/strijdernl 📅︎︎ Nov 20 2020 🗫︎ replies

thanks for much awaited tutorial <3

👍︎︎ 1 👤︎︎ u/Next_Concert1122 📅︎︎ Nov 20 2020 🗫︎ replies
Captions
hi guys in this video we will create a darker container that runs the django app with g-unicorn we will also create a container that runs nginx which will be listening to the g-unicorn container g-unicorn would listen at port 8000 and nginx at port 80. both containers will have access to a shared volume which contains these static files however g unicorn cannot serve static files so nginx will be the point of contact with the user request and nginx will serve the static files as well as proxy with the unicorn container and here is my django project it's a very simple one i just started a fresh project with django admin and this is where it's sitting in a django docker compose directory so the first thing i'm gonna do is create a file called requirements.txt and this is going to have the requirements for my django project and the requirements are django and unicorn so i'm going to save this and the next thing i'm going to do is create the docker file and this docker file belongs to or creates the image for running the django project so it's going to start by using the base image which is the python alpine image so i'm going to start by using the 3.8.5 one and it's the alpine one the next thing i'm gonna do is run or upgrade pip so i'm gonna say upgrade pip and then i will copy the requirements file over here and then i'm just going to install the requirements using pip so pip install requirements.txt now the next thing i'm going to do is i'm going to copy the content of my django project and for that i'm also going to be using copy searching django project and i'm gonna copy it to a directory called up and then i'm going to declare that my work directory is slash up and the last thing i'll do is uh copy a script which i'll create shortly and this script is the entry point so the script is is called entry point dot shell and i'm gonna copy it over and then i'm going to use entry point and just execute that script so whenever the container starts the script execution is the last thing that happens and let's save this and actually create the entry point file so i'm gonna save this as entry point dot shell and in there i'm just going to first declare that it is going to be using the shell executable and so the first thing i'm going to do is just migrate the database and it's going to be a very simple script basically the steps that you take to run your django project so i'm gonna say python manage.pi and then migrate as i said it's a very simple project and it doesn't really have any i don't i don't really have anything added to it so i'm just gonna do a migration and i'm just gonna say no input and then the next thing i'm going to do is i'm going to use also manage.pi collect static and what this does is basically collect all the static files that are needed up to this point inside the volume which we're gonna create shortly so um we're gonna notice this by looking at the slash admin page of the django project and you can tell that the static files are being served now the last thing i'm going to do is run the django server and instead of using python manage.pyron server i'm just going to say g unicorn django project dot whisky and then application and then i'm just gonna point it at port 8000 so i'm going to go ahead and save this and then i will create the docker compose file now i'm going to start creating it and i'm just going to create it in the root directory so i'm going to call it docker compose.yaml and then there i'm going to define the services that compose is going to run so first we'll start the version of dockercompose which is 3.7 and then i'll define the services now the first thing is the docker container which has our django project in it so i'm going to call this django g unicorn and this one has a build which has a context so the context is going to be the current directory it also uses ports so those ports are as we said are going to be just the port 8000 so it's going to be running at port 8 000. now i'm going to also define volumes because we said we're going to be using a volume and i'm just going to call it static and so this g unicorn or anjango container is going to have a volume and it's going to be using the static volume and it's going to be mapping to the slash static directory and the container i'm also going to define and file and this is going to have environment variables for our django container which i will show you shortly so it's going to be called dot and now this has some secrets in it so it's pattern well it's advised not to be put under version control so this is our first service which is the django container i will then create the dot and file in the root directory so it's called dot and and then there i'm going to put two variables for now the secret key and the debug mode so i'm gonna save this and then i'm gonna go into my django project into the settings file and then i'm going to comment this part out and command the secret key out and command the debug flag so for the secret key i'm just gonna say oh ask dot get and and then it's going to get the secret key environment variable same for the bug so the bug is os get on the book i'm also going to change the allowed hosts so i'm going to save this i will also scroll to the bottom and define so the static url is defined i'm going to also define the static route and it's also going to be static and now that we have things ready for the django docker container we're gonna create the configs for the androidx docker container and so in the root directory i'm going to create a folder called engine x and in that folder i'm going to create two files the first one is the docker file for that image from which i'm gonna spin out the container and then the second one is called default.conf which is the configuration for nginx now the default.conf is going to have some things in it that would allow the nginx to act as a proxy for the g unicorn container so i'm going to use upstream and i'm going to give it the django name and then i'm going to define one server and this one is the service from the docker compose so if i go to docker compose over here it's the django unicorn container so i'm going to give it that name so my g unicorn container is running at port 8000 so this is the server i want nginx to proxy for and the reason i can use the name here is because docker compose creates a network for all the containers that it runs as services and it can recognize it using the name if you were running it with docker on its own you need to use the internal ip of the container so just be aware of that then i will start by defining the port that nginx is going to listen on which is 80 and don't forget the semi columns and then i'm gonna say location slash so if um there's a request that is for the proxy for sorry for the g unicorn container then proxy pass and then it's going to go to http and then my django server and then if there is a request for which starts with static or chat static then it's going to be dealing with my volume so they're going to be served by anginax now i'm going to save this and then i'm going to go to the docker file for enginex i'm just going to close some things over here so this is the docker file for nginx and the base image is going to be nginx 1.19 and it's the alpine image and what is gonna happen is just one simple thing which is copy the uh the default.conf file in the current directory to slash etc slash engine x const.t and then default.conf so i'm going to replace the default conf of nginx by my own default conf that we just defined over there and then go back to the docker compose file and create the service for android x so under here i'm gonna say engine x now the build is going to be in the current directory and the andronex folder it's also going to be using the same volume that the unicorn service is using so that one is static and it also uses the slash static maps to the slash static and it's going to be listening at port 80 for both the host and the container and this one depends on the django unicorn service so i'm going to save this i'll then go back to terminal and in my root directory i'm going to use docker compose to bring the services up so if you want to use hyphen d it will do that in the background and if you want you can use the build option and you can see how it builds it so it's it's going to be very quick because i already built the images but here you can see it's running through the docker files and creating our g unicorn container as well as the enginex container and now that they are running i'm going to go to my browser and just type my localhost and here you can see that it is running to see that to make sure that the static files are being served you can see here you have the styling for the admin page now this is at port 80 so this is dealing with nginx if i want to see it dealing with g unicorn here g unicorn is there as well but it's not serving the static files and you can see that because the style does not get loaded over here so let's inspect what networks we have if i list the networks you can see here a docker compose has created the network for our services also if we list the volumes you can see there is a volume over here which is static for our docker compose directory so if i inspect this volume you can see here the information for this volume now if i want to see what's in this mount point of the volume you can see that there is the admin directory which has all the css the js and other static files that are being served from that volume now next you can do docker compose down to bring the services down and to get rid of the volume you can say docker volume prune and then it will prune the volumes that were not used but before you do that you probably want to get rid of the images because they are still being used so if i do darker remove image and if i remove this image as well and then if i say darker volume prune so get get rid of the volumes that are not being used you can see here it got rid of it so if i say docker volume list there are no volumes at the moment so i hope this was helpful i'm going to link in the description to my code on github and i'm also going to link to a lot of resources that i hope will be useful for you
Info
Channel: Dot JA
Views: 22,658
Rating: undefined out of 5
Keywords: django, deploy, docker, dockercompose, gunicorn, nginx
Id: vJAfq6Ku4cI
Channel Id: undefined
Length: 15min 59sec (959 seconds)
Published: Thu Nov 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.