In a previous article about the Calibre e-book library management program, I wrote that I did away with USB cable connections to transfer e-books from my Calibre library to my E-reader. Instead, I made my e-book library accessible on-line and now I am able to download my books securely over the Internet – no matter where I am, as long as I have a network connection.
In this article today, I am going to explain how I make my Calibre library accessible on-line.
Understandably, the article will be Slackware-centric, because that is where I have my Calibre library and where I run all the programs that I need. But, the technology and the configuration is generic enough that readers of this article running another distro or even employing an embedded (ARM) device will be able to make it work.
Which software is used?
- Slackware Linux – http://www.slackware.com/
- Calibre – https://calibre-ebook.com/
- Apache httpd – https://httpd.apache.org/docs/2.4/
- PHP – https://www.php.net/
- COPS (Calibre OPDS PHP Server) – https://blog.slucas.fr/projects/calibre-opds-php-server/
Apache and PHP are standard part of Slackware Linux. I assume that you know how to setup an Apache web server. The good news is that Slackware’s default httpd configuration works out of the box. However, it does not enable a secure (https) web site. That part is on you.
If your content server is going to be used in your home network only, then HTTPS is not even needed.
I have a package for Calibre in my repository which of course you will definitely need if you want to build an e-book library.
You’ll have to download the ZIP file of the latest COPS release from https://github.com/seblucas/cops/releases – the ZIP contains the extra stuff that is not contained in the source .tar.gz file.
The remainder is just configuration.
Now let me explain my setup.
The Calibre library
It all starts with Calibre of course. It is a desktop program, available for Linux, Windows and MacOS. It stores your e-book library as a directory tree. The directories immediately below the root of the tree are the book authors. In the root of the directory tree, Calibre creates a SQLite database file containing all the library metadata. The simple directory structure and the SQLite database file make that a Calibre library is independent of the Operating System that Calibre runs on. Its database scheme can be updated between major releases though. From within the Calibre GUI, it is however trivial to re-create this database file from scratch if it becomes corrupted.
This simple library setup has the advantage that if you store the library on a Cloud service like Dropbox, you can have access to your library from multiple computers running different Operating Systems (but preferably all the same version of Calibre). As long as one person accesses the library at any time, the Calibre database file will not get corrupted. This is how I have setup Calibre for my wife so that she can manage her e-books from every computer in the house.
Where to create the library
Myself, I use Calibre on a Linux machine which runs 24/7 (my package-build server in fact). I run a XFCE graphical desktop session inside a VNC server and that allows me to work in a desktop environment that’s always there for me. I use NoVNC to access this desktop using a web browser and that is perfect for corporate envronments which put a firewall up for everything except HTTPS traffic. Perhaps I’ll write another article sometime, explaining how to set that up.
What matters is that the Calibre library is stored on a machine with Internet access, and that this computer is running a web server like Apache. In Slackware, Apache httpd is the default webserver program.
I made this web server accessible from the Internet by configuring my ISP’s Internet router to forward ports 80 (http) and 443 (https) to the internal IP address of my Slackware machine.
For the sake of this article, let’s assume that two separate Calibre libraries exist on this computer, mine is located in /data/Calibre/EricLibrary and my wife’s books are stored in /data/Calibre/WifeLibrary . In Calibre itself, you can easily switch between libraries so that me and my wife are both able to maintain a separate collection of books. Our book tastes have no overlap…
How to configure the web server
I want both libraries to be accessible online.
I do not want to use Calibre’s own content server but instead use COPS. COPS is a collection of PHP scripts, and it does not require the Calibre program to function. It just needs access to the physical directory containing your Calibre library and it understands the Calibre SQLite database format.
If you want to get creative, you can install COPS on an Internet server – e.g. if you do not have a webserver at home. In that case, use a cloud storage service like Dropbox to keep your library in sync between your computer at home and that remote server running Apache.
My example setup is a Slackware computer at home with Apache enabled:
# chmod +x /etc/rc.d/rc.httpd # /etc/rc.d/rc.httpd start
Apache uses the concept of a DocumentRoot, which is a directory accessible by the httpd server. Everything stored below that DirectoryRoot will be accessible via the URL of the webserver. Never store files below the DocumentRoot that you do not want to share!
I downloaded and extracted the COPS zip file directly into the Apache DocumentRoot directory (the default in Slackware is configured in the file ‘/etc/httpd/httpd.conf’ to be “/srv/httpd/htdocs/” but you can change that default location of course):
# cd /tmp # links https://github.com/seblucas/cops/releases/download/1.1.3/cops-1.1.3.zip # cd /srv/httpd/htdocs/ # unzip /tmp/cops-1.1.3.zip # ln -s cops-1.1.3 mybooks # cd mybooks # cat <<EOT > config_local.php $config = array(); $config['calibre_directory'] = array ("Eric" => "/data/Calibre/EricLibrary/", "Wife => "/data/Calibre/WifeLibrary/"); $config['cops_title_default'] = "Aliens Library"; $config['cops_use_url_rewriting'] = "1"; $config['cops_recentbooks_limit'] = '100'; $config['cops_update_epub-metadata'] = "1"; $config['cops_books_filter'] = array ("Books" => "!News"); EOT
The lines from the “cat << EOT” until the “EOT” on its own line is called a “here document“. You can copy/paste these lines into a terminal and it will create the file “config_local.php” with the content as shown between the “EOT” lines.
This is a configuration which allows access to two separate libraries. If you access the “recently added” section of a library it will show the latest 100 books instead of the default 20 books. It does some URL re-writing to generate cleaner URLs and it will not show any News sources (in Calibre, you can add various paid-for and free newspaper subscriptions and those will then be dpwnloaded daily, but I do not want to see those online).
Compare this configuration of mine to the ‘config_local.php.example’ file in the COPS directory. The above is not all you can configure, although it is sufficient. All configurable parameters are documented in ‘config_default.php’ which also defines their default values.
You’ll have noticed that I created a symlink to the extracted cops files, which allows me to use an easy to remember URL to access my books. Suppose my apache server is accessible as http://foo.net/ – then my COPS installation will be accessible at http://foo.net/mybooks/ .
Under the above ‘mybooks’ URL you will now find a COPS installation with two Calibre libraries with separate names “Eric” and “Wife”. Pick a nice template and theme, and try out the ebook-reader which is part of COPS (you can read EPUBs in a web browser, no E-reader required).
Accessing COPS through the OPDS protocol
You want to configure your E-reader to access the library. An E-reader which contains a webbrowser is easy, just open http://foo.net/mybooks/ and click a book to download it.
Other E-readers, like FBReader for Android, are able to connect to an OPDS (Open Publication Distribution System) catalog. The COPS program exposes your library as a OPDS catalog if you just add ‘feed.php’ to the URL.
I.e. enter http://foo.net/mybooks/feed.php into the Network Library menu of FBReader and you’ll get instant access to “Alien’s Library” where you can browse Authors, Series, Categories, Recent Additions and read book descriptions, and then download the books you want to read.
If you want to always start with a list of recent library additions, you can add ‘?page=10’ at the end of the URL so that it becomes http://foo.net/mybooks/feed.php?page=10
Hiding the cops files from the Apache DocumentRoot
Some people feel a bit anxious having these cops files accessible in their DocumentRoot – suppose someone gains access to them trough other means. You can use Apache’s “Alias” directive to install COPS in e.g. /usr/local instead. In that case, add the following lines to your /etc/httpd/httpd.conf or whatever file holds your website definition:
<Directory "/usr/local/cops-1.1.3/"> AllowOverride All Options +ExecCGI +FollowSymLinks Require all granted </Directory> Alias /mybooks/ /usr/local/cops-1.1.3/
You should check the validity of your httpd configuration before restarting the webserver:
# apachectl configtest # /etc/rc.d/rc.httpd restart
And the URL to access your library will remain the same, i.e. http://foo.net/mybooks/feed.php?page=10 , only in this case your actual DocumentRoot directory will be empty.
Adding some sense of security
After following the above instructions, you now have an e-book library online whose access is not restricted in any way. If some search engine passes by it will neatly catalog all your books for other people to find. Oops!
You’ll need a basic access restriction at least. Apache offers a ‘Basic Authentication’ setup which will prompt anyone who tries to access your library for a valid account and password.
To achieve this, let’s first create a password file containing the account/password combinations for the people you want to grant access. For the sake of this example, I will grant myself and my wife access by creating account/password combinations for us in a file which we will then use in our Apache configuration.
The first ‘htpasswd’ command below has an additional ‘-c’ parameter to create the file “/etc/httpd/passwords/htaccess.opds”:
# mkdir -p /etc/httpd/passwords/ # htpasswd -b -c /etc/httpd/passwords/htaccess.opds eric ericspassword # htpasswd -b /etc/httpd/passwords/htaccess.opds wife wifespassword
The file will then have these contents, you see that the passwords are now MD5 encrypted:
Read “man htpasswd” to find out more about this command and its parameters.
Next you need to change the Apache <Directory></Directory> block which I provided above. It will become like this:
<Directory "/usr/local/cops-1.1.3/"> AllowOverride All Options +ExecCGI +FollowSymLinks AuthBasicAuthoritative off AuthUserFile /etc/httpd/passwords/htaccess.opds AuthType Basic AuthName "OPDS Server" Require valid-user # Require all granted </Directory> Alias /mybooks/ /usr/local/cops-1.1.3/
Once you made these changes, validate the configuration and restart the webserver:
# apachectl configtest # /etc/rc.d/rc.httpd restart
Now you will be greeted by an authentication request, next time you access your library. Only those users whose username/password combinations are stored in “/etc/httpd/passwords/htaccess.opds” will be able to get access.
Using encrypted HTTP
You should realize that these passwords will still be transmitted in cleartext if your webserver is not using HTTPS. It is possible for people to sniff the network connection and find your credentials.
I think however that instructions about enabling HTTPS for your Apache belongs in another blog post. Let me know in the comments section below if you have a need for such an article.
Also, let me know if parts of the above instructions are too cryptic and I will update the text where needed.
Good luck! Eric