Skip to content

Instantly share code, notes, and snippets.

@ErxrilOwl
Last active March 4, 2024 00:03
Show Gist options
  • Save ErxrilOwl/e40d6d53aa53817dbb040079c995a5e1 to your computer and use it in GitHub Desktop.
Save ErxrilOwl/e40d6d53aa53817dbb040079c995a5e1 to your computer and use it in GitHub Desktop.
Deploying Django Application with uWSGI/NGINX (Ubuntu 16.04)

Deploying Django Application with uWSGI and NGINX on Ubuntu 16.04

Reference Link

If deploying on AWS EC2 Instance make sure to add inbound rules HTTP/HTTPS on security group

Connect to server instance via SSH

ssh -i <filename.pem> ubuntu@<public_ip>

Install and Configure VirtualEnv and VirtualEnvWrapper

Update and install pip

  • For Python2
sudo apt-get update
sudo apt-get install python-pip
  • For Python3
sudo apt-get update
sudo apt-get install python3-pip

Install virtualenv and virtualenvwrapper

  • For Python2
sudo -H pip install --upgrade pip
sudo -H pip install virtualenv virtualenvwrapper
  • For Python3
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv virtualenvwrapper

Configure shell to work with virtualenvwrapper script. After running the scripts it will create a directory called Env

  • For Python3
echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
  • Run the next commands regardless of your python version
echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
source ~/.bashrc

Create virtual environment and install Django

mkvirtualenv <project_name>
pip install django // or pip3

Clone Django Project

git clone <project_git_url>

Basic Django Setup

  • Go to your project directory
cd <project>
  • If you have a requirements file install it using
pip install -r requirements.txt
  • If you come across with error with mysqlclient saying Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-7SrToZ/gitsome/. Try the following:
sudo apt-get install mysql-server
sudo apt-get install libmysqlclient-dev
sudo apt-get install libmariadbclient-dev
  • Migrate and create superuser if need
python3 manage.py migrate // or just python
python3 manage.py createsuperuser
  • Update the settings.py
vim <project_name>/settings.py

Change ALLOWED_HOSTS with your ip or domain

# Add the domain name(s) and IP addresses of your Django server
ALLOWED_HOSTS = [ 'example.com', '123.456.78.9]

Configure a directory which will hold your static files. In the same file settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

Save and close the file and collect your site's static files using

python3 manage.py collectstatic
  • Now open a port so that you can access your Django project on the server. Allow using UFW firewall enabled
sudo ufw allow 8080
  • Test and serve your django project by running the following command and visiting your website in the browser.
python3 manage.py runserver 0.0.0.0:8080
  • If you have a second project go throught the steps again starting with Create virtual environment and install Django

Working on different project

To work on different project using workon <project_name> to change the running virtual environment. But remember you should first deactivate it.

Set up uWSGI Application Server

Get the development files by running the ff commands

  • If you are using Python2
sudo apt-get install python-dev
  • If you are using Python3
sudo apt-get install python3-dev

Install uWSGI

  • If you are using Python2
sudo -H pip install uwsgi
  • If you are using Python3
sudo -H pip3 install uwsgi

Test your application by running and visit your site in the browser.

uwsgi --http :8080 --home /home/ubuntu/Env/<project_name> --chdir /home/ubuntu/<project_name> -w <project_name>.wsgi

Create configuration files

  • Create a directory that will hold your config files.
sudo mkdir -p /etc/uwsgi/sites
  • Create configuration file with .ini type for simplicity.
sudo vim /etc/uwsgi/sites/<project_name>.ini
  • Edit the file with the following configuration
[uwsgi]
project = <project_name>
uid = ubuntu
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

If you have another site copy it using

sudo cp /etc/uwsgi/sites/<project_name>.ini /etc/uwsgi/sites/<other_project_name>.ini

Create a systemd Unit File for uWSGI

Create using the following command

sudo vim /etc/systemd/system/uwsgi.service

Edit the file with the following configuration

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown ubuntu:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

Install and Configure Nginx as a Reverse Proxy

  • Install NGINX
sudo apt-get install nginx
  • Create and edit block configuration file
sudo nano /etc/nginx/sites-available/<project_name>
server {
    listen 80;
    # Use your domain or ip
    # server_name domain.com;
    server_name 123.456.78.9

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/ubuntu/<project_name>;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/<project_name>.sock;
    }
}

Copy the block config file if you have a second project

sudo cp /etc/nginx/sites-available/<project_name> /etc/nginx/sites-available/<other_project_name>
  • Create a link for your project
sudo ln -s /etc/nginx/sites-available/<project_name> /etc/nginx/sites-enabled
  • Check config syntax
sudo nginx -t
  • Restart NGINX
sudo systemctl restart nginx
  • Start uWSGI
sudo systemctl start uwsgi
  • Delete the UFW rule to port 8080 and instead allow access to our Nginx server
sudo ufw delete allow 8080
sudo ufw allow 'Nginx Full'
  • If this goes well, you can enable both of the services to start automatically at boot by typing
sudo systemctl enable nginx
sudo systemctl enable uwsgi

Next steps are adding an SSL certificate to secure the traffic of your site (Link)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment