<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: richard ndemo</title>
    <description>The latest articles on DEV Community by richard ndemo (@ndemo).</description>
    <link>https://dev.to/ndemo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F238627%2F3fde7db2-acb4-4c23-b845-25156adb3bd7.png</url>
      <title>DEV Community: richard ndemo</title>
      <link>https://dev.to/ndemo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ndemo"/>
    <language>en</language>
    <item>
      <title>Building CloudRegNotify: An AWS-Based User Registration and Notification System</title>
      <dc:creator>richard ndemo</dc:creator>
      <pubDate>Sun, 27 Oct 2024 06:41:14 +0000</pubDate>
      <link>https://dev.to/ndemo/building-cloudregnotify-an-aws-based-user-registration-and-notification-system-1lk1</link>
      <guid>https://dev.to/ndemo/building-cloudregnotify-an-aws-based-user-registration-and-notification-system-1lk1</guid>
      <description>&lt;p&gt;In today's digital age, user registration and notification systems play a critical role in enhancing user experience and engagement. I embarked on a journey to create CloudRegNotify, a scalable cloud-based system leveraging various AWS services to automate user sign-up, verify email addresses, store user data securely, and send notifications. This project not only challenged my skills but also deepened my understanding of cloud architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The primary goal of CloudRegNotify was to build an efficient system that simplifies user registration while ensuring data security and scalability. By automating the user sign-up process and utilizing AWS services, I aimed to create a seamless experience for users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To achieve this, I designed the architecture of CloudRegNotify to incorporate the following AWS services:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Cognito:&lt;/strong&gt; For user authentication and management.&lt;br&gt;
&lt;strong&gt;AWS Lambda:&lt;/strong&gt; To handle the user registration logic and backend processing.&lt;br&gt;
&lt;strong&gt;DynamoDB:&lt;/strong&gt; For securely storing user information.&lt;br&gt;
&lt;strong&gt;Amazon SNS:&lt;/strong&gt; To send email notifications to users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeu0ic89i7dkeroe67mt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeu0ic89i7dkeroe67mt.png" alt="Image description" width="792" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation Steps&lt;/strong&gt;&lt;br&gt;
The implementation process was divided into several key steps, each presenting unique challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Creating a Cognito User Pool&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I started by creating a user pool in the AWS Cognito console, configuring it to require both an email and a username for sign-in while enabling email verification. Ensuring the correct configuration of the user pool was crucial, as any oversight could lead to significant issues later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feei63amyshjhforxc9jk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feei63amyshjhforxc9jk.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Setting Up DynamoDB&lt;/strong&gt;&lt;br&gt;
Next, I created a DynamoDB table named "UserPreferences" to store user data. Initially, I faced challenges designing an efficient table schema but opted for a straightforward structure for this Minimum Viable Product (MVP).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps092isempc7ug1twi80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps092isempc7ug1twi80.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configuring SNS&lt;/strong&gt;&lt;br&gt;
To send notifications, I created an SNS topic called "UserNotifications." Configuring permissions for Lambda to interact with SNS was initially tricky, but I managed to troubleshoot and resolve the issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1iozrdg3itv4uhhyytu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1iozrdg3itv4uhhyytu.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Lambda Function Creation&lt;/strong&gt;&lt;br&gt;
I developed a Lambda function named "NotificationHandler" using Python. Writing the logic for storing user details in DynamoDB and triggering SNS notifications required several iterations, especially when I encountered permission errors. Updating the execution role with the correct policies resolved these issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import boto3
import logging

# Initialize logging
logging.basicConfig(level=logging.INFO)

# Initialize DynamoDB and SNS clients
dynamodb = boto3.resource('dynamodb')
sns = boto3.client('sns')

def lambda_handler(event, context):
    logging.info("Received event: %s", json.dumps(event))

    try:
        user_id = event['userName']
        email = event['request']['userAttributes']['email']

        logging.info(f"User confirmed: {user_id}, Email: {email}")

        # Access DynamoDB Table
        table = dynamodb.Table('UserPreferences')

        # Store user details in DynamoDB
        table.put_item(
            Item={
                'UserID': user_id,
                'Email': email,
                'NotificationPreference': 'Email'
            }
        )
        logging.info("User details saved to DynamoDB")

        # Subscribe the user's email to the SNS topic
        try:
            sns.subscribe(
                TopicArn='arn:aws:sns:us-east-1:867093160463:UserNotifications',  # Replace with your SNS Topic ARN
                Protocol='email',
                Endpoint=email
            )
            logging.info(f"User {email} subscribed to SNS topic")
        except Exception as sub_error:
            logging.error(f"Error subscribing user {email} to SNS topic: {str(sub_error)}")
            # You can choose to continue or return here if you don't want the process to continue.
            # return event

        # Send notification via SNS
        message = f"Hello {user_id}, your account has been successfully created!"
        response = sns.publish(
            TopicArn='arn:aws:sns:us-east-1:867093160463:UserNotifications',  # Replace with your SNS Topic ARN
            Message=message,
            Subject="Account Created"
        )
        logging.info("SNS publish response: %s", response)

        # Return the event as required by Cognito Post Confirmation trigger
        return event

    except Exception as e:
        logging.error("Error occurred: %s", str(e))
        return {
            'statusCode': 500,
            'body': json.dumps(f"An error occurred: {str(e)}")
        }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3on7glj3fc5jywy85sfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3on7glj3fc5jywy85sfm.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functionality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the setup was complete, I rigorously tested the system to ensure its functionality:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Registration:&lt;/strong&gt; Users can register with their email and username.&lt;br&gt;
&lt;strong&gt;Email Verification:&lt;/strong&gt; A verification code is sent to users, and upon confirmation, their details are securely stored in DynamoDB.&lt;br&gt;
&lt;strong&gt;Notification:&lt;/strong&gt; A welcome email is sent via SNS once the account is created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Services Used&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The successful implementation of CloudRegNotify relied on several AWS services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Cognito&lt;/li&gt;
&lt;li&gt;AWS Lambda&lt;/li&gt;
&lt;li&gt;DynamoDB&lt;/li&gt;
&lt;li&gt;Amazon SNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Challenges and Solutions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Throughout the project, I faced various challenges, including:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Permissions:&lt;/strong&gt; Figuring out why my Lambda function couldn’t publish to SNS or write to DynamoDB was frustrating. I resolved this by attaching the necessary policies, enabling seamless interaction between services.&lt;br&gt;
&lt;strong&gt;Handling Event Errors: ** I encountered issues with subscriptions to the SNS topic due to invalid email addresses. By enhancing error logging, I ensured that invalid emails wouldn’t disrupt the entire process.&lt;br&gt;
**Testing:&lt;/strong&gt; Comprehensive testing revealed multiple bugs, such as notifications not triggering correctly. Leveraging AWS CloudWatch logs proved invaluable for debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Future Improvements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reflecting on this project, I have identified several enhancements I plan to implement:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Preferences&lt;/strong&gt;: Allow users to select their preferred notification method (email, SMS, or push notifications).&lt;br&gt;
&lt;strong&gt;Improved Error Handling:&lt;/strong&gt; Develop more robust mechanisms to handle edge cases, particularly during user subscriptions.&lt;br&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Introduce analytics to track user engagement with notifications, providing insights for improving user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building CloudRegNotify has been a rewarding learning experience. By leveraging AWS services like Lambda, Cognito, DynamoDB, and SNS, I created a scalable, cloud-based solution for user registration and notifications. The challenges I encountered allowed me to deepen my understanding of AWS, and I am proud of the system I developed.&lt;/p&gt;

&lt;p&gt;You can explore the project further on&lt;a href="https://github.com/ndemo-richard/AWS_-Cloud-Based-User-Registration-and-Notification-System" rel="noopener noreferrer"&gt; GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>IT ASSET MANAGEMENT -bare basics</title>
      <dc:creator>richard ndemo</dc:creator>
      <pubDate>Wed, 01 Jun 2022 06:45:22 +0000</pubDate>
      <link>https://dev.to/ndemo/it-asset-management-the-things-you-should-know-3fkk</link>
      <guid>https://dev.to/ndemo/it-asset-management-the-things-you-should-know-3fkk</guid>
      <description>&lt;p&gt;IT assets, what are they, how do they end up in your organization/company and how do you manage them for better perfomance and produtivity? .-IT asset is a peae of software/hardware within an IT echo system.&lt;br&gt;
As an IT custodian, it is your responsibility to ensure the existing assets are useful and valuable to the organization.&lt;/p&gt;

&lt;p&gt;ITAM is a business process to ensure that IT assets are acounted for, intergrated, maintained/upgraded and desposed effectively.&lt;/p&gt;

&lt;p&gt;ITAM process involves five key phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;planning&lt;/li&gt;
&lt;li&gt;Developing/Acquiring&lt;/li&gt;
&lt;li&gt;Integration&lt;/li&gt;
&lt;li&gt;Maintenance/upgrade&lt;/li&gt;
&lt;li&gt;Disposal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;plannig&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is the begining phase of introduing an asset to the echosystem. It involves strategic planning across the organization to determine what asset is needed, how to procure it, the specific way it will be used and how it will be funded. This often includes total cost of ownership estimates and a cost-benefit analysis of alternatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Developing/Acquiring&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After planning and knowing the right asset that is needed, the next phase is the procument in which the organization build, purchase, lease or license the asset they need.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This follow the procurement phase. During which the asset is introduced into the ecosystem of the organization.It includes intergrating the asset with other components, establishing support and operations processes and specifying user access.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Maintenance/upgrade&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Once the asset is fully intergrated in the echosystem and is being utilised, to maximize its value and extend its life as well as mitigate risk and reduce support costs, maintenance, repair and extensive overhauls may be necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Disposal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When the asset reaches the end of its useful life, the last phase is disposal. This includes transitioning users to other resources, updating asset records, canceling support agreements, terminating licences renewals and initiating the planning for replacement asset.&lt;/p&gt;

&lt;p&gt;proper understanding and utilization of this phases will enable a smooth running of the IT echosystem .&lt;/p&gt;

</description>
      <category>it</category>
      <category>servicedesk</category>
    </item>
    <item>
      <title>How I deployed my Django app to Vultr VPS</title>
      <dc:creator>richard ndemo</dc:creator>
      <pubDate>Sun, 29 Sep 2019 15:44:25 +0000</pubDate>
      <link>https://dev.to/ndemo/how-i-deployed-my-django-app-to-vultr-vps-3k1i</link>
      <guid>https://dev.to/ndemo/how-i-deployed-my-django-app-to-vultr-vps-3k1i</guid>
      <description>&lt;p&gt;Having developed my Django app, it was time to deploy it so that it can be live, such a thrilling feeling to have my own hosted website online. - I did a couple of searches and decided to host with &lt;a href="https://www.vultr.com/?ref=8253469" rel="noopener noreferrer"&gt;vultr VPS&lt;/a&gt;. Let us jump to the whole process from setting up my server to actual running my website.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a New Instance
&lt;/h1&gt;

&lt;h5&gt;
  
  
  I chose cloud compute:
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fearns9q688jzq3em95d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fearns9q688jzq3em95d0.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Selecting the region for my server:
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4csj0et14rr7lcb2t87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4csj0et14rr7lcb2t87.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  selecting server operating system:
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspbic7a6s8en3yme0op9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspbic7a6s8en3yme0op9.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Selecting the size of the server:
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukumetwhz5v6047fcyac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukumetwhz5v6047fcyac.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I chose to name the server Testserver for a practical purpose. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fia2pcd1v3ulzswrzjrno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fia2pcd1v3ulzswrzjrno.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  after creating  the server:
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uox0i16pqqnzx0u2ssu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uox0i16pqqnzx0u2ssu.png" alt="Alt Text" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after receiving the root password via email, I ssh into the server using the server IP Address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbyjk03g22616rf05dhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbyjk03g22616rf05dhw.png" alt="Alt Text" width="631" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Updating the server
&lt;/h4&gt;

&lt;h5&gt;
  
  
  First thing is to upgrade the server's packages:
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;apt-get update&lt;br&gt;
       apt-get upgrade&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

######Creating Application User
It is always best practice not to work directly with the root user.so I created another user.

&amp;lt;code&amp;gt; adduser django&amp;lt;/code&amp;gt;


since I am deploying a Django application, It is simple to use a simple name.
This is the output. There are few questions to be answered.
~~~
Adding user `django' ...
Adding new group `django' (1000) ...
Adding new user `django' (1000) with group `urban' ...
Creating home directory `/home/django' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for urban
Enter the new value, or press ENTER for the default
  Full Name []:
  Room Number []:
  Work Phone []:
  Home Phone []:
  Other []:
Is the information correct? [Y/n]
~~~

Adding the user to sudoers to be able to perform root functions:
&amp;lt;code&amp;gt;gpassword -a django sudo&amp;lt;/code&amp;gt;

Now log in to the new user account.

##Installing the necessary Dependencies:

#####Supervisor
This will be used to start the Django application server and manage it.

&amp;lt;code&amp;gt;sudo apt-get install supervisor&amp;lt;/code&amp;gt;

######Starting and enabling the supervisor:


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;sudo systemctl enable supervisor&lt;br&gt;
sudo systemctl start supervisor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#####PostgreSQL 

Installing the dependencies to be used by Postgresql and Django

&amp;lt;code&amp;gt;sudo apt-get install build-essential libpq-dev python-dev&amp;lt;/code&amp;gt;

######Installing PostgreSQL server:

&amp;lt;code&amp;gt;sudo apt-get -y install postgresql postgresql-contrib&amp;lt;/code&amp;gt;

######Creating and Configuring PostgreSQL database:

#####Switch users:

&amp;lt;code&amp;gt;su - postgres&amp;lt;/code&amp;gt;

Creating a db user and database:


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;createuser django_project&lt;br&gt;
createdb prod --owner django_project&lt;br&gt;
psql -c "ALTER USER u_urban WITH PASSWORD '!@#fs_877#$cdfd@@'"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

######exit the postgreSQL user:
&amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt;

####Install and Configure Virtualenv

I used python3 that is already installed in ubuntu 16.04

######First, install pip3:

&amp;lt;code&amp;gt;sudo apt-get install python3-pip&amp;lt;/code&amp;gt;

######Using pip install virtualenv:

&amp;lt;code&amp;gt;pip3 install virtualenv&amp;lt;/code&amp;gt;

######Then create virtualenv:

&amp;lt;code&amp;gt;python3 -m venv django_env&amp;lt;/code&amp;gt;

######Activating it:
cd to the virtualenvdirectory &amp;lt;code&amp;gt;cd django_env&amp;lt;/code&amp;gt;

&amp;lt;code&amp;gt;source bin/activate&amp;lt;/code&amp;gt;

I used GitHub to store my Django website, so I cloned it from the git repository.

&amp;lt;code&amp;gt;git clone https://github.com/ndemo-richard/django_project.git&amp;lt;/code&amp;gt;

cd into project directory and install project dependencies:

&amp;lt;code&amp;gt;pip install -r requirements.txt&amp;lt;/code&amp;gt;

changing the database credentials in the settings.py file in the project root directory:

~~~
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'prod',
        'USER': 'django_project',
        'PASSWORD': '!@#fs_877#$cdfd@@',
        'HOST': 'localhost',
        'PORT': '',
    }
}
~~~

#####migrating the database:
&amp;lt;code&amp;gt;python manage.py migrate&amp;lt;/code&amp;gt;

#####collect project static files:
&amp;lt;code&amp;gt;python manage.py collectstatic&amp;lt;/code&amp;gt;

####Install and configure Gunicorn

&amp;lt;code&amp;gt;pip install gunicorn&amp;lt;/code&amp;gt;

create a file named gunicorn inside bin directory

&amp;lt;code&amp;gt; vi bin/gunicorn&amp;lt;/code&amp;gt; 
add this to the empty file:

~~~
#!/bin/bash

NAME="django_project"
DIR=/home/django/django_project
USER=django
GROUP=django
WORKERS=3
BIND=unix:/home/django/run/gunicorn.sock
DJANGO_SETTINGS_MODULE=django_project.settings
DJANGO_WSGI_MODULE=django_project.wsgi
LOG_LEVEL=error

cd $DIR
source ../bin/activate

export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DIR:$PYTHONPATH

exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $WORKERS \
  --user=$USER \
  --group=$GROUP \
  --bind=$BIND \
  --log-level=$LOG_LEVEL \
  --log-file=-
~~~

make the file executable

&amp;lt;code&amp;gt;chmod u+x bin/gunicorn&amp;lt;/code&amp;gt;

create directory for the UNIX socket file:

&amp;lt;code&amp;gt; mkdir run&amp;lt;/code&amp;gt;

#####Configure Supervisor

 first, create a directory for log files:

&amp;lt;code&amp;gt;mkdir logs&amp;lt;/code&amp;gt;

######Create an empty log file inside the log directory:

&amp;lt;code&amp;gt;touch logs/gunicorn-error.log&amp;lt;/code&amp;gt;

create a new supervisor config file:

&amp;lt;code&amp;gt;sudo vi /etc/supervisor/conf.d/django_project.conf&amp;lt;/code&amp;gt;

django_project.conf

~~~
[program:django_project]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;command=/home/django/django_project/bin/gunicorn&lt;br&gt;
user=urban&lt;br&gt;
autostart=true&lt;br&gt;
autorestart=true&lt;br&gt;
redirect_stderr=true&lt;br&gt;
stdout_logfile=/home/django/logs/gunicorn-error.log&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Reread the config file:


```

sudo supervisorctl reread
sudo supervisorctl update

```


Check the status:

```

sudo supervisorctl status django_project
django_project                      RUNNING   pid 42173, uptime 0:00:13

```



##NGINX

Installing Nginx web server, this will be used to run the Django application behind a proxy server

&amp;lt;code&amp;gt;sudo apt-get install nginx&amp;lt;/code&amp;gt;

create new config file inside /etc/nginx/sites-available/:

&amp;lt;code&amp;gt;sudo vim /etc/nginx/sites-available/django_project&amp;lt;/code&amp;gt;

/etc/nginx/sites-available/djago_project

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;upstream app_server {&lt;br&gt;
    server unix:/home/urban/run/gunicorn.sock fail_timeout=0;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;server {&lt;br&gt;
    listen 80;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
server_name 68.152.87.135;

keepalive_timeout 5;
client_max_body_size 4G;

access_log /home/urban/logs/nginx-access.log;
error_log /home/urban/logs/nginx-error.log;

location /static/ {
    alias /home/urban/static/;
}

# checks for static file, if not found proxy to app
location / {
    try_files $uri @proxy_to_app;
}

location @proxy_to_app {
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_pass http://app_server;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
creating a symbolic link:



```

sudo ln -s /etc/nginx/sites-available/django_project /etc/nginx/sites-enabled/django_project

```




Remove the default nginx website:
&amp;lt;code&amp;gt;sudo rm /etc/nginx/sites-enabled/default&amp;lt;/code&amp;gt;

Restart nginx:
&amp;lt;code&amp;gt;sudo service nginx restart&amp;lt;/code&amp;gt;

Now we are good to go. My website is online.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>django</category>
      <category>vultr</category>
      <category>webdev</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
