Step6: Deploy: Copy app to Remote Server - SwagatoMondal/Online-Shopping GitHub Wiki

There are multiple ways to copy your Django Web application to the remote server :

  1. GitHub clone
  2. File copy
  3. Via CLI

This document will cover on how we can achieve this using CLI commands. So let's get back to your local machine and do the following.

Activate virtual env -

Re-activate the virtual environment (which you should have done while creating the project).

source /path-to-app/bin/activate

Check all dependencies

To display all your dependencies, run the following command (PIP must be installed) -

pip freeze

Copy all dependencies to requirements.txt

To copy all the dependencies -

pip freeze > requirements.txt

NOTE : Make sure to copy the file into your project if not done.

Copy project to Web Server

scp -r <django-project root> username@<IP Address>:~/

NOTE : This copies the Django project from your local to the specified path of remote, which is Home for the given user.

Verify in Web Server

Run ls command on the folder you copied to verify the previous command.

Install dependencies

sudo apt-get install python3-pip
sudo apt-get install python3-venv

Activate virtual environment

python3 -m venv <project-location>/venv
source <project-location>/venv/bin/activate

Install dependencies for project in remote machine

pip install -r requirements.txt

Test your app

Static changes

To test your app on local, some changes are required in your settings.py file.

// Other details

ALLOWED_HOSTS = ['<Enter your IP_ADDRESS>']

// Add the next line
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

Save and exit the file.

python manage.py collectstatic

You can run ls command to check for static dir.

Run server

To run server, run the following command (remember we allowed only PORT 8000) -

python manage.py runserver 0.0.0.0:8000

To verify go to your browser and open <remote IP-address>:8000.

Install Apache and WSGI

NOTE : Remain in virtual environment to continue the process.

sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi-py3

Configure Apache Web Server

NOTE : Remain in virtual environment to continue the process.

// Move to directory
cd /etc/apache2/sites-available/

// Copy one of the config file into a new file (first arg is a default config file, second arg is a new file)
sudo cp 000-default.conf django_project.conf

// Edit the configuration file now
sudo nano django_project.conf

In the edit window, add the following rules just before the end of VirtualHost tag as follows -

Alias /static /home/username/project_location/static
<Directory /home/username/project_location/static>
    Required all granted
</Directory>
// Similarly for any other directories

// Add wsgi.py file for interaction between apache & Django
<Directory /home/username/project_location/project_name>
    <Files wsgi.py>
        Required all granted
    </Files>
</Directory>

// Add daemon (recommended by Django official documentation)
WSGIScriptAlias / /home/username/project_location/project_name/wsgi.py
WSGIDaemonProcess django_app python-path=/home/username/project_location python-home=/home/username/project_location/venv
WSGIProcessGroup django_app

Save and exit the edit mode.

Enable site through Apache

// Enable site
sudo a2ensite project_name

// Disable default config
sudo s2dissite 000-default.conf

Some more permissions for storage files/folders

// For your DB (Apache will become group owner of this file)
sudo chown :www-data project_location/db.sqlite3

// Set permission for the same
sudo chmod 664 project_location/db.sqlite3

// Add owner for project folder itself
sudo chown :www-data project_location/
sudo chmod 775 project_location/

// Verify using ls -la command to check for owner & group

// Also add for any folder(s) which might contain data like images uploaded by user (let's assume folder name is media)
sudo chown -R :www-data project_location/media/
sudo chmod -R 775 project_location/media/

Store your sensitive information in config file

Store information

If your project contains sensitive information such as keys, credentials then you should create a config file as mentioned below -

sudo touch /etc/app_name/config.json

// Grab your secret key from settings.py file 'SECRET_KEY' add to JSON
{
   "SECRET_KEY": "<secret-key>
   // Other similar info (if any)
}

Use stored information

Now open the settings.py file in edit mode and add the following -

import os
// New changes
import json

with open('/etc/app_name/config.json') as config_file:
    config = json.load(config_file)

// Other Code ...
SECRET_KEY = config['SECRET_KEY']

# SECURITY WARNING:
DEBUG = False

// Any other similar usage needs to updated

Now save and exit.

Final steps

Remove the 8000 allowed port in firewall

sudo ufw delete allow 8000

Allow HTTP traffic

sudo ufw allow http/tcp

Restart your Apache server

sudo service apache2 restart

Try using your IP address (only without port) on your browser and you should see your website. Now you can test your functionality.

If everything works you're all set. You can also refer to the official documentation checklist page for reference.

⚠️ **GitHub.com Fallback** ⚠️