Skip to content

Instantly share code, notes, and snippets.

@vucurovicmarko
Last active July 19, 2022 16:09
Show Gist options
  • Save vucurovicmarko/0699d1f622abd1944e09b586ddb8dcdc to your computer and use it in GitHub Desktop.
Save vucurovicmarko/0699d1f622abd1944e09b586ddb8dcdc to your computer and use it in GitHub Desktop.
Django app (api.nabavi.ga) deploy

Django app deploy

I'm using my api.nabavi.ga git project as an example. All occurrences of that project name should be replaced by your project name.

Register domain

Pick a free domain nabavi.ga on https://my.freenom.com/. Freenom would be a domain registrar for 12 months for free.

Cloudflare

https://www.cloudflare.com/

Add site Select free plan Remove freenom nameservers & add cloudflares

Nginx

General notes

Precreate the following:

  • .venv/var/run (for uwsgi.sock)
  • .venv/etc/uwsgi.ini

Commands to precreate:

mkdir -p .venv/var/run
mkdir -p .venv/etc && cp server/uwsgi.ini .venv/etc/uwsgi.ini

sudo su
apt install nginx
sudo su
nano /etc/nginx/sites-available/api.nabavi.ga

and past the following contents:

server/nginx.conf

server {
  listen 80;
  
  access_log /var/www/api.nabavi.ga/logs/nginx-access.log;
  error_log /var/www/api.nabavi.ga/logs/nginx-error.log;
  
  server_name api.nabavi.ga 127.0.0.1;
  
  location / {
    client_max_body_size 100M;
    include uwsgi_params;
    uwsgi_pass unix:/var/www/api.nabavi.ga/.venv/var/run/uwsgi.sock;
  }
  
  location /static/ {
    alias /var/www/api.nabavi.ga/static/;
  }
}
ln -s /etc/nginx/sites-available/api.nabavi.ga /etc/nginx/sites-enabled/api.nabavi.ga
service nginx reload
service nginx restart
nginx -t

uwsgi is a django server that serves the whole app on one linux socket .sock

unix is a protocol used to access .sock file

server/uwsgi_params

This is uwsgi configuration.

uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_ADDR $server_addr;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;

server/uwsgi.ini

This is uwsgi server initialization file

This file should be placed in .venv/etc/

[uwsgi]

chdir = /var/www/api.nabavi.ga/
module = core.wsgi
master = true
processes = 8
harakiri = 3600
socket = /var/www/api.nabavi.ga/.venv/var/run/uwsgi.sock
chmod-socket = 666
vacuum = true
enable-threads = true
single-interpreter = true
buffer-size = 8192
logto = /var/www/api.nabavi.ga/logs/uwsgi.log

module - where wsgi.py is located

processes - 2 * number of cores

harakiri - if some request lasts more than n of seconds it would be restarted. (fun fact: harakiri is japanese suicide method)

socket - place where the app would be served

logto - where to log. Same as when working with development server logs in terminal

Run uwsgi.ini service

In order to run uwsgi service, uwsgi should be installed.

pip install uwsgi

Considering that uwsgi.ini is in var/www/api.nabavi.ga/server/uwsgi.ini

uwsgi --ini server/uwsgi.ini

Watching live changes

Navigate to log file directory var/www/api.nabavi.ga/logs

less uwsgi.log

Read last n lines

tail -n 50 uwsgi.log

Automatically run uwsgi.ini service with linux services

Linux services are written in systemd (a.k.a daemon services). Linux services are automatically run when server is restarted.

They are located in:

cd /etc/systemd/system/

There I make file for writing service.

nano api.nabavi.ga.service

and past the following contents:

server/app.service

[Unit]
Description=uWSGI instance to serve api.nabavi.ga project
After=network.target

[Service]
User=root
WorkingDirectory=/var/www/api.nabavi.ga/core
Environment="PATH=/var/www/api.nabavi.ga/.venv/bin"
ExecStart=/var/www/api.nabavi.ga/.venv/bin/uwsgi --ini /var/www/api.nabavi.ga/.venv/etc/uwsgi.ini
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

Service management commands

#Reload the service files to include the new service.
sudo systemctl daemon-reload

#Start your service
sudo systemctl start api.nabavi.ga.service

#To check the status of your service
sudo systemctl status api.nabavi.ga.service

#To enable your service on every reboot
sudo systemctl enable api.nabavi.ga.service

#To disable your service on every reboot
sudo systemctl disable api.nabavi.ga.service

or

service api.nabavi.ga start

Static files

settings.py

STATIC_ROOT = BASE_DIR / 'static/'

Then run:

python manage.py collectstatic

Moving app to AWS Cloud

Launching Instance

  • Pick Compute > EC2 (Elastic Compute 2) - Virtual Server in the Cloud
  • Launch instance
  • Pick Ubuntu Server 20.04, 64-bit (based on your OS)
  • Key pair (login) > Create key pair > Download Key Pair - used to securely connect to instance
  • Launch Instance

Connect instance with public IP

It already has public IPv4, but whenever server is restarted the public IP changes. Elastic IP is used to solve this - giving permanent IP address.

Network & Security > Elastic Ips

  • Allocate
  • Select allocated IP address > Actions > Associate Elastic IP address
  • Choose an instance
  • Associate

Connect to instance

  • Instances > Select Instance > Connect
  • SSH Client
  • Follow instructions there

Inside instance

Connecting to instance can be found on AWS instance settings

ssh -i "[private_key_permission]" ubuntu@[server-ip-address].compute.amazonaws.com

sudo su

Every change should've been done locally, pushed to github and than pulled on server

The following commands are execured for the first time if no python, venv or nginx are installed


START FIRST_TIME

apt update
apt upgrade

Python 3 setup

sudo apt install -y python3-pip
sudo apt install -y build-essential libssl-dev libffi-dev python3-dev

Virtual environment setup

sudo apt install -y python3-venv

Nginx setup

apt install nginx

END FIRST TIME


Clone project inside /var/www

cd /var/www

git clone https://github.com/markofrontend/api.nabavi.ga.git
cd api.nabavi.ga

Create neccessary directories & files

mkdir media && mkdir static && mkdir -p .venv/var/run && mkdir -p .venv/etc && cp server/uwsgi.ini .venv/etc/uwsgi.ini

Create virtual environment & install dependencies

python3 -m venv .venv
. .venv/bin/activate

pip install -r requirements.txt

Run migrations

python manage.py migrate

Nginx configuration

# Remove 127.0.0.1 server name from the following config
cp server/nginx.conf /etc/nginx/sites-available/api.nabavi.ga

ln -s /etc/nginx/sites-available/api.nabavi.ga /etc/nginx/sites-enabled/api.nabavi.ga
service nginx reload
nginx -t

Make linux uwsgi.ini service

cp server/app.service /etc/systemd/system/api.nabavi.ga.service

#Reload the service files to include the new service.
sudo systemctl daemon-reload

#Start your service
sudo systemctl start api.nabavi.ga.service

Collect static files

python manage.py collectstatic

Cloudflare DNS management

Add A Record for server IP address

The IP address is found on AWS instance (Public IPv4 address)

Type Name IPv4 addres
A api [ip]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment