Running calibre server on Debian squeeze

This document intends to record the steps necessary to run calibre content server for easy sharing of books among small group of people. The matter is somewhat complicated by the fact that I would like to run it on Debian Stable.

From Calibre FAQ:

If you bought into the notion that a real server must run a decade old version of Debian, then you will have to jump through a few hoops.

... well, fuck that.

The first section describes jumping through (different) hoops and is specific to Debian. The rest of the guide should be independent of the way you managed to run calibre server.

Note

You may want to check out calibre2opds which allows you to share your books but does not require special server to be running.

Installing calibre in chrooted distro

One possibility of running newer version of calibre in stable is to use the packaged version from testing. Unfortunately, recent calibre depends on recent versions of some libraries such as libc. We'll try to overcome the dependency hell by installing a Debian testing distribution in a chroot of our server and run calibre in it. Using chroot should also somewhat isolate calibre from the rest of the system and thus reduce the impact should the calibre server become compromised (it would be even better to run it in dedicated virtual machine, but this is currently not an option for me as the host system is virtual itself).

Create the user calibre-server will run under:

root@host# useradd -r -m -U -r -d /home/calibre calibre
root@host# CHROOT=/home/calibre/chroot
root@host# mkdir $CHROOT

Note: we store everything under /home/calibre, you may want to use different directory -- YMMV.

Install the chrooted testing:

root@host# debootstrap testing $CHROOT http://ftp.cz.debian.org/debian/
root@host# cp /etc/{passwd,group} $CHROOT/etc/

Note: choose a good mirror, the default one may be slow.

(optional) Change prompt of the chroot to help avoiding disasters:

root@host# echo 'PS1="CHROOT:\w# "' >> $CHROOT/root/.bashrc

Install calibre (and socat which will be needed for adding books via email):

root@host# chroot $CHROOT
CHROOT:/# aptitude install calibre rsync

Note: calibre and its dependencies take about 500M of disk space.

Create calibre library:

root@host# LIBDIR=$CHROOT/home/calibre/library
root@host# mkdir $LIBDIR
root@host# chown -R calibre:calibre $LIBDIR

Note: library should probably be created using calibredb command, but I don't know how. Fortunately calibre seems to be able to initialize the library first time it is used. You may also import existing library instead of creating empty one.

We need a way to start the server, preferably at boot time. I used the following as an init script.

#! /bin/sh
# Calibre server init script

# settings
CHROOT=/home/calibre/chroot
LIBDIR=/home/calibre/library
PIDFILE=/home/calibre/calibre-server.pid
EXEC="/usr/bin/calibre-server"

# user and group the server will run under
USER=calibre
GROUP=calibre

# username and password to access the server
# note: password WILL be visible in the list of processes
USERNAME="test"
PASSWORD="test"

# port the server will listen on
PORT=8004

# end of settings

PIDFILE=$LIBDIR/calibre-server.pid
OPTIONS="--port $PORT --username $USERNAME --password $PASSWORD --with-library $LIBDIR --pidfile $PIDFILE --daemonize"
N="calibre-server"

do_start ()
{
    # start it through shell and pass it some reasonable $HOME
    # or edit $CHROOT/etc/passwd
    start-stop-daemon --start --chroot $CHROOT --chuid $USER:$GROUP --pidfile $CHROOT$PIDFILE --startas "/bin/bash" -- -c "HOME=$LIBDIR $EXEC $OPTIONS"
}

do_stop ()
{
    start-stop-daemon --stop --pidfile $CHROOT$PIDFILE
}

set -e

case "$1" in
  start)
    echo -n "Starting $N: "
    do_start
    echo "done."
    ;;

  stop)
    echo -n "Stopping $N: "
    do_stop
    echo "done."
    ;;

  reload|force-reload|restart)
    echo -n "Restarting $N: "
    do_stop
    sleep 1 # what the fuck
    do_start
    echo "done."
    ;;
  *)
    echo "Usage: calibre-server {start|stop|restart|reload|force-reload}" >&2
    exit 1
    ;;
esac

exit 0

Put the script into /etc/init.d and create symlinks to it from /etc/rcN.d/ directories (ncurses tool: sysv-rc-config).

The server should now start at boot and will be running on port 8004 accessible using username calibre and password calibre. If you won't be using it through this port directly, consider firewalling it for outside access.

Integrating calibre-server into lighttpd

If you want to access the server through web server which is running on the machine, you can use reverse proxy. This has the advantage that you don't have to remember the port number and you can also use SSL or you webserver's authentication mechanism.

Following excerpt from lighttpd config allows you to access the server via http://books.example.com:

server.modules += ( "mod_proxy" )

$HTTP["host"] == "books.example.com" {
    proxy.server = ( "" => (( "host" => "127.0.0.1", "port" => 8004 )) )
}

See mod_proxy's documentation for details. Or your favorite webserver's -- the configuration will probably be similar.

You may need to use calibre-server's --url-prefix parameter if you want it to live outside the HTTP root (i.e. at http://example.com/books/).

Once this works, you can set your firewall so that it filters the port 8004 for requests from the outside.

See relevant calibre documentation section.

Using email to add books

Calibre can be configured to send a book to an email address with just a few clicks. This feature can be used to add books to the server. Users are not interested in this feature though. Undocumented, half-working sources can be found on github.

Remote library management

Another way of maintaining the online library is to sync it with your local library. You can use rsync over ssh for that.

rsync -rvz -e ssh --delete --exclude ".*" --exclude calibre-server.pid $LOCAL_LIB/ calibre@host:chroot/home/calibre/library

You need to restart the server now though, as it doesn't notice that the library changed. Which is difficult to do as non-root user due to the chroot hack described above:(

TODO

  • the initscript is horrible mess
  • why are we still using HOME=$LIBDIR?
  • figure out how to restart the server without the need to be root