Create EC2 and PostgreSQL to deploy a Django and PostgreSQL

 

AWS

# Create VPCàCreate Subnet. Different subnet in different AZàAttach route table of each subnet Group

Before creating PostgreSQL

1.     Create a SG that for postgresql, port 5432 and source sg of ec2.

2.     Create a subnet group. Only private subnet added to this group. At lease to private subnet with different AZ .

 

PostgreSQL:

DB Instance: examdb

DB name: postgres

Master user: examdbuser

PWD: Ex****db

Port: 5432

Endpoint: examdb.czem0muqoe3b.ap-south-1.rds.amazonaws.com

EC2 তে PostgreSQL Client Install করুন-

Ubuntu

sudo apt update

sudo apt install postgresql-client -y

Step 6: EC2 থেকে Connect Test করুন

psql -h examdb.xxxxx.ap-south-1.rds.amazonaws.com \

-U postgresUser \

-d dbname

এখন পাসওয়ার্ড চাইবে

**press \q to go back ect2

Step 7: Django settings.py এ Configure করুন

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.postgresql',

        'NAME': 'postgres',

        'USER': 'postgres',

        'PASSWORD': 'yourpassword',

        'HOST': 'examdb.xxxxx.ap-south-1.rds.amazonaws.com',

        'PORT': '5432',

    }

}

 

/////////////////////

Create EC2

https://www.youtube.com/watch?v=43tIX7901Gs&t=1291s

PublicIPs: 13.127.49.18    PrivateIPs: 10.0.1.57    

 

বিশেষভাবে খেয়াল করুন:

  • AWS এখন অনেক region-এ Public IPv4 address এর জন্য hourly charge নেয়।
  • Instance বন্ধ থাকলেও Elastic IP attach থাকলে charge আসতে পারে।

তাই cost কমাতে:

  • ব্যবহার না করলে instance stop করুন
  • অপ্রয়োজনীয় public IP release করুন
  • ছোট instance type (যেমন t3.micro / t4g.micro) ব্যবহার করুন

////////

>sudo apt update && sudo apt upgrade -y

>sudo apt install python3-pip python3-venv git libpq-dev python3-dev -y

#mkdir myproject && cd myproject

>git clone https://github.com/imran814210/examlocalbackend.git

>github username

>github password চাবে এখানে access token দিবো (githubàsettingsàdeveloper এখান থেকে access token create করে নিয়ে যাবো)

github_pat_11*****************************************BNIGHY2QokonLEGH

এখন প্রজেক্ট ফোল্ডারে যেতে হবে।

> sudo apt update

> sudo apt install nginx -y

> sudo systemctl status nginx

>python3 -m venv venv

>source venv/bin/activate

>pip install gunicorn

>pip install -r requirements.txt

>python manage.py makemigrations

>python manage.py migrate

>python manage.py createsuperuser

> python manage.py collectstatic –noinput

Gunicorn restart> sudo systemctl restart gunicorn

Status check> sudo systemctl status gunicorn

Nginx restart> sudo systemctl restart nginx

Check> sudo systemctl status nginx

Check EC2 toPostgres DB> nc -vz examdb.czem0muqoe3b.ap-south-1.rds.amazonaws.com 5432

If output is successed that means

EC2
Django

RDS
exists

> 

Production এ কী ব্যবহার করবে?

>pip install gunicorn

>gunicorn --bind 0.0.0.0:8000 config.wsgi [এখানে config হলো প্রজেক্ট ফোল্ডারের নাম]

বাহির থেকে access করতে চাইলে:

>gunicorn –bind 0.0.0.0:8000 projectfolder.wsgi

এটা শুধুমাত্র current terminal session পর্যন্ত চলবে।

যদি:

  • terminal বন্ধ হয়
  • SSH disconnect হয়
  • EC2 reboot হয়
  • server crash হয়

তাহলে website বন্ধ হয়ে যাবে।

Production এ তাই নিচের architecture ব্যবহার করা হয়:

Internet

  

Nginx (Port 80/443)

  

Gunicorn (Unix Socket)

  

Django

কেন প্রয়োজন?

1. Gunicorn Service (systemd)

এটা:

  • auto start করবে
  • reboot এর পর আবার চালু করবে
  • crash হলে restart করবে
  • background এ run করবে

2. Nginx

এটা:

public request handle করে

static files fast serve করে

HTTPS দেয়

reverse proxy হিসেবে কাজ করে

এখন Step by Step করি

ধরি:

Item

Value

Project Path

/home/ubuntu/examlocalbackend

Virtual Env

/home/ubuntu/examlocalbackend/venv

Django Project

examlocalproject

আপনার path আলাদা হলে শুধু replace করবেন।

STEP 1 — Create Gunicorn Service

create file:

> sudo nano /etc/systemd/system/gunicorn.service

paste this:

/////////////////////////////

[Unit]

Description=Gunicorn daemon for Django project

After=network.target

[Service]

User=ubuntu

Group=www-data

WorkingDirectory=/home/ubuntu/examlocalbackend

ExecStart=/home/ubuntu/examlocalbackend/venv/bin/gunicorn \

          --workers 3 \

          --bind unix:/home/ubuntu/examlocalbackend/gunicorn.sock \

          examlocalproject.wsgi:application

 

[Install]

WantedBy=multi-user.target

////////////////////////////////////////////

save:

  • CTRL + O
  • ENTER
  • CTRL + X

STEP 2 — Start Gunicorn Service

reload systemd:

>sudo systemctl daemon-reload

enable service:

> sudo systemctl enable gunicorn

start service:

> sudo systemctl start gunicorn

check status:

> sudo systemctl status gunicorn
যদি active (running) দেখায় তাহলে ঠিক আছে

#gunicorn restart command

> sudo systemctl restart gunicorn

STEP 3 — Install Nginx

>sudo apt update

>sudo apt install nginx -y

start nginx:

>sudo systemctl start nginx

enable nginx:

> sudo systemctl enable nginx

STEP 4 — Create Nginx Config

create config:

> sudo nano /etc/nginx/sites-available/examlocalbackend

paste:

/////////////////////////////

server {

    listen 80;

    server_name_;

    location / {

        proxy_pass http://127.0.0.1:8000;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       proxy_set_header X-Forwarded-Proto $scheme; # এটি খুবই গুরুত্বপূর্ণ

    }

}

 

///////////////////////// save and exit।

STEP 5 — Enable Nginx Config:

>sudo ln -s /etc/nginx/sites-available/examlocalbackend /etc/nginx/sites-enabled

Show কোন file দুটো আছে দেখুন:

> ls -l /etc/nginx/sites-enabled/

remove default config:

> sudo rm /etc/nginx/sites-enabled/default

STEP 6 — Test Nginx

> sudo nginx -t

যদি দেখায়:

syntax is ok

test is successful

তাহলে restart:

> sudo systemctl restart nginx

STEP 7 — Django Static Files

settings.py

STATIC_URL = 'static/'

STATIC_ROOT = BASE_DIR / 'staticfiles'

তারপর:

> python manage.py collectstatic

//////////////////// Security Group////////////

** when create sg remain that sg and resource that consume sg are same vpc

** Open Security Group

AWS EC2 → Security Group → Inbound Rules:

Type

Port

source

HTTP

80

0.0.0.0/0

HTTPS

443

0.0.0.0/0

SSH

22

myIP

Custom TCP

8000 (যদি Django server বাহির থেকে access করতে চাই)

 

 

 

 

CloudFront to s3 and ec2

Architecture

User

 

CloudFront

  ── /        S3 React

  └── /api/*   → EC2 Django

এখন React call করবে:

fetch("/api/users/")

How To Configure

 

Step 4: CloudFront Second Origin Add করুন

CloudFront Distribution যান।

Existing Origin

  • S3 bucket

Add New Origin

Origin Domain:

  • EC2 public DNS
  • অথবা domain name

Example:

ec2-13-xxx.ap-south-1.compute.amazonaws.com

 

Protocol: যদি ec2 তে ‍ssl যুক্ত থাকে তবে HTTPS আর না থাকলে HTTP

Name: একটা নাম দিবো

Step 5: Behavior Add করুন

Add behavior:

Path Pattern:

/api/* এবং এই পাথটা s3 পাথের উপরে থাকবে

Origin:

  • EC2 Origin

Viewer Protocol:

  • Redirect HTTP to HTTPS

Step 6: React API URL Change করুন

axios.get("/api/users/")

or

axios.get("https://your-cloudfront-domain/api/users/")

/////////////////////////////////////////////

requirements.txt

Django

gunicorn

nginx

psycopg2-binary

dj-database-url

django-cors-headers


# AI প্রয়োজনীয়

groq

langchain

langchain-community

langchain-core


# Utility

requests

pydantic


python-dotenv

djangorestframework

djangorestframework-simplejwt

pandas

openpyxl

#for load static file in deploment server

whitenoise

////////////////////////////////.env

GROQ_API_KEY ="gsk_CmO1Pb******************V5tM16wJVUj"

SECRET_KEY="django- এটা django project এর security key $8=%1=3$1pgi*601k+"

DEBUG=False

ALLOWED_HOSTS =localhost,ec2 এর public IP,d49c5t1djalnx.cloudfront.net

DB_NAME="examdb"

DB_USER="examuser"

PASSWORD="Ex****db"

HOST="postger এর endpoint"

PORT="5432"

////////////////////////////////////settings.py

from pathlib import Path
import dj_database_url
import os
from dotenv import load_dotenv
load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BA
SECRET_KEY =os.getenv('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv('DEBUG') == 'True'

ALLOWED_HOSTS =  os.getenv('ALLOWED_HOSTS').split(',')

CSRF_TRUSTED_ORIGINS = ["https://d49c5t1djalnx.cloudfront.net"]

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
     # Third party
    "rest_framework",
    "corsheaders",
    # Local apps
    "accounts",
    "forms",
    "results",
    "aiassistant",
   
]
MIDDLEWARE = [
     "corsheaders.middleware.CorsMiddleware",
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'examlocalproject.urls'
CORS_ALLOW_ALL_ORIGINS = False
CORS_ALLOWED_ORIGINS = ["https://d49c5t1djalnx.cloudfront.net"]
AUTH_USER_MODEL = "accounts.User"
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
WSGI_APPLICATION = 'examlocalproject.wsgi.application'


DATABASES= {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('PASSWORD'),
        'HOST': os.getenv('HOST'),
        'PORT': os.getenv('PORT'),
    }
}

# Password validation
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/6.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
# TIME_ZONE = "Asia/Dhaka"
USE_I18N = True
USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/6.0/howto/static-files/
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
# JWT Authentication Setup
from datetime import timedelta
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
    "DEFAULT_PERMISSION_CLASSES": (
        "rest_framework.permissions.IsAuthenticated",
    )
}
SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=60),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
     "AUTH_HEADER_TYPES": ("Bearer",),
}

GROQ_API_KEY = os.getenv("GROQ_API_KEY")

Comments