Django Deployment Assistant

First, create the instance in DigitalOcean!
Phase 1: Initial Server Setup
sudo apt update && sudo apt full-upgrade -y sudo reboot adduser USER && usermod -aG sudo USER
Firewall setup:
ufw app list && ufw allow OpenSSH && ufw enable
SSH Key Migration:
mkdir -p /home/USER/.ssh && cp ~/.ssh/authorized_keys /home/USER/.ssh/ && chown -R USER:USER /home/USER/.ssh && sudo usermod -aG www-data
PWless sudo:
sudo visudo
Add last of all:
ALL=(ALL) NOPASSWD: ALL logout
Phase 2: Core Dependencies
Install Core Dependencies:
sudo apt update && sudo apt install -y python3-pip python3-dev python3-venv nginx && sudo ufw allow 'Nginx Full'
Set Nginx user to your SSH user:
sudo systemctl stop nginx && sudo nano /etc/nginx/nginx.conf
Change these lines:
http { sendfile on; tcp_nopush on; server_tokens off; proxy_headers_hash_max_size 1024; proxy_headers_hash_bucket_size 128; server_names_hash_bucket_size 128; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
Phase 3: Aliases & Environment
sudo nano ~/.bash_profile PS1=' » ' alias s="source ~/.env/bin/activate" alias d="deactivate" alias r="sudo systemctl restart " alias l="pip3 list" alias o="pip3 list --outdated" alias u="pip3 install -U " alias req="pip3 install -r requirements.txt" alias res="sudo systemctl restart nginx && sudo systemctl restart " alias cs="python3 manage.py collectstatic --noinput" alias run="python3 manage.py runserver 0.0.0.0:8000" alias mkmig="python3 manage.py makemigrations" alias mig="python3 manage.py migrate" alias klear="find . -name \*.pyc -delete && find . -name \*.DS_Store -delete && find . -name \*__pycache__ -delete" alias klearmigs="find . -path \"*/migrations/*.py\" -not -name \"__init__.py\" -delete && find . -path \"*/migrations/*.pyc\" -delete" alias fakemig="python3 manage.py makemigrations && python3 manage.py migrate --fake-initial" . ~/.bash_profile
Python VirtualEnv setup:
python3 -m venv .env && source ~/.env/bin/activate && pip3 install -U pip gunicorn Django
Phase 4: Django Project Setup
django-admin startproject PROJECT
Update ALLOWED_HOSTS in settings.py:
ALLOWED_HOSTS = ['IP', 'localhost', 'DOMAIN'] cd PROJECT && pip3 install -r requirements.txt && gunicorn --bind 0.0.0.0:8000 PROJECT.wsgi && deactivate
Phase 5: Gunicorn Systemd
Socket Config:
sudo nano /etc/systemd/system/PROJECT.socket [Unit] Description=gunicorn socket [Socket] ListenStream=/run/.sock SocketUser= SocketGroup=www-data SocketMode=0660 [Install] WantedBy=sockets.target
Service Config:
sudo nano /etc/systemd/system/PROJECT.service [Unit] Description=gunicorn daemon Requires=.socket After=network.target [Service] User= Group=www-data WorkingDirectory=/home// Type=notify UMask=0007 Restart=on-failure RestartSec=5s ExecStart=/home//.env/bin/gunicorn \ --access-logfile - \ --workers 5 \ --bind unix:/run/.sock \ .wsgi:application [Install] WantedBy=multi-user.target sudo systemctl daemon-reload && sudo systemctl restart .socket && sudo systemctl restart .service && sudo systemctl status .service sudo systemctl start && sudo systemctl enable && sudo systemctl status && file /run/.sock sudo systemctl status && sudo systemctl daemon-reload && sudo systemctl restart && sudo systemctl status
Phase 6: Nginx Server Block
sudo nano /etc/nginx/sites-available/PROJECT server { listen 80; listen [::]:80; server_name www.; return 301 https://$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name www.; ssl_certificate /etc/letsencrypt/live//fullchain.pem; ssl_certificate_key /etc/letsencrypt/live//privkey.pem; return 301 https://$request_uri; } server { listen 443 ssl; http2 on; server_name ; ssl_certificate /etc/letsencrypt/live//fullchain.pem; ssl_certificate_key /etc/letsencrypt/live//privkey.pem; access_log /var/log/nginx/_access.log; error_log /var/log/nginx/_error.log; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; location / { include proxy_params; proxy_pass http://unix:/run/.sock; proxy_set_header X-Forwarded-Proto $scheme; } # location /static/ { # root /home//bucket/; # } # location /media/ { # root /home//bucket/; # } # client_max_body_size 5M; } sudo ln -s /etc/nginx/sites-available/PROJECT /etc/nginx/sites-enabled sudo nginx -t && sudo systemctl daemon-reload && sudo systemctl restart nginx && sudo systemctl status nginx.service
Phase 7: Database
Connect to the DB with the user doadmin in TablePlus.
Database Permissions:
ALTER SCHEMA public OWNER TO DB_USER; GRANT ALL PRIVILEGES ON DATABASE DB_NAME TO DB_USER;
Alter DNS for "media." on DigitalOcean » Networking » Domains to point to the Droplet.
Phase 8: SSL
Certbot Installation:
sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/bin/certbot sudo certbot --nginx -d DOMAIN -d www.DOMAIN
Certbot Renewal:
sudo systemctl status snap.certbot.renew.service && sudo certbot renew --dry-run &&sudo systemctl reload nginx
List certificates:
sudo certbot certificates
Delete certificates:
sudo certbot delete --cert-name DOMAIN
Verify Domain Configuration:
Phase 9: Root Deactivation & Security
Check User (Expected: root):
sudo whoami
Deactivate root:
sudo nano /etc/ssh/sshd_config
Change "#Port 22" to "Port 2244".
Change "PermitRootLogin" to "PermitRootLogin no".
Change "PasswordAuthentication" to "PasswordAuthentication no".
Change "PubkeyAuthentication" to "PubkeyAuthentication yes".
sudo ufw allow 2244/tcp && sudo ufw delete allow 22/tcp && sudo ufw reload sudo passwd -l root && sudo systemctl restart ssh
Install Fail2Ban:
sudo apt update && sudo apt install fail2ban -y && sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local && sudo nano /etc/fail2ban/jail.local
Change:
[sshd] enabled = true port = 2244 logpath = %(sshd_log)s backend = %(sshd_backend)s maxretry = 3 findtime = 10m bantime = 1h sudo systemctl restart fail2ban
New Terminal: SSH with port 2244
ssh -p 2244 @