Storage Azure

kiwix-serve 3.8 Offline Content Server on Ubuntu 24.04 on Azure User Guide

| Product: kiwix-serve 3.8 Offline Content Server on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of kiwix-serve 3.8 on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. kiwix-serve is a single, self contained HTTP server that serves offline ZIM content archives, self contained snapshots of Wikipedia, StackExchange, Project Gutenberg, wikis and other websites, through a built in library and reader web UI. Visitors browse the catalog, open articles and run full text search entirely offline, with no internet connection required once the archives are in place. kiwix-serve is part of the Kiwix project and is released under the GNU General Public License v3.0 or later.

The image installs the official statically linked kiwix-tools release (version 3.8.2 at build time) to /usr/local/bin. The kiwix-serve HTTP listener is bound to loopback only and fronted by nginx on port 80 with HTTP Basic Auth, so the library is never exposed without a credential. At first boot, kiwix-serve-firstboot.service generates a unique per VM Basic Auth password (there is no default login baked into the image), reloads nginx, proves an authenticated round trip, and writes the password to /root/kiwix-serve-credentials.txt (mode 0600, root only). A small sample archive, the top hundred English Wikipedia articles, is bundled so the library works the moment the VM boots; you can add your own ZIM files at any time.

What is included:

  • kiwix-serve, kiwix-manage and kiwix-search 3.8.2 (official static musl release), pinned and sha256 verified

  • A bundled sample ZIM, the top hundred English Wikipedia articles (Wikipedia content under CC BY-SA 3.0, freely redistributable), at /var/lib/kiwix

  • kiwix-serve.service systemd unit running the server as the unprivileged kiwix user, bound to loopback with a hardened service sandbox

  • kiwix-serve-firstboot.service systemd oneshot that generates the per VM HTTP Basic Auth password, reloads nginx, proves an authenticated round trip and writes /root/kiwix-serve-credentials.txt

  • nginx on port 80 reverse proxying to the loopback bound kiwix-serve listener, with HTTP Basic Auth and an unauthenticated /healthz for load balancer probes

  • The Kiwix library and reader web UI, reachable at http://<vm-ip>/ after signing in

  • Ubuntu 24.04 LTS base with the latest security patches

  • Azure Linux Agent for seamless cloud integration and SSH key injection

  • 24/7 cloudimg support with guaranteed 24 hour response SLA

Prerequisites

  • An active Azure subscription, SSH public key, VNet plus subnet in the target region

  • A subscription to the kiwix-serve 3.8 on Ubuntu 24.04 listing on Azure Marketplace

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small libraries. For large archives (a full Wikipedia is tens of GB) and higher traffic, use Standard_D2s_v5 or larger and resize the OS disk to fit your ZIM files.

Step 1: Deploy from the Azure Portal

Search kiwix in Marketplace, select the cloudimg publisher entry, then click Create.

NSG rules: allow TCP 22 from your management IP and TCP 80 from your client IPs. The kiwix-serve HTTP listener is bound to loopback, so only nginx on port 80 is exposed. The library is protected by HTTP Basic Auth, but for public deployments put a TLS terminating reverse proxy in front of port 80 so credentials and content are encrypted in transit.

Step 2: Deploy from the Azure CLI

RG="kiwix-prod"; LOCATION="eastus"; VM_NAME="kiwix-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/kiwix-serve/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name kx-vnet --address-prefix 10.90.0.0/16 --subnet-name kx-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name kx-nsg
az network nsg rule create -g "$RG" --nsg-name kx-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name kx-nsg --name allow-http --priority 110 \
  --source-address-prefixes "<your-client-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name kx-vnet --subnet kx-subnet --nsg kx-nsg --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

kiwix-serve.service and nginx.service start automatically, and kiwix-serve-firstboot.service generates the per VM Basic Auth password on the first boot.

Step 4: Verify the kiwix-serve Service

sudo systemctl is-active kiwix-serve.service nginx.service
sudo test -f /var/lib/cloudimg/kiwix-serve-firstboot.done && echo FIRSTBOOT_DONE

Both services should report active, and the first boot sentinel should be present.

kiwix-serve and nginx services reporting active, and the ss listener table showing nginx bound to port 80 and kiwix-serve bound to loopback 8080

Step 5: Inspect the Listeners

The kiwix-serve HTTP listener is bound to 127.0.0.1:8080, and nginx serves it on port 80. Nothing but nginx listens on a public interface.

sudo ss -tln | grep -E ':80 |:8080'

Step 6: Review the Bundled Library

The bundled sample archive and the library.xml manifest that kiwix-serve serves live in /var/lib/kiwix:

sudo /usr/local/bin/kiwix-manage /var/lib/kiwix/library.xml show
ls -lh /var/lib/kiwix/

You will see the book metadata (title, article count, size) and the ZIM file on disk.

kiwix-manage show output listing the bundled Wikipedia 100 book with its article count and size, and the ls listing of the ZIM file and library.xml in /var/lib/kiwix

Step 7: Retrieve the Access Password

The per VM HTTP Basic Auth password is generated at first boot and stored in a root only file:

sudo cat /root/kiwix-serve-credentials.txt

You will see the sign in user, the per VM password, and the endpoint URLs:

KIWIX_HTTP_USER=admin
KIWIX_BASIC_AUTH_PASSWORD=<KIWIX_BASIC_AUTH_PASSWORD>
KIWIX_URL=http://<vm-ip>/
KIWIX_HEALTHZ=http://<vm-ip>/healthz
KIWIX_LOCAL_HTTP=http://127.0.0.1:8080/

The per VM kiwix-serve credentials file at /root/kiwix-serve-credentials.txt (mode 0600 root), the Basic Auth password redacted, showing the sign in user and the library and health check endpoint URLs

Step 8: Verify Access Control over HTTP

kiwix-serve is reached only through the authenticated nginx proxy. Confirm that an unauthenticated request is rejected, that the per VM password works, and that an article loads over HTTP:

PW=$(sudo grep '^KIWIX_BASIC_AUTH_PASSWORD=' /root/kiwix-serve-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'no creds: %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'library index: %{http_code}\n' -u "admin:$PW" http://127.0.0.1/
BOOK=$(curl -s http://127.0.0.1:8080/catalog/v2/entries | grep -oE '/content/[^"<]+' | head -1 | sed 's:/content/::')
curl -sL -o /dev/null -w 'article: %{http_code}\n' -u "admin:$PW" "http://127.0.0.1/content/$BOOK"

The unauthenticated request returns 401, the authenticated library index returns 200, and the article fetch returns 200. The unauthenticated /healthz endpoint stays open for load balancer probes.

Access control proof over HTTP: an unauthenticated request returning HTTP 401, an authenticated library index returning HTTP 200, and an authenticated article fetch returning HTTP 200

Step 9: Open the Library in a Browser

Open http://<vm-ip>/ from your workstation (assuming the NSG allows TCP 80). Your browser prompts for HTTP Basic Auth: sign in with user admin and the per VM password from /root/kiwix-serve-credentials.txt. The library welcome page lists every archive on the server:

The Kiwix library welcome page after signing in, showing the bundled Wikipedia 100 book card with its description, a language and category filter, a search box, and a Powered by Kiwix footer

Step 10: Browse an Archive

Click a book to open it in the built in reader. The archive's main page renders offline, with the reader navigation bar and search box at the top:

The Kiwix reader showing the Wikipedia 100 main page, a visual index of the top articles including the White House, Antarctica and other entries, with the reader navigation bar and search box

Step 11: Read an Article

Open any article and it renders exactly as it would online, including infoboxes and images, entirely from the offline archive:

The World Heritage Site Wikipedia article rendered offline in the Kiwix reader, with the full article text and the World Heritage Site infobox showing formation year and other facts

Step 12: Full Text Search

Use the search box to run full text search across an archive. Results list matching articles with snippets and word counts:

Kiwix full text search results for the query world, showing 56 matching articles including World Heritage Site and List of World Heritage Sites of Europe, each with a snippet and word count

Step 13: Add Your Own Archives

Download any ZIM from the Kiwix library, drop it in /var/lib/kiwix, and register it with kiwix-manage. kiwix-serve runs with --monitorLibrary, so it reloads the library automatically, no restart needed. Replace <version> with the current dated filename from the download site:

cd /var/lib/kiwix
sudo curl -fLO https://download.kiwix.org/zim/other/archlinux_en_all_maxi_<version>.zim
sudo /usr/local/bin/kiwix-manage /var/lib/kiwix/library.xml add /var/lib/kiwix/archlinux_en_all_maxi_<version>.zim
sudo chown kiwix:kiwix /var/lib/kiwix/*

Browse to the library and the new archive appears alongside the bundled sample.

Step 14: Server Components

Component Path
kiwix-serve binary /usr/local/bin/kiwix-serve
kiwix-manage binary /usr/local/bin/kiwix-manage
Archive directory /var/lib/kiwix
Library manifest /var/lib/kiwix/library.xml
Systemd unit /etc/systemd/system/kiwix-serve.service
Firstboot script /usr/local/sbin/kiwix-serve-firstboot.sh
Firstboot service /etc/systemd/system/kiwix-serve-firstboot.service
Credentials file /root/kiwix-serve-credentials.txt (mode 0600)
Firstboot sentinel /var/lib/cloudimg/kiwix-serve-firstboot.done
nginx site /etc/nginx/sites-available/cloudimg-kiwix
Basic Auth file /etc/nginx/.kiwix_htpasswd

Step 15: Managing the Service

sudo systemctl status kiwix-serve.service --no-pager | head -6
sudo journalctl -u kiwix-serve.service --no-pager | tail -5

To restart the service after adding archives or changing options, run sudo systemctl restart kiwix-serve.service.

Step 16: Security Recommendations

  • Rotate the Basic Auth password by regenerating /etc/nginx/.kiwix_htpasswd with openssl passwd -apr1 and reloading nginx, and store the password in your secrets manager

  • Keep the HTTP listener on loopback as shipped; expose only nginx on port 80, and put TLS in front of it (Azure Application Gateway, or nginx with a real certificate)

  • Restrict the NSG so port 80 only reaches trusted client networks

  • Make the library public only if intended by removing the auth_basic lines from /etc/nginx/sites-available/cloudimg-kiwix and reloading nginx

  • Only add archives you have the right to redistribute; Wikipedia and StackExchange ZIMs are CC BY-SA and freely redistributable, and each book's licence and attribution are shown in the library UI

  • Back up the archive directory at /var/lib/kiwix, or take Azure disk snapshots

  • Patch the OS monthly with sudo apt-get update && sudo apt-get upgrade && sudo reboot

Step 17: Support and Licensing

kiwix-serve is licensed under the GNU General Public License v3.0 or later. There are no per node, per CPU, or per GB fees. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the Kiwix or openZIM project; Kiwix is a trademark of its respective owner and is used here only to describe the software included in the image. The bundled sample archive contains Wikipedia content under the Creative Commons Attribution ShareAlike 3.0 licence.

cloudimg provides commercial support for this image separately from the upstream project.

  • Email: support@cloudimg.co.uk

  • Website: www.cloudimg.co.uk

  • Support hours: 24/7 with guaranteed 24 hour response SLA

Deploy on Azure

Launch kiwix-serve 3.8 Offline Content Server on Ubuntu 24.04 with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7.

support@cloudimg.co.uk