Applications Azure

I, Librarian Reference Manager on Ubuntu 24.04 on Azure User Guide

| Product: I, Librarian 5.11.3 Reference Manager on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of I, Librarian on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. I, Librarian is a self-hosted reference and PDF management system for research groups, laboratories and libraries, developed by Martin Kucej and published at github.com/mkucej/i-librarian-free. You upload PDFs and it extracts and indexes their full text, fetches bibliographic metadata, lets you read and annotate papers in the browser, and organises everything with tags, categories and shared projects.

The image installs I, Librarian 5.11.3 served by nginx and PHP 8.3 FPM, backed by an on-box SQLite database — there is no external database server to run or secure. poppler provides full-text PDF indexing and the built-in PDF viewer, ghostscript backs the viewer, and Tesseract provides optional OCR of scanned documents. Unattended security upgrades are configured to keep the server patched on your running VM.

One appliance, one web application. I, Librarian is a front-controller application: nginx and php8.3-fpm serve the whole site on port 80 and route every request through the application's public/index.php. The SQLite database, your uploaded PDFs, the configuration and the application source all live outside the web root, so only the web interface is reachable and your library data is never served as source.

Security by design — there is no administrator account in the image. I, Librarian grants administrator rights to the first account created on a fresh library, and it auto-creates its database on the first web request — which would let an unauthenticated visitor register themselves as the first administrator. This image closes that hole completely. It ships no account and no database at all. On the very first boot of every VM a one-shot service generates a unique administrator password, creates the SQLite database and the single administrator account, disables public self-registration and sets new-account permissions to regular user, and then proves the new password signs in through the real sign-in form and that admin, a blank password and other common guesses do not, before writing /root/i-librarian-credentials.txt (mode 0600, root only).

The site cannot serve an unprovisioned instance. nginx and php8.3-fpm are each gated on a bootstrap marker that first boot writes only after the database and administrator account are in place. Until that marker exists systemd skips those units entirely, so there is no window in which a half-provisioned site — or an empty library where the first visitor becomes administrator — is reachable. The units are still enabled, so the appliance comes straight back after a reboot.

What is included:

  • I, Librarian 5.11.3 served by nginx and PHP 8.3 FPM, routing every request through the application front controller

  • An on-box SQLite database holding your library, with no external database server to manage

  • The poppler, ghostscript and tesseract-ocr toolchain for full-text PDF indexing, the built-in PDF viewer and optional OCR of scanned documents

  • A first-boot service that mints a per-instance administrator password, seeds the administrator, disables self-signup, and proves the credentials before the site is reachable

  • The bootstrap gate that stops nginx and php-fpm serving until provisioning is complete

Prerequisites

  • An Azure subscription and either the Azure Portal or the Azure CLI (az) signed in
  • An SSH key pair so you can read the generated credentials file
  • Inbound TCP port 80 open to the browsers that will reach the library (and port 22 for administration)

Step 1: Deploy from the Azure Portal

  1. Open the cloudimg I, Librarian Reference Manager on Ubuntu 24.04 LTS offer in the Azure Marketplace and choose Create.
  2. Pick a resource group and region, keep the recommended Standard_B2s size (2 vCPU / 4 GB is comfortable for a lab library), and provide your SSH public key for the azureuser account.
  3. On the Networking step allow inbound 80 (the web application) and 22 (SSH). I, Librarian serves everything over port 80; put it behind an Azure Application Gateway or a reverse proxy if you want TLS.
  4. Create the VM and note its public IP address.

Step 2: Deploy from the Azure CLI

RG="i-librarian-prod"; LOCATION="eastus"; VM_NAME="i-librarian"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/i-librarian-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values "$SSH_KEY" \
  --public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002

Step 3: First boot and your credentials

On first boot the image mints the per-instance administrator password, creates the SQLite database, seeds the single administrator account, disables self-registration, opens the bootstrap gate, starts nginx and php-fpm, verifies the new credentials work and the common defaults are rejected, and writes /root/i-librarian-credentials.txt. This completes within a minute or two. SSH in as azureuser and read the details:

sudo cat /root/i-librarian-credentials.txt

The file gives you the library URL, the administrator username (admin) and the per-instance administrator password. Keep it safe — it is readable only by root.

Step 4: Confirm the appliance is running

Both services should report active. ss confirms the web application is on port 80, and the SQLite databases sit on the local disk (there is no network database to expose).

systemctl is-active php8.3-fpm.service nginx.service
sed -n "s/.*IL_VERSION = '\([^']*\)'.*/I, Librarian \1/p" /var/www/i-librarian/public/index.php | head -1
php -r 'echo "PHP ".PHP_VERSION."\n";'
ss -tulnp | grep ':80 ' | sed 's/users:.*//'
ls -la /var/www/i-librarian/data/database/ | grep '\.db$'

Both services report active, I, Librarian 5.11.3 and PHP 8.3 report their versions, ss shows the web application on port 80, and the on-box SQLite databases are listed

Step 5: Sign in to I, Librarian

Browse to http://<your-vm-ip>/. You will see the I, Librarian sign-in page. Sign in with the administrator username admin and the password from the credentials file.

The I, Librarian sign-in page with the username and password fields

Once signed in you land on the dashboard, with the library, import tools, projects, catalog and the administrator panel all one click away.

The signed-in I, Librarian dashboard

Step 6: Change the administrator password

Open the account menu (top right), choose your profile, and set a new password. From then on use your own password; the generated one in the credentials file was only to get you in.

Step 7: Add your first reference

This is what I, Librarian exists to do. From Import you can add references by identifier (DOI, PubMed ID, arXiv, Crossref and more), upload published PDFs, or enter one by hand with Manual import — attaching the PDF as you go. I, Librarian extracts the full text of every PDF with pdftotext, so the paper becomes searchable the moment it is imported. Imported references appear in your Library.

The I, Librarian library listing an imported reference with its attached PDF

Step 8: Read, search and organise

Opening a reference shows its summary page: the metadata, the abstract, the notes and discussion, the tags, and the attached PDF — which you read in the built-in viewer, download, or manage. Use Search and Filter for full-text and fielded search across the whole library, group papers into shared Projects, and label them with Tags and Categories.

A stored reference on its I, Librarian summary page with its metadata panels and the attached PDF

The whole library — references, uploaded PDFs, tags, projects and settings — lives in the on-box SQLite database and the PDF store, served on port 80:

A reference stored in the on-box SQLite library, the single administrator account with self-signup disabled, and curl confirming the library serves on port 80

Step 9: Prove the per-VM administrator works and defaults are rejected

The image ships no shared credential. The credentials file is root-only, and the real sign-in form accepts only the per-VM administrator password, while the configuration and the database are never web-served:

ls -l /root/i-librarian-credentials.txt
stat -c 'credentials mode %a owner %U:%G' /root/i-librarian-credentials.txt
# the per-VM administrator password signs in through the real form:
sudo /usr/local/sbin/i-librarian-login-check.sh admin '<ILIBRARIAN_ADMIN_PASSWORD>' \
  && echo "per-VM administrator: SIGNED IN" \
  || echo "per-VM administrator: run this on your VM (the password is substituted from the credentials file)"
# every guessable default is rejected:
for p in admin password librarian ilibrarian 123456 ""; do
  if sudo /usr/local/sbin/i-librarian-login-check.sh admin "$p"; then
    echo "  '$p' ACCEPTED (unexpected)"
  else
    echo "  '$p' rejected (correct)"
  fi
done
# the config and the database are never web-served:
curl -s -o /dev/null -w '  GET /config/ilibrarian.ini -> HTTP %{http_code} (404 = not served)\n' http://127.0.0.1/config/ilibrarian.ini
curl -s -o /dev/null -w '  GET /data/database/main.db -> HTTP %{http_code} (404 = not served)\n' http://127.0.0.1/data/database/main.db

The credentials file at mode 600 owned by root, the real sign-in form rejecting admin, password, librarian, ilibrarian, 123456 and a blank password, and the config and database returning HTTP 404 over the web

Step 10: OCR and metadata lookup

I, Librarian ships with Tesseract for OCR of scanned PDFs (the OCR path is pre-configured to /usr/bin/tesseract) and can fetch bibliographic metadata for a reference from Crossref, PubMed, arXiv, NASA ADS and other sources. Both are available from the Administrator → Global settings page and from a reference's own tools; no extra configuration is required to get started.

Step 11: How the first-boot gate protects an unprovisioned instance

The distinguishing security property of this image is that the web tier cannot serve until provisioning is complete. Each web unit carries a ConditionPathExists drop-in on the bootstrap-ready marker, which first boot writes only after the administrator has been seeded — so there is never a moment when an empty library is reachable and the first visitor could become administrator.

grep -H ConditionPathExists /etc/systemd/system/nginx.service.d/cloudimg-bootstrap-gate.conf
for u in php8.3-fpm nginx; do
  printf '%-12s %s\n' "$u" "$(grep -h ConditionPathExists /etc/systemd/system/$u.service.d/cloudimg-bootstrap-gate.conf)"
done
ls -l /var/lib/cloudimg/
systemctl is-enabled php8.3-fpm.service nginx.service

The systemd drop-in for nginx showing ConditionPathExists on the cloudimg i-librarian bootstrap-ready marker, the same condition on php8.3-fpm, the marker and first-boot sentinel present in /var/lib/cloudimg, and both units reported as enabled so they survive a reboot

Step 12: Add more users

Self-registration is disabled by default, so new accounts can only be created by an administrator. From Administrator → Users you can add colleagues, set their permissions (administrator, regular user or guest), and manage their access. New accounts default to regular user, so only accounts you explicitly promote get administrator rights.

Step 13: Back up and restore

The whole library — references, tags, projects, settings and the uploaded PDFs — lives under /var/www/i-librarian/data (the SQLite databases in data/database, the documents in data/pdfs and data/supplements). Back it up with a routine archive:

sudo tar czf "i-librarian-$(date +%F).tar.gz" -C /var/www/i-librarian data

Restore into a fresh instance by extracting the archive back over /var/www/i-librarian/data (stop the web units first, then sudo chown -R www-data:www-data /var/www/i-librarian/data).

Step 14: Security recommendations

  • Put I, Librarian behind TLS. The image serves plain HTTP on port 80. Terminate HTTPS at an Azure Application Gateway, a load balancer, or a reverse proxy in front of the VM, and restrict port 80 to that front end.
  • Restrict SSH to your administration network with an NSG rule.
  • Rotate the administrator password (Step 6) and keep the credentials file (/root/i-librarian-credentials.txt) readable only by root.
  • Keep self-registration disabled unless you deliberately want open signup; new accounts default to regular user.
  • Keep the OS patched. Unattended security upgrades are enabled; reboot periodically to pick up new kernels.
  • Back up regularly (Step 13), especially before a large import.

Step 15: Support and licensing

I, Librarian is distributed under the GNU General Public License v3.0; the licence text ships at /var/www/i-librarian/LICENSE. This cloudimg image bundles I, Librarian 5.11.3 with nginx, PHP, SQLite and the poppler/ghostscript/Tesseract toolchain from Ubuntu 24.04, configured and hardened as described above.

cloudimg provides 24/7 support for this image by email at support@cloudimg.co.uk. We help with library setup, PDF import and full-text indexing, OCR configuration, metadata lookup, user and project management, citation export, backup and restore, performance tuning and I, Librarian version upgrades.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.