Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
This is every step, in detail, to create a Django App with Postgres, NGINX, Gunicorn, and HTTPS on Digital Ocean. The only thing I don't go over is how to create a droplet and manage the domain.
Django/Postgres/Nginx/Gunicorn in Ubuntu:
Where you see "user", "myproject" and "myprojectuser" replace that with what is relevent to what you are working on.
User Setup
Complete login process
$ adduser demo - Creates new user
Complete new user process
$ gpasswd -a demo sudo - add new user to root group
Secure Server - SSH
$ cat ~/.ssh/
Copy key to clipboard
$ su - demo - switch to new user
$ mkdir .ssh - create ssh dir in new user home
$ chmod 700 .ssh - make it accessable
$ vim .ssh/authorized_keys to create file
Paste key in file
$ chmod 600 .ssh/authorized_keys to restrict permissions
$ exit - to return to root
$ vim /etc/ssh/sshd_config
Change PermitRootLogin to no
Change PasswordAuthentication to no
$ sudo service ssh restart to restart ssh
Test that you can login with SSH and the new user in a new terminal window BEFORE you logout of the ROOT user
Secure Server - Basic Firewall
$ sudo ufw allow ssh - Allows SSH
$ sudo ufw allow 80/tcp - for HTTP
$ sudo ufw allow 443/tcp - for SSL
$ sudo ufw show added - to show what was changed
$ sudo ufw enable - enable firewall
Setup Timezone and NTP
$ sudo dpkg-reconfigure tzdata
Set to timezone for local (or for choice)
$ sudo apt-get update - Because this is the first time you are running this it will be big
$ sudo apt-get install ntp
For Python 3
sudo apt-get install python3-pip libpq-dev postgresql postgresql-contrib nginx build-essential libssl-dev libffi-dev python3-dev python3-venv
Create Postgres DB and User
$ sudo su - postgres
$ psql - login to server
$ CREATE DATABASE myproject;
$ CREATE USER myprojectuser WITH PASSWORD 'password';
$ ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
$ ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
$ ALTER ROLE myprojectuser SET timezone TO 'UTC';
$ GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
$ \q to quit
$ exit to exit
Setup VE
$ mkdir ~/envs to create dir
$ cd ~/envs to cd into the virtualenvs
$ python3 -m venv myproject
$ source myproject/bin/activate - to fire up the env
Create SSH key for Git
$ ssh-keygen -t rsa -b 4096 -C ""
$ eval "$(ssh-agent -s)"
$ vim ~/.ssh/ - Copy the Key
Follow these instructions to add key to Github account:
Get project and install requirements
$ git clone
$ cd projectname/
In case you don’t have your VE enabled, $workon vename
$ pip install -r requirements/base.txt - Obviously, this will depend on how you have your requirements setup
If error: sudo apt-get install python-dev sudo apt-get install libncurses5-dev
$ python check - to ensure everything is right
$ python migrate - to install DB
$ python createsuperuser - create superuser
$ python createcachetable - If applicable
$ gunicorn --bind production - to test the gunicorn setup
Create an Upstart Script
$ mkdir ~/run to create the dir where the sock file will live
$ sudo vim /etc/systemd/system/gunicorn.service
Description=gunicorn daemon
ExecStart=/home/dave/envs/myproject/bin/gunicorn --workers 3 --bind unix:/home/dave/run/myproject.sock production
$ sudo systemctl start gunicorn
$ sudo systemctl enable gunicorn
Configure NGINX
# sudo vim /etc/nginx/sites-available/myproject
server {
listen 80;
access_log /home/user/logs/nginx/nginx-access.log;
error_log /home/user/logs/nginx/nginx-error.log;
client_max_body_size 4G;
server_name domain_name_or_ip;
root /home/user/myproject;
keepalive_timeout 5;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
alias /home/user/myproject/static;
location /uploads {
alias /home/user/myproject/uploads;
error_page 500 502 503 504 /500.html;
location = /500.html {
alias /home/user/myproject/templates;
location / {
include proxy_params;
proxy_pass http://unix:/home/user/myproject/project.sock;
2. $ sudo mkdir -p ~/logs/nginx/
3. $ sudo nginx -t
4. $ sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
5. $ sudo systemctl restart nginx
7. $ sudo ufw allow 'Nginx Full'
SSL Certificate:
Just go here: and do what it says.
8. $ sudo systemctl restart nginx
You’re done!

This comment has been minimized.

Copy link

@jefftriplett jefftriplett commented Aug 10, 2020


Have you played with DO's built-in firewall? I tried it out this weekend and it worked really well for me. It prevents traffic from ever getting to your boxes with is a nice bonus.


This comment has been minimized.

Copy link

@shariq1989 shariq1989 commented Aug 14, 2020

Have you used certbot/SSL on an IP address? Or always on a named domain?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment