Django on Bluehost

This year I bought the domain juliobs.com and hosting on bluehost.com, so far it only has a copy of my old site, made from scratch in PHP and this blog.
But finally my vacation has arrived, and I will have some time to redo everything.

Now I plan to create a more professional and easy-to-maintain website, good reasons to use a CMS or a framework.
I have created sites with Joomla and even liked it, but I want something different, more pythonic…

Exactly, I will use Django!
I have wanted to work with this framework for some time, and since I am studying a lot of Python, I will combine the useful with the pleasant.

The only problem is that Bluehost does not provide official support for Django, it is not included in simplescripts and the Python version available on the server is 2.4, while the minimum recommended is 2.5.

In this post, I will show a step-by-step guide on how to work around this issue and install Django on Bluehost.

Installing Python 2.7

  1. Contact technical support and request SSH access. Their support is very good, and the login should be granted on the same day.

  2. Access your box via SSH and download the latest Python2:

    julio@julio-acer ~> ssh juliobs.com
    Enter passphrase for key '/home/julio/.ssh/juliobs':
    
    juliobor@box780 ~  $  wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tgz
    juliobor@box780 ~  $  tar xvfz Python-2.7.3.tgz
    
  3. Go to the extracted folder, configure and install Python with wide Unicode support:

    juliobor@box780 ~  $  cd Python-2.7.3
    juliobor@box780 ~/Python-2.7.3  $  ./configure --prefix="$HOME" --enable-unicode=ucs4
    juliobor@box780 ~/Python-2.7.3  $  make
    juliobor@box780 ~/Python-2.7.3  $  make install
    

    If everything went well, you can now run the new Python as follows:

    juliobor@box780 ~  $  ~/bin/python
    Python 2.7.3 (default, May 23 2012, 23:29:34)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    
  4. Edit your ~/.bashrc to export the PATH variable whenever Bash starts (order matters):

export PATH=$HOME/bin:$PATH
juliobor@box780 ~  $  echo $PATH
/home7/juliobor/bin:/usr/lib64/qt-3.3/bin:/home7/juliobor/perl5/bin:/usr/kerberos/bin:/ramdisk/bin:/usr/bin:/bin
  1. Run the .bashrc and test if the Python called with the python command is the version you just installed:

    juliobor@box780 ~  $  source .bashrc
    juliobor@box780 ~  $  python
    Python 2.7.3 (default, May 23 2012, 23:29:34)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    
  2. You can delete the files used in the installation.

juliobor@box780 ~  $  rm -r  Python-2.7.3.tgz Python-2.7.3/

There you go! Python is now updated, and we can start the Django installation.

Django Installation

  1. There are several ways to get Django. For me, the simplest method is through a version control system, as it facilitates future updates and allows development using the latest available version.

    But note that using the trunk/master will install the latest version still in testing and therefore not recommended for sites that require stability. It’s not my case.

    I recommend using git because Django development has moved to GitHub, but there are also mirrors on svn and mercurial (bluehost does not have mercurial installed).

    To update later, simply run git pull if you are using git or svn update if you are using SVN.

  2. Update setuptools and install pip:

juliobor@box780 ~  $  wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
juliobor@box780 ~  $  sh setuptools-0.6c11-py2.7.egg
juliobor@box780 ~  $  rm setuptools-0.6c11-py2.7.egg
juliobor@box780 ~  $  easy_install pip

Or run the script https://bootstrap.pypa.io/get-pip.py

  1. Install the Django module.

    The easiest way to install Django is through pip. The following command downloads and installs directly from GitHub. It also avoids having to mess around with the $PATH.

    juliobor@box780 ~  $  pip install git+https://github.com/django/django.git
    

    Alternatives:

    • Use pip, but keep the version control directory: sudo pip install -e ~/django/ (Easier to keep updated with git pull)
    • Create a .pth file in the site-packages folder pointing to the directory downloaded by git/svn
    • Install using setup.py install --user
  2. Edit the “~/.bashrc” file again to:

    export PATH=$HOME/bin:$HOME/.local/bin:$PATH
    
    juliobor@box780 ~  $  echo $PATH
    /home7/juliobor/bin:/home7/juliobor/.local/bin:/usr/lib64/qt-3.3/bin:/home7/juliobor/perl5/bin:/usr/kerberos/bin:/ramdisk/bin:/usr/bin:/bin
    
  3. Test if you can import Django:

    juliobor@box780 ~  $  python
    Python 2.7.3 (default, May 23 2012, 23:29:34)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import django
    >>> django.VERSION
    (1, 5, 0, 'alpha', 0)
    >>> print django.get_version()
    1.5
    
  4. To use the FastCGI protocol, we must install Flup:

    juliobor@box780 ~  $  pip install flup
    

    Alternative:

    juliobor@box780 ~  $  wget http://www.saddi.com/software/flup/dist/flup-1.0.2.tar.gz
    juliobor@box780 ~  $  tar xvfz flup-1.0.2.tar.gz
    juliobor@box780 ~  $  cd flup-1.0.2
    juliobor@box780 ~/flup-1.0.2  $  python setup.py build
    juliobor@box780 ~/flup-1.0.2  $  python setup.py install
    

Django is now installed. We can create a test project to learn the basic operations and see if everything is working correctly.

Creating a project

  • Create a projects directory somewhere not accessible from the Web (i.e., outside of ~/public_html). Eg.:

    juliobor@box780 ~  $  mkdir django_projects; cd django_projects
    
  • Create a project inside your projects folder

    juliobor@box780 ~/django_projects  $  django-admin.py startproject juliobs
    

    If you didn’t use pip, you probably need to edit the $PATH to use django-admin.py as in the command above:

    juliobor@box780 ~  $  export PATH=/home7/juliobor/django/django/bin:$PATH
    
  • Edit the settings.py file with your database settings.

'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/home7/juliobor/django_projects/mysite/testDB',

SQLite3 is good for testing purposes, but I recommend using PostgreSQL. You will need to install psycopg2:

juliobor@box780 ~  $  pip install psycopg2

Alternative:

juliobor@box780 ~  $  easy_install psycopg2
  • Run the following command to create the database tables. Answer no if asked to create a user: juliobor@box780 ~/django_projects/juliobs $ python manage.py syncdb

  • Create a .fcgi file in ~/public_html (or in a subdirectory if you prefer)

    Edit the django.fcgi file and make it executable:

    #!/home7/juliobor/bin/python
    import sys
    import os
    
    # Add a custom Python path.
    sys.path.insert(0,"/home7/juliobor/django_projects/juliobs")
    sys.path.insert(0,"/home7/juliobor/bin")
    
    os.chdir("/home7/juliobor/django_projects/juliobs")
    
    # Set the DJANGO_SETTINGS_MODULE environment variable.
    os.environ['DJANGO_SETTINGS_MODULE'] = "juliobs.settings"
    
    from django.core.servers.fastcgi import runfastcgi
    runfastcgi(method="threaded", daemonize="false")
    
    juliobor@box780 ~/public_html  $  chmod a+x django.fcgi
    
  • Add an .htaccess file

  • If Django is in the root of the site:

(AddHandler fcgid-script .fcgi
  Options +SymLinksIfOwnerMatch
  RewriteEngine On
  RewriteBase /
  RewriteRule ^(media/.*)$ - [L]
  RewriteCond %{REQUEST_URI} !(django.fcgi)
  RewriteRule ^(.*)$ django.fcgi/$1 [L]
  • If the site is in /django:

~/public_html/.htaccess

(AddHandler fcgid-script .fcgi
  Options +SymLinksIfOwnerMatch
  RewriteEngine On
  RewriteBase /
  RewriteRule ^(django\.fcgi/.*)$ - [L]
  RewriteRule ^(.*)$ /django/django.fcgi/$1 [L]

Now you can follow any Django tutorial. I am learning most things by reading The Django Book (The Definitive Guide to Django), which has this Web preview, is very up-to-date, and explains the concepts well.

Django + Apache + mod_wsgi

For obvious reasons, I will not develop directly on the server where my site is hosted, but rather on my own notebook. Django has a nice way to test the site without needing to install a server, which is by running the command python2 manage.py runserver

The site should be displayed at http://localhost:8000

However, some things become more complicated to test this way, and since I already have Apache installed here, I find it much more practical to develop and test on my Apache.

  1. Install Django from git via pip:
julio@julio-acer ~> sudo pip2 install git+https://github.com/django/django.git
  1. Install mod_wsgi:

    julio@julio-acer ~> sudo pacman -S mod_wsgi
    
  2. Edit wsgi.py:

    import os
    import sys
    
    # Adiciona caminho do projeto e seu diretório pai ao sys.path (precisa para
    # import juliobs.settings). Também pode ser feito pelo httpd.conf com PythonPath
    sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")))
    sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "juliobs.settings")
    
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    
  3. Edit http.conf

    LoadModule wsgi_module modules/mod_wsgi.so
    
    #WSGI - (para Django)
    WSGIScriptAlias /django /media/externo/Documentos/Programacao/Web/django_projects/juliobs/wsgi.py
    WSGIPythonPath /media/externo/Documentos/Programacao/Web/django_projects/juliobs/
    
    <Directory /media/externo/Documentos/Programacao/Web/django_projects/juliobs>
        <Files wsgi.py>
        Order deny,allow
        Allow from all
        </Files>
    </Directory>
    
    Alias /media/ /media/externo/Documentos/Programacao/Web/django_projects/juliobs/juliobs/media/
    <Directory /media/externo/Documentos/Programacao/Web/django_projects/juliobs/juliobs/media>
    SetHandler None
    Order allow,deny
    Allow from all
    </Directory>
    
  4. You should be able to access the site at http://localhost/django

Put your site under version control

Now that everything is working, we can start developing the site. Remember that

If you don’t want to store your site’s code in a repository like GitHub, a good alternative is rsync

julio@julio-acer Web/django/django_projects> rsync -avze --delete ssh juliobs juliobor@juliobs.com:~/django_projects

Notes:

  • Error when creating super user:

    python manage.py createsuperuser
        return getpass.getuser().decode(locale.getdefaultlocale()[1])
    TypeError: decode() argument 1 must be string, not None
    

    I solved it by defining the locale:

    juliobor@box780 ~  $  export LANG=en_US.UTF-8
    
  • In Arch Linux, mod_wsgi is for Python3, you need to install mod_wsgi2.


Julio Batista Silva
Julio Batista Silva
Data Engineer

I’m a computer engineer passionate about science, technology, photography, and languages. Currently working as a Data Engineer in Germany.

comments powered by Disqus