Loris setup guide for Ubuntu/Debian

Page mise à jour le 17.12.2013. Certaines informations sont désormais obsolètes et risquent de ne pas s'appliquer à la dernière version de Loris. Depuis cette date, les instructions d'installation et de configuration de Loris ont été largement améliorées. Se reporter au README pour une documentation actualisée : https://github.com/pulibrary/loris

Loris setup guide for Ubuntu/Debian

Loris is an image server developed by Jon Stroop at Princeton University. It is a Python-based implementation of the IIIF Image API 1.1 specification. It supports JPEG, JPEG2000 and TIFF source images. The software is released under GNU-GPL.

This tutorial is primarily intended for beginners or hurried web admins who want to set up a IIIF-compliant image server quickly.

Tested environments:

  • Debian 6.0.8 (Squeeze) / Apache 2.2.16 / Python 2.7.3
  • Debian 7.2 (Wheezy) / Apache 2.2.22 / Python 2.7.3
  • Ubuntu 12.04.3 (Precise) / Apache 2.2.22 / Python 2.7.3

Table of contents:

  1. Requirements
  2. Loris dependencies
  3. Loris setup
  4. Deploy with Apache
  5. Checking your installation

1. Requirements

1.1 Python

1.1.1 Check your Python version:

$ python --version 

The output should be:

  • 2.6.6 (Debian 6)
  • 2.7.3 (Debian 7 and Ubuntu 12.04)

If your version is 2.6.6 (which is the default one on Debian 6), it is recommended that you set up Python 2.7+ in a separate virtual environment.

Debian 7 and Ubuntu 12.04 users who already have Python 2.7+ can jump to SECTION 1.1.6.

1.1.2 Install the build-essential package:

$ sudo apt-get install build-essential

1.1.3 Install some additionnal packages

$ sudo apt-get install zlib1g-dev libssl-dev python-dev


  • zlib1g and libssl are required for Zlib and SSL support in Python
  • python-dev is required if you use Pillow as your Python imaging library (see below SECTION 2.3)

1.1.4 Install Python from source:

$ wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz
$ tar -xzvf Python-2.7.3.tgz
$ cd Python-2.7.3
$ ./configure --enable-shared --with-threads
$ make
$ sudo make altinstall

Python 2.7.3 should now be installed into the following directories:

  • /usr/local/lib/
  • /usr/local/bin/

1.1.5 Check if Python executable is finding libpython shared library:

$ ldd /usr/local/bin/python2.7

If you have this line "libpython2.7.so.1.0 => not found" in the output, then you need to add /usr/local/lib to your LD_LIBRARY_PATH:

Create a new file called libpython2.7.conf and paste your path in it (in our case it is "usr/local/lib") :

$ cd /etc/ld.so.conf.d/
$ sudo nano libpython2.7.conf

Paste your Python path in it, e.g.:


And run ldconfig:

$ sudo /sbin/ldconfig

Then check again the ldd command above. You should now see "libpython2.7.so.1.0 => /usr/local/lib/libpython2.7.so.1.0".

1.1.6 Set-up a Python virtual environment:

Install pip and virtualenv:

$ sudo apt-get install python-pip
$ sudo pip install --upgrade pip
$ sudo pip install virtualenv

Create a new folder for the loris project in /opt:

$ sudo mkdir /opt/loris
$ cd /opt/loris

(Debian 6 only) Create in the loris folder a virtualenv called "env" with the new version of Python, and then activate it:

// Debian 6
$ sudo virtualenv --python=/usr/local/bin/python2.7 env
$ . env/bin/activate

1.2 Apache Mod_wsgi

Critical info from mod_wsgi documentation: “Note that the version of Python from which this baseline environment is created must be the same version of Python that mod_wsgi was compiled for. It is not possible to mix environments based on different major/minor versions of Python.”

It means that you can't use the default "libapache2-mod-wsgi" from official Debian packages if you're running under a different version of Python (for instance in Debian 6 libapache2-mod-wsgi was compiled for Python 2.6.6, so you can't use it with a Loris instance running under Python 2.7.3). If you're in that case you need to compile and install mod_wsgi from the sources, as you did before for Python.

Debian 7 and Ubuntu 12.04 users can jump to SECTION 1.2.2.

1.2.1 Compile mod_wsgi from source (Debian 6)

Important: note that you need the apache development headers to configure mod_wsgi properly (you will find "apache2-prefork-dev" or "apache2-threaded-dev" in Debian repositories ; you can check which one to use by inspecting the output of "/usr/sbin/apachectl -V").

$ wget http://modwsgi.googlecode.com/files/mod_wsgi-3.4.tar.gz
$ tar -xvfz mod_wsgi-3.4.tar.gz
$ cd mod_wsgi-3.4/
$ ./configure --with-apxs=/usr/bin/apxs2 --with-python=/opt/loris/env/bin/python2.7
$ make 
$ sudo make install

Check if the module is ok:

$ ldd /usr/lib/apache2/modules/mod_wsgi.so

You should have the line "libpython2.7.so.1.0 => /usr/local/lib/libpython2.7.so.1.0".

Load the module into Apache:

$ cd /etc/apache2/mods-available
$ sudo nano wsgi.load

Add this line to the file wsgi.load:

LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

1.2.2 Activate the wsgi module:

// Only for Debian 7 / Ubuntu 12.04
$ sudo apt-get install libapache2-mod-wsgi

// for everyone
$ sudo a2enmod wsgi
$ sudo /etc/init.d/apache2 reload

2. Loris dependencies

2.1 Werkzeug

// Debian 6
$ cd /opt/loris/env
$ sudo bin/pip install Werkzeug

// Debian 7 / Ubuntu 12.04
$ sudo pip install Werkzeug

2.2 Kakadu

Download and install the Kakadu binaries:

$ cd /usr/local/lib/
$ sudo wget https://github.com/sul-dlss/Djatoka/raw/master/lib/Linux-x86-32/libkdu_v60R.so

$ cd /usr/local/bin
$ sudo wget https://github.com/sul-dlss/Djatoka/raw/master/bin/Linux-x86-32/kdu_expand

Note: if you're running a 64-bit OS, you can try an upper version of Kakadu (7.2) (works in Ubuntu 12.04 64-bit) : http://www.kakadusoftware.com/executables/

Run this command into the terminal:

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

Check if kdu_expand is executing:

$ /usr/local/bin/kdu_expand -v
This is Kakadu's "kdu_expand" application.
        Compiled against the Kakadu core system, version v6.0
        Current core system version is v6.0

2.3 Python Imaging Library (PIL or Pillow)

Pillow is recommended by the Loris documentation. According to the Pillow documentation, Pillow (instead of PIL) is already included in the Debian/Ubuntu distributions, but it seems to be true only since Ubuntu 13.04 (see python-imaging package) and only in Debian "sid" unstable version (see the new python-pil package).

PIL or Pillow have to be built/installed after Little CMS, so you need to remove them first if you already have them:

$ cd /opt/loris/env
$ sudo bin/pip uninstall PIL
$ sudo bin/pip uninstall Pillow
$ sudo apt-get purge python-imaging

Install all the dependencies:

// Debian 6
$ sudo apt-get install libjpeg62 libjpeg62-dev libjpeg8 libjpeg8-dev libfreetype6 libfreetype6-dev zlib1g zlib1g-dev liblcms-dev liblcms-utils libtiff4-dev

// Debian 7
$ sudo apt-get install libjpeg8 libjpeg8-dev libfreetype6 libfreetype6-dev zlib1g-dev liblcms liblcms-dev liblcms-utils libtiff4-dev

A. Install Pillow

$ sudo bin/pip install Pillow

Check if the dependencies are met:

--- ZLIB (PNG/ZIP) support available
--- TIFF G3/G4 (experimental) support available
--- FREETYPE2 support available
--- LITTLECMS support available

B. Install PIL

The problem with PIL is the same as mod_wsgi: you can't use the Debian 6 package and need to build it from source if you're using a different version of Python.

Check which Python version the Debian package was compiled for:

$ apt-cache show python-imaging

If the dependency is python2.6, let's compile our own for Python 2.7 (required for Debian 6):

$ wget http://effbot.org/media/downloads/Imaging-1.1.7.tar.gz
$ tar -xzvf Imaging-1.1.7.tar.gz
$ cd Imaging-1.1.7/
$ sudo /opt/loris/env/bin/python2.7 setup.py install

Check the dependencies:

--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
--- LITTLECMS support available

If you're on Debian 7 /  Ubuntu 12.04 only, just install the python-imaging package:

$ sudo apt-get install python-imaging

3. Loris setup

3.1 Download Loris

Clone Loris from Github repository (wherever you want, e.g. in your home directory):

$ git clone https://github.com/pulibrary/loris.git

3.2 Test, configure and install

Run the tests:

$ cd loris
// Debian 6
$ sudo /opt/loris/env/bin/python2.7 test.py
// Debian 7
$ sudo ./test.py

If the tests are passed, then you should configure Loris to meet your own needs (see the page Configuration and options for the details). Especially you should pay attention to the user and group under which Loris will be running and set various system paths (www and cache directories, root directory for images, path to kdu_expand binary...). You may also want to set your own CORS whitelist or set it to "*".

Edit loris.conf to reflect your needs :

$ nano etc/loris.conf

Add a new user/group for the Loris application:

$ sudo useradd -d /var/www/loris -s /sbin/false loris

Run the install script:

// Debian 6
$ sudo /opt/loris/env/bin/python2.7 setup.py install
// Debian 7 / Ubuntu 12.04
$ sudo ./setup.py install

You should see a success message and a summary of your configuration options.

If you just want to test Loris and don't have your own images, copy the contents of the "tests/img" folder into your "src_img_root" (by default it is set to "/usr/local/share/images", so you need to create it if you didn't set your own).

Go to the loris folder (depending on where you cloned it before, e.g. into your home):

$ cd /home/username/loris

Copy the sample images into your src_img_root:

$ sudo cp -R tests/img/* /usr/local/share/images/

For Debian 6 only: edit the WSGI file (e.g. /var/www/loris/loris.wsgi) in order to have the following content:

import site;

from loris.webapp import create_app
application = create_app()

4. Deploy with Apache

Important: note that you can't use mod_wsgi and mod_python at the same time (unless you recompile mod_python to use the same version of Python that mod_wsgi is using ; see this section of mod_wsgi documentation for more details).

So you may need to disable mod_python:

$ sudo a2dismod python

Then add the following directives to your virtualhost configuration file (adjust if needed):

ExpiresActive On
ExpiresDefault "access plus 5184000 seconds"
AllowEncodedSlashes On
WSGIDaemonProcess loris user=loris group=loris processes=10 threads=15 maximum-requests=10000
WSGIScriptAlias /loris /var/www/loris/loris.wsgi
WSGIProcessGroup loris

And enable the required modules:

$ sudo a2enmod headers expires
$ sudo /etc/init.d/apache2 reload

5. Check your installation

Have a look at http://{your_server}/loris/.
If the appropriate message is being displayed, you could check some of the sample IIIF URLs pointing to the images you previously put in your "src_img_root":

If you're facing some troubles with mod_wsgi, have a look at this page : http://code.google.com/p/modwsgi/wiki/CheckingYourInstallation

Important: if you're using slashes in the identifier slot (as in the above examples, e.g. "01/04/0001.tif" which is the identifier of the image as defined in IIIF Image API) and if you're running your web server behind a reverse proxy, you should make sure that the AllowEncodedSlashes Apache directive is allowed by the reverse proxy.

If your web server is accessible over the Internet, you can check the IIIF implementation provided by Loris with the IIIF validator: http://iiif-test.stanford.edu (the Image ID should be the filename of the test image in your "src_image_root", e.g. "67352ccc-d1b0-11e1-89ae-279075081939.jp2").