If you enter your server and project details on this page, the list of commands below the form will automatically update (it's using JavaScript; nothing is being saved, I promise!)
Because launching a new website on a new server from scratch can be quite the task (over 50 steps!) the idea is you can copy/paste your server and project details into this form and get a list of commands to run by copying and pasting most of the code that's generated for you.
ssh root@167.172.xxx.xx
adduser newuser
usermod -aG sudo newuser
ufw app list
ufw allow OpenSSH
ufw enable
ufw status
rsync --archive --chown=newuser:newuser ~/.ssh /home/newuser
ssh newuser@167.172.xxx.xx
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
sudo -u postgres psql
CREATE DATABASE your_db_name;
CREATE USER your_db_user WITH PASSWORD 'your_db_password';
ALTER ROLE your_db_user SET client_encoding TO 'utf8';
ALTER ROLE your_db_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE your_db_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE your_db_name TO your_db_user;
\q
sudo -H pip3 install --upgrade pip && sudo -H pip3 install virtualenv
mkdir ~/yourprojectname && cd ~/yourprojectname
git clone https://github.com/your-repo-url/ .
virtualenv .venv
source .venv/bin/activate
pip install gunicorn psycopg2-binary
pip install -r requirements.txt
python manage.py collectstatic --settings=yourprojectname.settings.production
python manage.py runserver 0.0.0.0:8000 --settings=yourprojectname.settings.production
At this point you should see migrations are required.
export DJANGO_SETTINGS_MODULE='yourprojectname.settings.production'
Re run the server and we no longer need to specify a settings file
python manage.py migrate
python manage.py createsuperuser
sudo ufw allow 8000
python manage.py runserver 0.0.0.0:8000
Go to http://167.172.xxx.xx:8000/ and you'll see it at least loads.
It'll look terrible, but it works!
cd ~/yourprojectname
gunicorn --bind 0.0.0.0:8000 yourprojectname.wsgi
deactivate
sudo nano /etc/systemd/system/gunicorn.socket
Add this to it:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
sudo nano /etc/systemd/system/gunicorn.service
And add this into it:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=newuser
Group=www-data
WorkingDirectory=/home/newuser/yourprojectname
ExecStart=/home/newuser/yourprojectname/.venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
yourprojectname.wsgi:application
[Install]
WantedBy=multi-user.target
sudo systemctl start gunicorn.socket && sudo systemctl enable gunicorn.socket
sudo systemctl status gunicorn.socket
Should say active listening
file /run/gunicorn.sock
sudo systemctl status gunicorn
You should see INACTIVE DEAD
curl --unix-socket /run/gunicorn.sock localhost
You should see the html output of your site.sudo systemctl daemon-reload && sudo systemctl restart gunicorn
sudo nano /etc/nginx/sites-available/yourprojectname
And add this:
server {
listen 80;
listen [::]:80;
server_name 167.172.xxx.xx;
charset UTF-8;
error_log /home/newuser/yourprojectname/nginx-error.log;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/newuser/yourprojectname/static/;
}
location /media/ {
alias /home/newuser/yourprojectname/media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
sudo ln -s /etc/nginx/sites-available/yourprojectname /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
sudo ufw delete allow 8000 && sudo ufw allow 'Nginx Full'
sudo nano /etc/nginx/sites-available/yourprojectname
Replace 167.172.xxx.xx with yourwebsite.com
sudo nginx -t
sudo systemctl restart nginx
sudo nano yourprojectname/settings/production.py
Add yourwebsite.com to the ALLOWED_HOSTS
and
Remove the ip address of 167.172.xxx.xx