Create a sudo user
useradd -m user
echo user:d5TFrZfvfW5Ssny| chpasswd
usermod -aG sudo user
chsh --shell /bin/bash user
su - user
Add user to
/etc/ssh/sshd_config AllowUsers configuration if
AllowUsers is used to allow specific user logins via
SSH.
Setup Database
Install Postgresql:apt-get install postgresql postgresql-contrib
Enable and start Postgresql
systemctl enable postgresql
systemctl start postgresql
Create database and role:
sudo su - postgres
createdb db_name
echo "CREATE ROLE db_user WITH PASSWORD 'UgQBq8svKPCEyqT';" | psql
echo "ALTER ROLE db_user WITH LOGIN;" | psql
echo "GRANT ALL PRIVILEGES ON DATABASE "db_name" to db_user;" | psql
exit
Setup pushing via Git
cd
mkdir repo.git app conf logs media static
cd repo.git
git init --bare
git --bare update-server-info
git config core.bare false
git config receive.denycurrentbranch ignore
git config core.worktree /home/user/app/
cat > hooks/post-receive <<EOF
#!/bin/sh
git checkout -f
cd ../app/
./deploy.sh
EOF
chmod +x hooks/post-receive
cd
Add this bare repo as a remote on local.
git remote add server [email protected]:/home/user/repo.git/
ssh-copy-id [email protected]
git push server --all
You may want to modify your git post-receive hook to run custom commands on the server, like running database migrations, notifying services of new deployments, pushing static files to CDN, etc. A deploy.sh file with executable permission is expected in the project root in this example post-receive hook.
Install Required Libraries and Packages
apt install python3-pip
pip3 install virtualenv
Setup the Project
cd
virtualenv env -p python3
source env/bin/activate
cd app
pip install -r requirements/prod.txt
pip install gunicorn
python manage.py migrate
python manage.py collectstatic
Also, try running ./manage.py runserver
to see if everything
is all right.
Install Supervisor
apt install supervisor
systemctl enable supervisor
systemctl start supervisor
Create supervisor configuration
cd
vim conf/supervisor.conf
[program:django_project]
command=/home/user/env/bin/gunicorn django_project.wsgi:application --workers 3 --bind 127.0.0.1:8000
#command=/home/user/env/bin/gunicorn django_project.wsgi:application -c /home/user/app/gunicorn.conf.py
user=user
directory=/home/user/app/
stdout_logfile=/home/user/logs/django.log
stderr_logfile=/home/user/logs/django_err.log
Soft-link our configuration to supervisor conf.d
directory
sudo ln -s /home/user/conf/supervisor.conf /etc/supervisor/conf.d/django_project.conf
sudo supervisorctl reload
Allow user to restart supervisor process without having to use the password
vi /etc/sudoers.d/supervisor_edusanjal
esdj1x ALL = (root) NOPASSWD:/usr/bin/supervisorctl restart edusanjal
Install redis
apt install redis-server
systemctl enable redis-server
systemctl start redis-server
Install nginx
apt install nginx
systemctl enable nginx
rm /etc/nginx/sites-enabled/default
Configure nginx with security headers
cd
vim conf/nginx.conf
upstream django_project {
server 127.0.0.1:8000;
# server unix:/tmp/django_project;
}
# Redirect www.awecode.com to awecode.com
server {
listen 80;
server_name www.awecode.com;
return 301 https://awecode.com$request_uri;
}
server {
listen 80;
server_name awecode.com;
#access_log /home/user/logs/nginx.access.log;
error_log /home/user/logs/nginx.error.log;
#limit_conn conn_limit_per_ip 100;
#limit_req zone=req_limit_per_ip burst=100 nodelay;
location /robots.txt {
alias /home/user/static/robots.txt;
}
location /favicon.ico {
alias /home/user/static/img/favicon.ico;
}
location ~ ^/(media|static)/ {
root /home/user/;
expires 30d;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://django_project;
client_max_body_size 50m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options SAMEORIGIN;
}
# Prevent hidden files (beginning with a period) from being served
location ~ /\. { access_log off; log_not_found off; deny all; }
}
Soft-link our configuration to nginx conf.d
directory
sudo ln -s /home/user/conf/nginx.conf /etc/nginx/conf.d/django_project.conf
Obtain SSL certificate with Certbot
apt install certbot python-certbot-nginx
certbot --nginx
Check configuration and restart nginx
nginx -t
systemctl restart nginx