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.
Pick a free domain nabavi.ga on https://my.freenom.com/. Freenom would be a domain registrar for 12 months for free.
Add site Select free plan Remove freenom nameservers & add cloudflares
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
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
Navigate to log file directory var/www/api.nabavi.ga/logs
less uwsgi.log
tail -n 50 uwsgi.log
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
#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
settings.py
STATIC_ROOT = BASE_DIR / 'static/'
Then run:
python manage.py collectstatic
- 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
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
- Instances > Select Instance > Connect
- SSH Client
- Follow instructions there
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
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] |