Tutorial

How To Use the Django One-Click Install Image for Ubuntu 14.04

How To Use the Django One-Click Install Image for Ubuntu 14.04

This tutorial is out of date and no longer maintained.

Status: Deprecated

This article is no longer being maintained. It uses a One-Click app that has been deprecated.

See Instead: An updated version of this article is available here: How To Use the Django One-Click Install Image for Ubuntu 16.04. It uses the Django 1.8.7 on Ubuntu 16.04 One-Click app instead.

Django is a high-level Python framework for developing web applications rapidly. DigitalOcean’s Django One-Click app quickly deploys a preconfigured development environment to your VPS employing Django, Nginx, Gunicorn, and Postgres.

Creating the Django Droplet

To use the image, select Django on Ubuntu 14.04 from the Applications menu during droplet creation:

One-Click Apps

Once you create the droplet, navigate to your droplet’s IP address (http://your.ip.address) in a browser, and verify that Django is running:

It worked!

You can now login to your droplet as root and read the Message of the Day, which contains important information about your installation:

MOTD

This information includes the username and password for both the Django user and the Postgres database. If you need to refer back to this latter, the information can be found in the file /etc/motd.tail

Configuration Details

The Django project is served by Gunicorn which listens on port 9000 and is proxied by Nginx which listens on port 80.

Nginx

The Nginx configuration is located at /etc/nginx/sites-enabled/django:

upstream app_server {
    server 127.0.0.1:9000 fail_timeout=0;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    client_max_body_size 4G;
    server_name _;

    keepalive_timeout 5;

    # Your Django project's media files - amend as required
    location /media  {
        alias /home/django/django_project/django_project/media;
    }

    # your Django project's static files - amend as required
    location /static {
        alias /home/django/django_project/django_project/static; 
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server;
    }
}

If you rename the project folder, remember to change the path to your static files.

Gunicorn

Gunicorn is started on boot by an Upstart script located at /etc/init/gunicorn.conf which looks like:

description "Gunicorn daemon for Django project"

start on (local-filesystems and net-device-up IFACE=eth0)
stop on runlevel [!12345]

# If the process quits unexpectedly trigger a respawn
respawn

setuid django
setgid django
chdir /home/django

exec gunicorn \
    --name=django_project \
    --pythonpath=django_project \
    --bind=0.0.0.0:9000 \
    --config /etc/gunicorn.d/gunicorn.py \
    django_project.wsgi:application

Again, if you rename the project folder, remember to update the name and pythonpath in this file as well.

The Upstart script also sources a configuration file located in /etc/gunicorn.d/gunicorn.py that sets the number of worker processes:

"""gunicorn WSGI server configuration."""
from multiprocessing import cpu_count
from os import environ


def max_workers():
    return cpu_count() * 2 + 1

max_requests = 1000
worker_class = 'gevent'
workers = max_workers()

More information on configuring Gunicorn can be found in the project’s documentation.

Django

The Django project itself is located at /home/django/django_project It can be started, restarted, or stopped using the Gunicorn service. For instance, to restart the project after having made changes run:

service gunicorn restart

While developing, it can be annoying to restart the server every time you make a change. So you might want to use Django’s built in development server which automatically detects changes:

service gunicorn stop
python manage.py runserver localhost:9000

While convenient, the built in server does not offer the best performance. So use the Gunicorn service for production.

Writing Your First Django App

There are many resources that can provide you with an in-depth introduction to writing Django applications, but for now let’s just quickly demonstrate how to get started. Log into your server and switch to the django user. Now let’s create a new app in the project:

cd /home/django/django_project
python manage.py startapp hello

Your directory structure should now look like:

.
├── django_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── hello
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── manage.py

Next, we’ll create our first view. Edit the file hello/views.py to look like:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world! This is our first view.")

Then, we can connect that view to a URL by editing django_project/urls.py

from django.conf.urls import patterns, include, url
from hello import views
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^admin/', include(admin.site.urls)),
)

After that, we can restart the project as root: service gunicorn restart

If you reload the page, you’ll now see:

Hello, world!

Next Steps

<div class=“author”>By Andrew Starr-Bochicchio</div>

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products


Tutorial Series: DigitalOcean 1-Click Application Images

This series links all of the DigitalOcean 1-Click Application images into a cohesive list. Articles are listed in the order that the images are shown on the create droplet screen. New articles are added as more application images are published.

About the authors
Default avatar
Andrew SB

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
10 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Andrew Starr-Bochicchio thank you. Nginx and Gunicorn have been so hard for me to get working. I’ve spent far more time being a server admin rather than a developer it seems like. (I’m a developer) I’ve actually just gave up on projects and shut down droplets for weeks at a time cause I couldn’t get Nginx and Gunicorn to work. It made me give up on python and go back to PHP. Hours and hours and hours plugging away trying to figure out what was wrong and seeing that dreaded 502 bad gateway page so many times I could hardly stand the thought of refreshing my browser. And after a solid 2 months of going to work for 8 hrs a day writing PHP hurrying home to login and spend all my evenings working on it trying everything in the world. It finally worked when I changed the Django projects owner to www-data! A simple but key piece that it seemed no one had mentioned. Again I’m a developer not a linux admin. When it finally worked I was all out of steam and it would be another 2 months before I could go back to working on this app. In the last week I’ve finally gathered the willpower to get back to working on it. And then today I get the email that this is now a droplet image preconfigured. So I guess the next step is to destroy my droplet and redeploy with yours haha! But any who. Thanks this made me happy today.

Hi! I use this image but I get the 502 error.

In the Gunicorn Upstart script what does the parameter ‘name’ stands for?

Andrew SB
DigitalOcean Employee
DigitalOcean Employee badge
May 29, 2014

@genofongenofon: The <code>–name</code> flag adjusts the name of Gunicorn process. It’s often used so that the name of the process appears as the Django app rather than just gunicorn. We use <code>–name=django_project</code> because the default project we made is just called “django_project”

@Andrew SB thanks!

If I can ask another thing: how can I log the errors (in gunicorn and/or Nginx)?

I tried to add --log-level=error --log-file=$LOGFILE \ in gunicorn specifying LOGFILE=errors.log but it doesn’t work.

Andrew SB
DigitalOcean Employee
DigitalOcean Employee badge
May 30, 2014

@genofongenofon: Upstart logs the Gunicorn job at <code>/var/log/upstart/gunicorn.log</code> while the Nginx logs are in their standard location: <code>/var/log/nginx/error.log</code>

What is the suggested droplet size for this application?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
June 5, 2014

@burlingk: It depends on the size of your application. You can start off with 512MB and upgrade later on if need be.

for anyone else having issues with static files, try this: sudo service nginx restart

Hi, I got this image working out-of-the-box but I am trying to run my own django app on the server now and I’m getting a 502 Bad Gateway error.

I created a virtualenv in the django folder and cloned my git repository into the root of the virtualenv (/django/myenv/myapp/).

I’ve altered my gunicorn.conf as follows: <pre> chdir = /home/django/myenv exec gunicorn
–name=myapp/app –pythonpath=myapp … myapp/app.wsgi:application </pre> I’ve been restarting both nginx and gunicorn after every change.

I’m thinking somewhere in there my syntax is a little off, if you could help me get in the right direction that would be greatly appreciated, thanks.

What the simplest way to set environmental variables such that they will be seen by django when running under this nginx/gunicorn/upstart environment? I have all my database config in the environmental variables and pull them into the django config via e.g. <pre> ‘USER’: os.environ[‘DJ_DB_USER’], ‘PASSWORD’: os.environ[‘DJ_DB_PASSWORD’], </pre> This runs fine if I source the config file that sets these environmental variable then run the django development server (runserver) but I can’t work out how to set them using nginx/gunicorn. I tried sourcing within the configs for these but can’t guess the correct syntax (if this is even possible).

How should I go about maintaining the separation between the app code and these deployment settings?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.