% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode}{hyperref}
\PassOptionsToPackage{hyphens}{url}
%
\documentclass[
]{article}
\usepackage{amsmath,amssymb}
\usepackage{iftex}
\ifPDFTeX
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc}
  \usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
  \usepackage{unicode-math} % this also loads fontspec
  \defaultfontfeatures{Scale=MatchLowercase}
  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\fi
\usepackage{lmodern}
\ifPDFTeX\else
  % xetex/luatex font selection
\fi
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
  \usepackage[]{microtype}
  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
  \IfFileExists{parskip.sty}{%
    \usepackage{parskip}
  }{% else
    \setlength{\parindent}{0pt}
    \setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
  \KOMAoptions{parskip=half}}
\makeatother
\usepackage{xcolor}
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
\ifLuaTeX
  \usepackage{selnolig}  % disable illegal ligatures
\fi
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\urlstyle{same}
\hypersetup{
  pdftitle={django-virtualenv-apache-mod\_wsgi},
  hidelinks,
  pdfcreator={LaTeX via pandoc}}

\title{django-virtualenv-apache-mod\_wsgi}
\author{}
\date{}

\begin{document}
\maketitle

\hypertarget{django-virtualenv-apache-mod_wsgi}{%
\section{django-virtualenv-apache-mod\_wsgi}\label{django-virtualenv-apache-mod_wsgi}}

\hypertarget{django-virtualenv-apache2-mod_wsgi}{%
\section{Django virtualenv Apache2
mod\_wsgi}\label{django-virtualenv-apache2-mod_wsgi}}

By the end of this article you will know how to deploy a Django web
application using a python virtualenv, using an Apache2 webserver with
mod\_wsgi.

You should bookmark this page.

\textbf{Why use wsgi and virtualenv?}

\begin{itemize}
\tightlist
\item
  I also host pylons applications using mod\_wsgi and apache2 and
  mod\_python is incompatible.
\item
  mod\_wsgi is fast.
\item
  I don't want my public site-packages library conflicting with other
  applications.
\end{itemize}

.. contents::

\hypertarget{install-virtualenv}{%
\subsection{Install virtualenv}\label{install-virtualenv}}

\begin{enumerate}
\item
  Install Setup tools:

  .. code-block :: bash

  \$ sudo apt-get install python-setuptools memcached
\item
  Install virtualenv:

  .. code-block :: bash

  \$ sudo easy\_install virtualenv
\end{enumerate}

\hypertarget{create-a-virtualenv}{%
\subsection{Create a virtualenv}\label{create-a-virtualenv}}

\begin{enumerate}
\item
  Move to the directory where you want to create the virtualenv:

  .. code-block :: bash

  \$ cd /www/lostquery.com
\item
  Create python environment:

  .. code-block :: bash

  \$ virtualenv --no-site-packages virtpy
\end{enumerate}

\hypertarget{install-django}{%
\subsection{Install Django}\label{install-django}}

\begin{enumerate}
\item
  Activate the virtualenv:

  .. code-block :: bash

  \$ source virtpy/bin/activate
\item
  The shell should have changed to \emph{(virtpy) \$} . Run this command
  to install django to the virtualenv:

  .. code-block :: bash

  \# I know this version works\ldots{} \$ easy\_install django==1.3.1
\item
  Install any dependencies you will need to the virtualenv:

  .. code-block :: bash

  \$ easy\_install MySQL-python markdown html5lib modwsgideploy
  python-openid South python-memcached
\end{enumerate}

\hypertarget{install-and-configure-the-django-web-application}{%
\subsection{Install and configure the Django web
application}\label{install-and-configure-the-django-web-application}}

\begin{enumerate}
\item
  Get the sourcecode:

  .. code-block :: bash

  \$ svn co http://svn.osqa.net/svnroot/osqa/trunk
\item
  Configure the application:

  .. code-block :: bash

  \$ cd trunk

  \$ cp settings\_local.py.dist settings\_local.py

  \$ vi settings\_local.py
\item
  You must tell the Django's application what database to use. Also
  configure memcached:

  .. code-block :: python

  \# database settings DATABASE\_NAME = `databasename' \# Or path to
  database file if using sqlite3. DATABASE\_USER = `username' \# Not
  used with sqlite3. DATABASE\_PASSWORD = `p@ssw0rd' \# Not used with
  sqlite3. DATABASE\_ENGINE = `mysql' \#mysql, etc DATABASE\_HOST =
  `localhost' DATABASE\_PORT = '\,'

  \# memcached settings (osqa is slow as dirt without this)
  CACHE\_BACKEND = `memcached://127.0.0.1:11211/'
\item
  Give apache access to a few directories, /trunk/log and
  /trunk/forum/upfiles:

  .. code-block :: bash

  \$ chmod 777 log \$ chmod 777 forum/upfiles
\item
  Create the database
  \texttt{(example\ syntax\ to\ create\ a\ mySQL\ database)\ \textless{}http://www.foxhop.net/mySQL\#create-database\textgreater{}}\_.

  Let the django application build the tables in the new database:

  .. code-block :: bash

  \$ python manage.py syncdb --all \$ python manage.py migrate forum
  --fake
\end{enumerate}

\hypertarget{configure-apache2-virtualhost}{%
\subsection{Configure Apache2
VirtualHost}\label{configure-apache2-virtualhost}}

\begin{enumerate}
\item
  Turn on mod\_rewrite:

  .. code-block :: bash

  \$ a2enmod rewrite
\item
  Create a sites-available vhost apache2 file:

  .. code-block :: bash

  \$ sudo vi /etc/apache2/sites-available/007-lostquery
\item
  Setup the host file:

  .. code-block :: apache :linenos:

  \#lostquery.com

  \#Djangos embeded mod\_wsgi \textless VirtualHost *:80\textgreater{}
  ServerName lostquery.com ServerAlias www.lostquery.com ServerAdmin
  admin@admin.com

\begin{verbatim}
   # ReWrite URL to WWW
   RewriteEngine On
   RewriteCond %{HTTP_HOST} ^www.lostquery.com
   RewriteRule (.*) http://lostquery.com$1 [R=301,L]

   # Log Files
   ErrorLog /var/log/apache2/error-lostquery.log
   CustomLog /var/log/apache2/access-lostquery.log combined

   # Prevent django from serving static files
   DocumentRoot /www/lostquery.com/trunk/forum
   Alias /m/ /www/lostquery.com/trunk/forum/skins/
   Alias /upfiles/ /www/lostquery.com/trunk/forum/upfiles/
   <Directory /www/lostquery.com/trunk/forum/skins>
       Order allow,deny
       Allow from all
   </Directory>

   # Setup mod_wsgi
   WSGIDaemonProcess lostquery display-name=lostquery user=www-data processes=2 threads=15
   WSGIScriptAlias / /www/lostquery.com/mod_wsgi/dispatch.wsgi
\end{verbatim}
\end{enumerate}

\hypertarget{configure-mod_wsgi}{%
\subsection{Configure mod\_wsgi}\label{configure-mod_wsgi}}

\begin{enumerate}
\item
  Create the egg-cache directory:

  .. code-block :: bash

  \$ mkdir /www/lostquery.com/mod\_wsgi

  \$ mkdir /www/lostquery.com/mod\_wsgi/egg-cache
\item
  Create the wsgi dispatch file:

  .. code-block :: bash

  \$ vi /www/lostquery.com/mod\_wsgi/dispatch.wsgi
\item
  Setup the wsgi dispatch file:

  .. code-block :: python :linenos:

  import os import sys sys.stdout = sys.stderr \# Add the virtual Python
  environment site-packages directory to the path import site
  site.addsitedir(`/www/lostquery.com/virtpy/lib/python2.6/site-packages')

  \# Avoid
  \texttt{{[}Errno\ 13{]}\ Permission\ denied:\ \textquotesingle{}/var/www/.python-eggs\textquotesingle{}}
  messages\\
  import os os.environ{[}`PYTHON\_EGG\_CACHE'{]} =
  `/www/lostquery.com/mod\_wsgi/egg-cache'

  \#If your project is not on your PYTHONPATH by default you can add the
  following sys.path.append(`/www/lostquery.com/trunk')
  os.environ{[}`DJANGO\_SETTINGS\_MODULE'{]} = `settings'

  import django.core.handlers.wsgi application =
  django.core.handlers.wsgi.WSGIHandler()
\end{enumerate}

\hypertarget{enable-the-virtual-host-and-reload-apache2}{%
\subsection{Enable the Virtual Host and reload
Apache2}\label{enable-the-virtual-host-and-reload-apache2}}

\begin{enumerate}
\item
  Reset apache2 so that it reads in the new config files:

  .. code-block :: bash

  \$ a2ensite lostquery

  \$ sudo service apache2 reload
\end{enumerate}

\hypertarget{fritzvd-sep-28-2011-1131-pm}{%
\subsection{fritzvd --- Sep 28, 2011 11:31
pm}\label{fritzvd-sep-28-2011-1131-pm}}

Hi,

Thanks this is great and exhaustive. Helped me host my django. One
question though, I usually do this: Create sites and put them in:
sites-available. Reload apache2 for a graceful restart. Call them/switch
on:

\begin{verbatim}
a2ensite lostquery

/etc/init.d/apache2 reload
\end{verbatim}

Is there any special reason why you don't do this?

Fritz

\hypertarget{foxhop-sep-29-2011-0500-pm}{%
\subsection{foxhop --- Sep 29, 2011 05:00
pm}\label{foxhop-sep-29-2011-0500-pm}}

@fritzvd

I have recently started using the \emph{a2ensite} method that you
described.

Thanks for your input. I have adjusted the tutorial. Feel free to adjust
anything you feel need work!

Foxhop

\end{document}
