Setting up Django on Ubuntu with Apache and mod_wsgi and virtualenv
Published on by nick
Thanks to Ayman Farhat for the starting points.
Since I wrote this article quite a while ago, I have deployed several Apache servers running mod_wsgi and Django since. While this article can probably get you going to run your own Django web site and application, it is missing some key ingredients. I know this because I frequently reference this article and Ayman's. To this effect, I have edited this post to reflect some new tips and tricks I have learned in the last couple years.
First thing you need is a server running Ubuntu (I've deployed this on 12.04, but I'm sure the process is very similar on 13.04/13.10). I created an account at Digital Ocean and then made myself a droplet with Ubuntu 12.04 64-bit. This VM is ready to go with Python 2.7 pre-installed.
I'm running as root on the VM so I will leave out sudo but keep in mind that if you aren't running as root, the sudo command will be required in some cases.
Start by updating the repository:
apt-get update
I use vim throughout, so make sure your editor is installed:
apt-get install vim
Then let's install PIP:
apt-get install python-pip python-dev build-essential
You may need to run with --fix-missing if the command doesn't work.
Let's update PIP:
pip install --upgrade pip
You will also need MySQL or another SQL database. Check Django's docs for databases. I'm using MySQL for this tutorial:
apt-get install mysql-server
Another great choice that includes a web UI for administration of MySQL databases is Bitnami's Lampstack.
If required, follow the prompts to set up your MySQL database. Later on, we will create a database and user, if required, for the Django project.
virtualenv is a tool for creating isolated Python environments. My experience with virtualenv is limited but you can read more about it here.
Then on top of that there is virtualenvwrapper, which can help us manage our virtual environments. When you install virtualenvwrapper, virtualenv is installed as a dependency.
Let's install it, then...
pip install virtualenvwrapper
NOTE: in my case, I had to run pip from the complete path: /usr/local/bin/pip, although this certainly is not required in all cases. When your virtual environment is set up correctly, and installed in the default location in your development directory (this should be in your /home/user path somewhere), it's only necessary to run pip. COnfirm it's in your path as well.
Next, let's set the location where to save these virtual environments (I like vim):
vim ~/.bash_profile
To make activating the virtual environment easier, you can run the bin/activate command with a shortcut. Set the following (depending where you set up your virtual environment. In this example, I chose /home/django):
export WORKON_HOME=/home/django/virtualenv source /usr/local/bin/virtualenvwrapper.sh
Reload your bash_profile file:
source ~/.bash_profile
Now, let's create a virtual environment to work with:
mkvirtualenv /home/django/virtualenv/mysiteenv --no-site-packages
At this point you are ready to install Django or upload existing Django projects and then install Django. Let's run through this briefly.
First, switch to your virtual environment:
workon mysiteenv
To install Django with PIP:
pip install Django==1.5.1
To verify Django was installed, launch the interactive python shell and run these commands:
>>> import django >>> print(django.get_version()) 1.5.1
I should note here that sometimes you will have a Django project already started. In this case, hopefully you have a requirements.txt file already with all the dependencies for your project. If this is the case, you can easily install everything you need into your virtual environment by issuing the following command:
pip install -r requirements.txt
This will install all dependencies, including the version of Django specified.
If you haven't created a project or if you didn't bring one to the server, let's create one now. Create and change directory into where you want to store your projects. I chose /home/django_projects. Then, use Django to create the project files:
mkdir /home/django_projects cd /home/django_projects django-admin.py startproject mysite
Pretty much the first thing you want to do next is set up your database.
First, log in to MySQL and create a database:
mysql -u root -p******
At the MySQL command prompt:
CREATE DATABASE mysite; SHOW DATABASE;
Depending on your setup, you probably want to create a user and credentials for accessing the database you created:
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON mysite.* TO 'user'@'localhost';
Then edit your project's settings.py file (from where you were):
vim mysite/mysite/settings.py
NOTE: Sometimes it's easier to cd into the base of the project and then work from there. The commands would be this instead:
cd /home/django_projects/mysite vim mysite/settings.py
Edit the settings.py file with the database information we want:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # Using 'mysql' for this tutorial. 'NAME': 'mysite', # Database name. 'USER': 'root', # or 'user', described above 'PASSWORD': '******', 'HOST': '', # Empty for localhost. 'PORT': '', # Empty string for default. } }
Be sure to read the section notes on MySQL on the Django website. This gives information about installing the Python module for MySQL, MySQLdb.
Briefly, you need to run these commands (the order is important here for dependencies):
apt-get install python-mysqldb apt-get install libmysqlclient-dev pip install mysql-python
Note that I have encountered issues when setting up new virtual environments when I don't install python-mysqldb and libmysqlclient-dev before mysql-python. This has caught me a few times, so make sure this order is maintained.
Please note that this tutorial is based on Linux, but I know that some folks will end up here wanting details on how to make this work on Windows. Heck, I actually come back to this article myself from time to time for reminders. I also develop on Windows, so this is helpful for me too. Anyway, MySQLdb is easy to set up on Windows too:
easy_install mysql-python
For the INSTALLED_APPS to function in Django, you need database tables for them:
python manage.py syncdb
Now, let's install and configure Apache and mod_wsgi:
apt-get install apache2 apache2.2-common apache2-mpm-prefork apache2-utils libexpat1 apt-get install libapache2-mod-wsgi
This should automatically restart Apache but just to be sure, issue this command:
service apache2 restart
We need to now create a virtual host and set up WSGI. First, let's create the site in the Apache configuration:
Apache can be tricky to configure and each distribution can be set up differently by default. The first thing you want to do is investigate how your version was set up when you installed it. For example, Bitnami's Lampstacks use completely different file structure than the default version installed with Ubuntu's package manager. Depending on what file is the master Apache configuration, you may need to use different configuration files.
For instance, in my case, I'm using /etc/apache2/apache2.conf as main configuration, /etc/apache2/httpd.conf as user configuration and /etc/apache2/sites-enabled for virtual host configuration.
vim /etc/apache2/sites-enabled/mysite
The contents of this file should look like this:
<VirtualHost *:80> ServerAdmin [email protected] ServerName mysite.com ServerAlias www.mysite.com WSGIScriptAlias / /home/django_projects/mysite/mysite/wsgi.py <Directory /home/django_projects/mysite/mysite> <Files wsgi.py> Allow from all </Files> Options FollowSymLinks AllowOverride None </Directory> Alias /static/ /var/www/mysite/static/ <Location "/static/"> Options -Indexes </Location > </VirtualHost >
Then, the user defined configuration file:
vim /etc/apache2/http.conf
Should look something like this...
WSGIScriptAlias / /home/django_projects/mysite/mysite/wsgi.py WSGIPythonPath /home/django_projects/mysite/mysite/ # you should add the virtual environment as well: # /home/django_projects/virtualenv/mysiteenv/lib/python2.7/site-packages/ <Directory /home/django_projects/mysite/mysite> <Files wsgi.py> Order deny,allow Allow from all </Files> </Directory>
There are different ways to set up the WSGI part. The Django docs are a good place to start. And, as Ayman Farhat describes, you can create an index.wsgi and place this in the sites-available file for your site. In this case, I think going with the Django method is best, using the file referred to in the Virtual Host setup above:
vim /home/django_projects/mysite/mysite/wsgi.py
In it, add these lines (Django sets some default values, so consider this carefully):
import os import sys import site # Add the site-packages of the chosen virtualenv to work with site.addsitedir('~/.virtualenvs/mysiteenv/local/lib/python2.7/site-packages') # Add the app's directory to the PYTHONPATH sys.path.append('/home/django_projects/mysite') sys.path.append('/home/django_projects/mysite/mysite') os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
Let's then set where static files go for Django:
mkdir /var/www/mysite/static vim /home/django_projects/mysite/mysite/settings.py
Make sure these lines are set:
STATIC_ROOT = '/var/www/mysite/static/' STATIC_URL = '/static/'
Note that at this point, it might be necessary to edit permissions on your /var/www/mysite folder so static files can be written. To do this, you can edit permissions or change group access for Apache:
sudo chown root:www-data -R /var/www/mysite
Next, we need to tell Django to collect the static files for use on the site:
python manage.py collectstatic --noinput
Restart Apache again and you should be good to go:
service apache2 restart
Drop me a line...
[email protected]
Follow me on Twitter...
@nicorellius
Share on
Comments
Comments powered by Disqus