Deploying a Django Project on Linode: A Step-by-Step Guide

2024-06-02




Record the deployment procedure

Recording the deployment procedure of this website


Setting Up Your Linode Server

  • Creating a Linode Account

    • Create a Linode Instance:

      • Image: Ubuntu
      • Region: Atlanta, GA (or choose a region close to you)
      • Plan: Nanode 1GB
      • Label: django-server
      • Tags: Leave empty
      • Root Password: Set a strong password
    • Boot Your Server:
      • Click Create and wait for your Linode to boot up.
      • Once booted, click on your Linode instance labeled django-server.
    • Other
      • server migrate: using Linode's GUI option, follow the step. The process takes less than an hour to complete in my case.
        • If Linode is undergoing maintenance, the migration may fail, and Linode will not send your email to inform you that your migration is failed. But you can check Activity Feed in your server panel about the migration fail message. Then just simply retry the migration once the maintenance is finished.
  • Configuring Your Server

    • SSH into Your Server:
      • Access the server via SSH
        ssh root@<your-server-ip>
      • Update and upgrade packages
        apt-get update && apt-get upgrade
      • Set the hostname
        hostnamectl set-hostname django-server
      • Verify the hostname
        hostname
    • Update /etc/hosts:

      • Edit the hosts file
        nano /etc/hosts
      • Add the following line
        your_ip_address django-server
    • Create a New User:

      • Add a new user
        adduser yourusername
      • Add the user to the sudo group
        adduser your_user_name sudo
      • Exit the SSH session
        exit
    • SSH as the New User:

      • SSH back into the server
        ssh your_user_name@your_ip_address
  • Setting Up Key-Based Authentication

    • Create .ssh Directory:

      • Run
        mkdir -p ~/.ssh
      • List directory contents to verify
        ls -la
    • Copy SSH Key:

      • Generate an SSH key pair on your local machine
        ssh-keygen -b 4096
      • Copy the public key to the server
        scp ~/.ssh/id_rsa.pub your_user_name@your_ip_address:~/.ssh/authorized_keys
    • Update SSH Permissions:

      • Set permissions
        sudo chmod 700 ~/.ssh and sudo chmod 600 ~/.ssh/*
      • Restrict root login and disable password authentication
        sudo nano /etc/ssh/sshd_config
        • Set PermitRootLogin no
        • Uncomment PasswordAuthentication no
      • Restart SSH service
        sudo systemctl restart sshd
  • Setting Up UFW Firewall

    • Install and Enable UFW:

      • Install UFW
        sudo apt-get install ufw
      • Set default rules
        sudo ufw default allow outgoing and sudo ufw default deny incoming
      • Allow SSH and web traffic
        sudo ufw allow ssh and sudo ufw allow 8000
      • Enable UFW
        sudo ufw enable
      • Verify UFW status
        sudo ufw status

Deploying Your Django Application

  • Preparing Your Local Environment

    • Prepare Your Django Project:
      • Activate your virtual environment
        source django_project/venv/bin/activate
      • Freeze your dependencies
        pip freeze > requirements.txt
      • Copy your project to the server
        scp -r django_project your_user_name@your_ip_address:~/
  • Setting Up the Server Environment

    • Install Python and Virtual Environment:

      • Install pip: 
        sudo apt-get install python3-pip
      • Install virtual environment
        sudo apt-get install python3-venv
      • Create a virtual environment
        python3 -m venv django_project/venv
      • Activate the virtual environment
        source venv/bin/activate
    • Install Dependencies:

      • Navigate to your project directory
        cd django_project
      • Install dependencies
        pip install -r requirements.txt
  • Configuring Django Settings

    • Update Django Settings:

      • Edit settings.py
        sudo nano django_project/settings.py
      • Set ALLOWED_HOSTS
        ALLOWED_HOSTS = ['your_ip_address']
      • Set static files directory
        STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    • Collect Static Files

      • python manage.py collectstatic
  • Running Your Django Application

    • Test the Server:
      • Run the development server
        python manage.py runserver 0.0.0.0:8000
      • Open your browser and navigate to your_ip_address:8000 to test the application.
  • Setting Up Apache with mod_wsgi

    • Install Apache and mod_wsgi:

      • Install Apache
        sudo apt-get install apache2
      • Install mod_wsgi
        sudo apt-get install libapache2-mod-wsgi-py3
    • Configure Apache:

      • Create a new Apache configuration file
        sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/django_project.conf
      • Edit the configuration file
        sudo nano /etc/apache2/sites-available/django_project.conf
      • Add the following configuration (django_project.conf):
      • <VirtualHost *:80>
        	# The ServerName directive sets the request scheme, hostname and port that
        	# the server uses to identify itself. This is used when creating
        	# redirection URLs. In the context of virtual hosts, the ServerName
        	# specifies what hostname must appear in the request's Host: header to
        	# match this virtual host. For the default virtual host (this file) this
        	# value is not decisive as it is used as a last resort host regardless.
        	# However, you must set it for any further virtual host explicitly.
        	#ServerName www.example.com
        
        	ServerAdmin webmaster@localhost
        	DocumentRoot /var/www/html
        
        	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        	# error, crit, alert, emerg.
        	# It is also possible to configure the loglevel for particular
        	# modules, e.g.
        	#LogLevel info ssl:warn
        
        	ErrorLog ${APACHE_LOG_DIR}/error.log
        	CustomLog ${APACHE_LOG_DIR}/access.log combined
        
        	# For most configuration files from conf-available/, which are
        	# enabled or disabled at a global level, it is possible to
        	# include a line for only one particular virtual host. For example the
        	# following line enables the CGI configuration for this host only
        	# after it has been globally disabled with "a2disconf".
        	#Include conf-available/serve-cgi-bin.conf
        
        	#Alias /static/ /home/<your_username>/<your_project_name>/static/
        	#<Directory /home/<your_username>/<your_project_name>/static>
        	#	Require all granted
        	#</Directory>
        
        	Alias /static/ /home/<your_username>/<your_project_name>/staticfiles/
        	<Directory /home/<your_username>/<your_project_name>/staticfiles>
        		Require all granted
        	</Directory>
        
        	Alias /media/ /home/<your_username>/<your_project_name>/media/
        	<Directory /home/<your_username>/<your_project_name>/media>
                        Require all granted
                </Directory>
        
        	<Directory /home/<your_username>/<your_project_name>/<your_project_name>>
        		<Files wsgi.py>
        			Require all granted
        		</Files>
        	</Directory>
        
        	WSGIScriptAlias / /home/<your_username>/<your_project_name>/<your_project_name>/wsgi.py
        	WSGIDaemonProcess <your_project_name> python-path=/home/<your_username>/<your_project_name> python-home=/home/<your_username>/<your_project_name>/venv user=www-data group=www-data processes=2 threads=15
        	WSGIProcessGroup <your_project_name>
        
        </VirtualHost>
        
    • Enable the Site and Restart Apache:

      • Enable your site
        sudo a2ensite django_project
      • Disable the default site
      • sudo a2dissite 000-default.conf
      • Restart Apache
      • sudo service apache2 restart
  • Securing Your Django Application

    • Secure Your Database and Media Files:

      • Set permissions
        sudo chown :www-data django_project/db.sqlite3 and sudo chmod 664 django_project/db.sqlite3
      • Set permissions for media files
        sudo chown -R :www-data django_project/media/ and sudo chmod -R 775 django_project/media
    • Secure Sensitive Information:

      • Create a configuration file
        sudo touch /etc/config.json
      • Add your secret key and email credentials (config.json):
      • {
            "SECRET_KEY": "your-secret-key",
            "EMAIL_USER": "your-email@example.com",
            "EMAIL_PASS": "your-email-password"
        }
        
      • Add config data assess (settings.py):
      • import json
        
        with open('/etc/config.json') as config_file:
            config = json.load(config_file)
        
        SECRET_KEY = config['SECRET_KEY']
        DEBUG = False
        EMAIL_HOST_USER = config['EMAIL_USER']
        EMAIL_HOST_PASSWORD = config['EMAIL_PASS']
        

         

    • Update UFW Rules:

      • Remove the rule for port 8000
        sudo ufw delete allow 8000
      • Allow HTTP traffic
        sudo ufw allow http/tcp
      • Restart Apache
        sudo service apache2 restart
  • Final Testing and Launch

    • Final Testing:

      • Navigate to your_ip_address:8000 to test all functionality.
      • Ensure that user registration, login, post creation, updates, deletions, profile picture uploads, and admin functionalities are working as expected.
    • Deploying to Production:

      • Follow Django's deployment checklist to ensure all settings are production-ready.
      • Secure your application with HTTPS and set up a domain name if required.

Apache Log

  • Path
    • /var/log/apache2/error.log
    • /var/log/apache2/access.log






Login to like - 0 Likes



Comments...


No Comments Yet...



Add Comment...




Footer with Icons