Report this

What is the reason for this report?

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

Published on May 16, 2014
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.

Still looking for an answer?

Was this helpful?
Leave a comment...

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?

@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.

@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?

@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?

@dobbs: If you’re using the same project layout, it would be: <pre> chdir /home/django

exec gunicorn
–name=myapp
–pythonpath=myapp
–bind=0.0.0.0:9000
–config /etc/gunicorn.d/gunicorn.py
app.wsgi:application </pre>

@mattjamesfrancis: You can do it by editing the Upstart script that launches Gunicorn. Instead of exec (which will only run one command), you can use script. Then you need to pass it on to Gunicorn as well. So it would look like:

script
    source /path/to/file
    export USER
    export PASSWORD
    gunicorn \
        --name=django_project \
        --pythonpath=django_project \
        --bind=0.0.0.0:9000 \
        --config /etc/gunicorn.d/gunicorn.py \
        --env USER=$USER PASSWORD=$PASSWORD
        django_project.wsgi:application
end script

Would you please recommend how to scale this tutorial for multiply domains/projects at one droplet?

Where is the default environment directory? Where is django installed?

If I try to install any other packages, where would the end up by default? Is there anyway to change the default setting for that somewhere or some how?

Okay, I think I found it …

django, along with all other pre-installed packages, are installed in “/usr/lib/python2.7/dist-packages” directory

My guess is that any other packages that I may need to install would go in “/usr/local/lib/python2.7/site-packages” directory ------ OR ------- does it go to “/usr/local/lib/python2.7/dist-packages” directory?

If someone could confirm this for me, I’d really appreciate it. Thanks a bunch.

@xhannan: Django is installed installed system-wide via apt I’d recommend using apt to install any needed dependencies if they are available in the repository. pip is also installed. If you’re installing things manually, you want /usr/local/lib/python2.7/dist-packages Though the setup.py file should just “do the right thing.”

Hi, I followed all the above steps and got the app up, But the static files are not getting served , So no css/js files is accessible: Here is the IP of the server: http://128.199.139.199/ Project Name is: kosmoderma App Name is: app_kosmo

My settings.py:

STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
STATIC_URL = '/assets/'

MEDIA_ROOT= os.path.join(BASE_DIR,'media')
MEDIA_URL='/media/'

STATICFILES_DIRS=(
    (os.path.join(BASE_DIR,'static')),
)

I have already run collectstatic and all the files are under assets directory. So i made the following changes in the nginx config file:

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/kosmoderma/media/;
    }

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

    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;
    }
}

I need help urgently as I am supposed to get this website live by today.

@prajjwal1988: Your website is loading fine for me. Are you still experiencing this issue?

@warrenbeyda - you probably don’t want www-data to own python script folders in case Nginx gets exploited. In this configuration Nginx is proxying for gunicorn so all they can “exploit” is a collection of cache files that aren’t executable. That means if someone actually managed to break the Nginx they wouldn’t be able to run arbitrary python scripts and since the www-data user doesn’t have write access to the Django files all is good.

so I uploaded my app and started working on my project, but things all seem broken compared to my local dev. So I just destroyed and am starting fresh. All the versions of things match up, the only major difference is going to be NGINX, and i was using a virtualenv on my local box. Anyways I had a lot of difficulties getting the static files to be where they needed to be first. I had to change the nginx config file to reflect the location static/ alias /home/django/django_project/static; instead of the default alias /home/django/django_project/django_project/static; which seems pretty odd to me. Anyways, another thing I’ve noticed is my django admin isn’t having it’s css load either. I am on a fresh install of this Django image, created a superuser , and am going to myip/admin to login just fine, but no css applied. I haven’t made any changes on this install, just created a superuser in the django_project/ and logged in. I’ve ran manage.py collectstatic to see if that helps at all. It seems weird this isn’t working right out of the box though. Any assistance would help. Thanks.

Thank you for this! Quick question, does this installation include all of the required GeoDjango and PostGIS related extensions?

Nevermind - it was just my nginx config file. Still pretty strange it’s setup that way by default. Other than that - this is awesome. Saved me tons of time :)

The default, out-of-the-box setup does not seem to link django admin static files properly… I fixed it by adding

location /static/admin {
        alias /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin;
    }

To /etc/nginx/sites-enabled/django (and restarting nginx)

Was that the correct way to fix it? Or does the django app have something that fixes it automatically?

@bensnik, I do a collectstatic and point it to that directory

Hi,

Thanks for the great tutorial. The only thing that’s bothering me is that you installed Python 2.7.6. on this preconfigured image. I’ve been studying python lately and it was version 3.4.1. Does porting a Django 1.6.1 project to Python 3 only requires installing 3.4.1 in addition to the 2.7.6 version installed on this image, or is it something really tricky requiring to modify almost everything ?

Take care

I tried adding my own project:

/home/django/myproject

But the default project screen keeps coming up for:

/home/django/django_project

I have repointedgunicorn.confto the “myproject” directory, as well as /etc/nginx/sites-enabled/myproject.

My question is, does the default site in /etc/nginx/sites-available affect anything if it is not linked to /etc/nginx/sites-enabled?

Is the “django_app” for gunicorn linked to any other files that I need to config to get it working?

It doesn’t show a server error. It just keeps showing the default django start up screen for a new project, instead of the project that I have created.

thanks

HELP!! I need to run my django 1.7 app under python 3.4. I think I need to edit the /etc/init/gunicorn.conf to use a different virtualenv, right?

So, I’ve create one with:

$ mkdir ~/venvs/
$ virtualenv -p /usr/bin/python3.4 ~/venvs/webapp
$ source ~/venvs/webapp/bin/activate
$ ~/venvs/webapp/bin/easy_install -U gunicorn
$ deactivate

And I don’t know how to make my /etc/init/gunicorn.conf use this new virtualenv. Any tip?

How on Earth do I restart Gunicorn? Instructions restarting using service seem outdated:

stop: Unknown job: gunicorn
start: Unknown job: gunicorn

What is supposed to be the password for the django user? (And do I really need to log on as that user when developing in this environment?)

I tried both passwords listed in my motd, but to no avail.

edit: I mean I can use my regular user and sudo, but I don’t think that’s intended :)

I cannot login to the Django admin I did create the super super I do not know whats the problem

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

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.