DEV Community

Cover image for How to Deploy A Django Project
Eric Hu
Eric Hu

Posted on • Updated on • Originally published at techjblog.com

How to Deploy A Django Project

This post is first published at https://www.techjblog.com/index.php/2020/07/how-to-deploy-a-django-project/

In the Django Tutorial for Beginners, we talked about how to deploy a Django project using a server management panel. But, since the "Python Manager" is still under development, sometimes it doesn't work. In this article, we'll talk about how to deploy a Django project manually with uWSGI and Nginx, and we'll use CentOS 8 as an example.

Install VirtualEnv and VirtualEnvWrapper

Since different Python projects have different requirements, we will be installing our Django project in an isolated virtual environment. To do that, we need to install two packages, virtualenv and virtualenvwrapper. virtualenv can create a Python virtual environment for our project, and virtualenvwrapper can add some usability improvements to the virtualenv workflow.

CentOS should already have Python 3 and pip3 installed, so just type:

sudo pip3 install virtualenv virtualenvwrapper
Enter fullscreen mode Exit fullscreen mode

Clone Django Project Using Git

Git is an open-source version control software that can track the changes in the source code. It is designed for coordinating work among programmers.

Assuming you already know how to use Git to clone a project, if not, here is a cheat sheet that can help you. But first, we need to install Git on our server:

sudo yum install git
Enter fullscreen mode Exit fullscreen mode

And then, go to the home directory, and clone our project from Github onto the server.

cd /
git clone https://your/repository/url/Django_Blog
Enter fullscreen mode Exit fullscreen mode

This command will create a Django_Blog directory and put our project in it. Next time, when we make changes to our project, instead of uploading the entire project again, we only need to run the git pull command.

Create Virtual Environment & Install Requirements

Now that we have installed the Python virtual environment tools and cloned our project, we need to create an isolated virtual environment in our project directory.

Go to Django_Blog directory:

cd Django_Blog
Enter fullscreen mode Exit fullscreen mode

Create a virtual environment:

virtualenv venv
Enter fullscreen mode Exit fullscreen mode

This will create a virtual environment in the directory named venv, and install Python and pip in it. After this, all we need to do is activate the virtual environment and install all the requirements for this project.

Remember, if you install required packages without activating the virtual environment, the packages will be installed globally, instead of in the virtual environment we just created, which is isolated for our Django project.

Activate virtual environment:

source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Deactivate virtual environment:

deactivate
Enter fullscreen mode Exit fullscreen mode

Install requirements:

pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Install uWSGI

uWSGI is a software application that "aims at developing a full stack for building hosting services". It is named after the Web Server Gateway Interface (WSGI), which was the first plugin supported by the project.

uWSGI is often used for serving Python web applications in conjunction with web servers such as Cherokee and Nginx, which offer direct support for uWSGI's native uWSGI protocol.

Before we can install uWSGI, we need to first install the Python development package.

sudo yum groupinstall "Development Tools"
sudo yum install python-devel
Enter fullscreen mode Exit fullscreen mode

Next, install the latest stable version of uWSGI:

pip install uwsgi
Enter fullscreen mode Exit fullscreen mode

Test Your Django Project

Now, we can test our Django project with uWSGI. First make sure our site actually works:

python manage.py runserver 0.0.0.0:8000
Enter fullscreen mode Exit fullscreen mode

And if that works, run it using uWSGI:

uwsgi --http :8000 --module django_blog.wsgi
Enter fullscreen mode Exit fullscreen mode

module mysite.wsgi: load the specified wsgi module.

Point your browser at the server; if the site appears, it means uWSGI is able to serve your Django application from your virtualenv, and this stack operates correctly:

the web client <-> uWSGI <-> Django
Enter fullscreen mode Exit fullscreen mode

Now normally we won’t have the browser speaking directly to uWSGI. That’s a job for the webserver, which will act as a go-between.

Install Nginx

Nginx is an open-source high-performance web server. Comparing to Apache, it is much more flexible and lightweight.

First, we need to add Nginx repository:

sudo yum install epel-release
Enter fullscreen mode Exit fullscreen mode

Install Nginx using yum command:

sudo yum install nginx
Enter fullscreen mode Exit fullscreen mode

After this, we can start the Nginx server by typing:

sudo systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

Now we need to check if the Nginx server is working properly by visiting it in a web browser on port 80. You should get a message from Nginx: “Welcome to Nginx!”. If not, it is probably because something else is running on port 80, and you need to reconfigure Nginx to serve on a different port. For this tutorial, we'll use port 8000.

Configure Nginx for Your Site

To configure Nginx to work for our Django site, we need to use the uwsgi_params file, which is available in the nginx directory of the uWSGI distribution, or from https://github.com/nginx/nginx/blob/master/conf/uwsgi_params.

We need to copy this file to the Django project directory, and later we'll need to tell Nginx to refer to it.

Now create a file called django_blog_nginx.conf in the /etc/nginx/sites-available/ directory, and put this in it:

# django_blog_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name example.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    location /media  {
        alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /path/to/your/mysite/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
    }
}
Enter fullscreen mode Exit fullscreen mode

This configuration file tells Nginx to serve the site on port 8000. Nginx will handle the static file and media files, as well as request that require Django's intervention. For a large project, it is always better to let one server handel static/media files, and another to handle Django applications. But for now, this is all we need to do.

Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:

sudo ln -s /etc/nginx/sites-available/django_blog_nginx.conf /etc/nginx/sites-enabled/
Enter fullscreen mode Exit fullscreen mode

Deploy Static Files

Before running Nginx, we have to collect all Django static files in the static folder. First of all, we have to edit Django_Blog/settings.py adding:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Enter fullscreen mode Exit fullscreen mode

and then run

python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

Test Nginx Server

Since we made changes to the Nginx server configuration, we need to restart the server so that these changes can take effect:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Upload a new image (media.png) to the /media directory, can then visit http://yourdomain.com:8000/media/media.png in the browser to see if Nginx is serving the media files correctly. If it doesn't work, try stopping and starting the Nginx server again. This will inform you if there is a problem and where it is.

Run the Django Application with Nginx and uWSGI

Now that we have uWSGI and Nginx properly installed and configured, we can run out Django application with them:

uwsgi --socket django_blog.sock --module django_blog.wsgi --chmod-socket=664
Enter fullscreen mode Exit fullscreen mode

Configuring uWSGI to run with a .ini file

We can put the same options that we used with uWSGI into a file, and then ask uWSGI to run with that file. It makes it easier to manage configurations.

Create a file called django_blog_uwsgi.ini:

# django_blog_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /path/to/your/project
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
home            = /path/to/virtualenv

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /path/to/your/project/mysite.sock
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true
Enter fullscreen mode Exit fullscreen mode

And run uwsgi using this file:

uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file
Enter fullscreen mode Exit fullscreen mode

Install uWSGI System-Wide

So far, uWSGI is only installed in our virtual environment, and we’ll need it installed system-wide for deployment purposes.

Deactivate your virtualenv:

deactivate
Enter fullscreen mode Exit fullscreen mode

and install uWSGI system-wide:

sudo pip3 install uwsgi
Enter fullscreen mode Exit fullscreen mode

The uWSGI wiki describes several installation procedures. Before installing uWSGI system-wide, it’s worth considering which version to choose and the most appropriate way of installing it.

Check again that we can still run uWSGI just like we did before:

uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file
Enter fullscreen mode Exit fullscreen mode

Related Articles

Django Tutorial For Beginners

Some Useful Tools For Web Development Using Python

Laravel Tutorial For Beginners

Discussion (0)