@maxgonpe
For Python 3, my test consisted of the following commands. I used max
as the username here since that’s what you wanted to use, so you should be able to simply copy and paste my commands in to terminal (MacOS), PuTTy (Windows), etc.
You can copy and paste multi-line commands directly in as well (I use them to prevent having to enter in single line commands and speed things up a bit).
sudo apt-get update \
&& sudo apt-get -y dist-upgrade \
&& sudo apt-get -y install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx \
&& sudo pip3 install virtualenv \
&& pip3 install --upgrade pip
mkdir -p /home/max/myproject \
&& useradd -d /home/max max
cd /home/max/myproject \
&& virtualenv myprojectenv \
&& source myprojectenv/bin/activate \
&& pip install django gunicorn psycopg2 \
&& django-admin.py startproject myproject .
nano myproject/settings.py
Find ALLOWED_HOSTS = []
and add your Droplet’s Public IPv4 IP there so that it looks like this (change 111.222.333.444
to your IP).
ALLOWED_HOSTS = ['111.222.333.444']
Find:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Replace it with (I used the defaults, you’ll need to change NAME
, USER
, PASSWORD
to match).
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
At the bottom of the file, find STATIC_URL = '/static/'
and directly below it add:
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
CTRL + X and save the file. Then run:
./manage.py makemigrations \
&& ./manage.py migrate \
&& ./manage.py createsuperuser
You’ll be asked to create a user. Choose whatever username and password you’d like. That’s what you’ll login to the admin panel with once the project is live.
./manage.py collectstatic
For the time being, skip all the firewall rules in the guide. With Ubuntu, ufw
(the firewall) is off by default, so let’s not worry about those rules just yet. Well move on to the rest of the setup.
Let’s make sure the project can be served now.
./manage.py runserver 0.0.0.0:8000
If you can access the project on port 8000, let’s see if Gunicorn works now. Hit CTRL + C to exit the server.
gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
If that works too, so far so good :-). Hit CTRL + C to exit the server and then run deactivate
to kill off the virtual env.
Now we need to make sure all the files inside the home directory are owned by max
otherwise the systemd
file we create will fail to create the socket. So let’s run:
chown -R max:max /home/max/*
Now we’ll setup the systemd
file.
sudo nano /etc/systemd/system/gunicorn.service
Within that paste in:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=max
Group=max
WorkingDirectory=/home/max/myproject
ExecStart=/home/max/myproject/myprojectenv/bin/gunicorn --workers 3 -u max -g max --bind unix:/home/max/myproject/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Hit CTRL + X and save the file. Now run:
sudo systemctl start gunicorn && sudo systemctl enable gunicorn
Now we’ll setup the NGINX server block:
sudo nano /etc/nginx/sites-available/myproject
Within that file, paste:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/max/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/max/myproject/myproject.sock;
}
}
You need to change server_name server_domain_or_IP;
by replacing server_domain_or_IP
with the IP of your Droplet. So it should look like:
server_name 111.222.333.444;
Where 111.222.333.444
is your IP. CTRL + X and save the file.
Create the required symlink:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Test the configuration:
sudo nginx -t
Restart NGINX:
sudo systemctl restart nginx
You’ll need to refer back to the guide on setting up the Postgres Database, though the above should get you up and working with Python 3. I just tested this with each of the commands I just used above.