DigitalOcean is a Virtual Private Server (VPS) provider. In my opinion it’s a great service to get started. It’s cheap and very simple to setup. In this tutorial I will guide you through the steps I go to deploy a Django application using Ubuntu 16.04, Git, PostgreSQL, NGINX, Supervisor and Gunicorn.
In this tutorial we will be deploying the following Django application: github.com/sibtc/urban-train
It’s just an empty Django project I created to illustrate the deployment process. If you are wondering about the name, it is the repository name suggestion GitHub gave.
If you don’t have a DigitalOcean account yet, you can sign up using the link below and get $10 credit to get started:
Get $10 free credit on DigitalOcean. (Disclaimer: this is referral link, meaning you and me get credit.)
Anyway! Let’s get started.
Create a New Droplet
Pick the Ubuntu 16.04.1 distribution:
Select the size of the Droplet (cloud server):
Select the region you want to deploy:
Finally pick a name for the Droplet:
And click on Create. After that you will see the recently created droplet in your profile:
You will receive the root password via email. Now pick the IP Address and ssh into the server:
You will be asked to change the root password upon the first login.
If you are using a Unix-like operating system you can use the terminal. If you are on Windows, you can perhaps download PuTTY.
Also if you prefer, you can use the Digital Ocean’s console:
Installing the Server Dependencies
First thing let’s upgrade the packages:
Install the dependencies to use PostgreSQL with Python/Django:
Install the PostgreSQL Server:
Install NGINX, which will be used to serve static assets (css, js, images) and also to run the Django application behind a proxy server:
Supervisor will start the application server and manage it in case of server crash or restart:
Enable and start the Supervisor:
The Django application will be deployed inside a Python Virtualenv, for a better requirements management:
Configure PostgreSQL Database
Create a database user and the application database:
PS: Make sure to pick a secure password! I’m using 123 for simplicity sake.
We can now go back to the root user, simply exit:
Configure The Application User
Create a new user with the command below:
Usually I just use the application name. You will be asked a few questions. Sample of the output below:
Add the user to the list of sudoers:
Switch to the recently created user:
Configure the Python Virtualenv
At this point we are logged in with the urban user (or whatever named you selected). We will install our Django
application in this user’s home directory
Clone the repository:
This is how the
/home/urban directory should look like at the moment:
First open the urban-train directory:
Install the project’s dependencies:
At this point you will need to set the database credentials in the settings.py file:
PS: There are better and secure ways to handle SECRET_KEY, database credentials etc. I’m editing it directly in the settings.py file for the sake of simplicity. The focus of this tutorial is on the deployment process itself.
Migrate the database:
Collect the static files:
Test if everything is okay:
Access the IP Address of your server using port 8000. In my case, 18.104.22.168:8000.
This is just a test. We won’t be using the
runserver to run our application. We will be using a proper application
server to securely serve our application.
CONTROL-C to quit the development server and let’s keep moving forward.
First install Gunicorn inside the virtualenv:
Create a file named gunicorn_start inside the bin/ folder:
And add the following information and save it:
Make the gunicorn_start file is executable:
Create a directory named run, for the unix socket file:
Now what we want to do is configure Supervisor to take care of running the gunicorn server.
First let’s create a folder named logs inside the virtualenv:
Create a file to be used to log the application errors:
Create a new Supervisor configuration file:
Reread Supervisor configuration files and make the new program available:
Check the status:
Now you can control your application using Supervisor. If you want to update the source code of your application with a new version, you can pull the code from GitHub and then restart the process:
urban-train will be the name of your application.
Add a new configuration file named urban inside /etc/nginx/sites-available/:
Create a symbolic link to the sites-enabled dir:
Remove NGINX default website:
The Final Test
Alright! At this point your application should be up and running! Open the web browser and access it:
A final test I like to run is rebooting the machine and see if everything restarts automatically:
Wait a few seconds. Access the website via browser. If it loads normally, means everything is working as expected! All the process are starting automatically.
Updating the Application
Usually that’s the process you will follow when you want to update your Django application:
I just wanted to take you through the basic steps of a deployment using Digital Ocean. Actually, for the most part the basic steps will be the same for pretty much every cloud provider.
Please note that there are lots of details regarding security, performance, how you should manage the sensitive data of your application, SSL certificate installation and so on.
I highly recommend reading all the available documentation about deployment on the official Django Docs. Also it’s very important to learn about the tooling you are using. Gunicorn, NGINX, Ubuntu, Supervisor, etc.
- Django Docs: Deployment checklist
- Deploying Gunicorn
- NGINX Pitfalls and Common Mistakes
- Initial Server Setup, Root Login, etc
- How to Setup a SSL Certificate on Nginx for a Django Application
- Separating settings from code (database information, security key, allowed hosts, etc)
I hope you enjoyed this tutorial! If you have any question, please leave a comment below!
Even though I’m sharing a referral link, I truly recommend their service (this blog itself is hosted there) and I have several Django applications deployed on DigitalOcean. I find it very inexpensive and ridiculously easy to setup.