Storage AWS

kiwix-serve 3.8.2 on AWS User Guide

| Product: kiwix-serve 3.8.2 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the kiwix-serve 3.8.2 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg file sharing and sync listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

kiwix-serve is the web server of the open source Kiwix project. It serves ZIM archives, compressed offline copies of web content such as Wikipedia in any language, Wiktionary, Stack Exchange sites, Project Gutenberg, TED talks and many more, with a built in library, an article reader and full text search. Everything is served from files on your instance, so the content stays available without any connection to the original sites.

The cloudimg image locks kiwix-serve down:

  • HTTPS from the first boot. nginx serves the library on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped.
  • A sign in unique to your instance. kiwix-serve has no login of its own, so nginx puts HTTP Basic authentication in front of it. First boot generates a random password for the user admin and writes it to /root/kiwix-serve-credentials.txt (root only). The image ships with no password, no certificate and no published site: until first boot has finished, nothing is served.
  • The content server stays on localhost. kiwix-serve listens on 127.0.0.1:8080 only, as an unprivileged kiwix account that can read your library but cannot change it, and it is blocked at the kernel level from opening any connection beyond the instance itself, including the EC2 instance metadata service.
  • Read only by design. nginx passes only GET and HEAD requests to kiwix-serve, never forwards your sign in to it, and keeps search terms out of its access log.
  • A sample book to start with. The library ships with one small book, a selection of English Wikipedia articles on climate change, so you can try the reader and search straight away. Add your own ZIM files in Step 7.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: kiwix-tools 3.8.2 (kiwix-serve, kiwix-manage, kiwix-search in /usr/local/bin, the official statically linked release), the sample book in /var/lib/kiwix, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH), TCP 443 (the library) and TCP 80 (redirects to HTTPS) from your own networks only.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick kiwix-serve 3.8.2 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, a security group as above, and a subnet. The AMI brings an 8 GiB root volume; ZIM archives can be large (a full English Wikipedia with pictures is over 100 GB), so raise the root volume under Configure storage, or attach a data volume later (Step 7), to fit the books you plan to serve.

With the AWS CLI (replace the values in angle brackets; this sets the root volume to 50 GiB):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=50,VolumeType=gp3}' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=kiwix}]'

Step 2: Connect to your instance

Version SSH user
kiwix-serve 3.8.2 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot generates the certificate and the password, then publishes the site. It takes a few seconds:

systemctl is-active kiwix-serve-firstboot kiwix-serve nginx
active
active
active

Only SSH (22) and nginx (80, 443) listen on the network. kiwix-serve (8080) listens on loopback, and the other two are Ubuntu's local DNS resolver:

sudo ss -lntp | awk 'NR>1 {print $4}' | sort -u
0.0.0.0:22
0.0.0.0:443
0.0.0.0:80
127.0.0.1:8080
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
[::]:443
[::]:80

If nginx serves nothing, first boot has not finished (or failed, in which case the site is never published). Check systemctl status kiwix-serve-firstboot and journalctl -u kiwix-serve-firstboot.

Step 4: Get your URL and password

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

The file is readable by root only and holds the address and this instance's sign in:

# kiwix-serve - this instance's library sign-in (HTTP Basic Auth), generated on this instance; unique to it.
# Open KIWIX_URL in a browser (the certificate is self-signed until you install your own; see the guide) and sign in.
# Rotate the password with: sudo kiwix-reset-password      Change the served name: sudo kiwix-set-hostname <name>
# Guide: https://www.cloudimg.co.uk/guides/kiwix-serve-3-8-2-on-ubuntu-24-04-aws/
KIWIX_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/
KIWIX_HTTP_USER=<KIWIX_HTTP_USER>
KIWIX_BASIC_AUTH_PASSWORD=<KIWIX_BASIC_AUTH_PASSWORD>
KIWIX_HEALTHZ=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/healthz

The URL uses the instance's public DNS name from EC2 instance metadata. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too. To serve the library under your own DNS name, see Step 9.

You can prove the sign in works from the command line. The check signs in through nginx exactly as a browser does: an anonymous request and a wrong password are refused, and this instance's password opens the library, the catalog, an article and a search:

sudo kiwix-verify.sh
kiwix: anonymous 401, wrong password 401, instance password 200 (library, catalog, article wikipedia_en_climate-change_mini_2026-10, search)
KIWIX_ROUNDTRIP_OK

Step 5: Open the library

Open the KIWIX_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own certificate, Step 9). The browser then asks for a user name and password: enter KIWIX_HTTP_USER and KIWIX_BASIC_AUTH_PASSWORD from Step 4. The library opens with every book on the instance; filter by language or category, or search the titles.

The Kiwix library on cloudimg, served over HTTPS, with the sample book

Step 6: Read and search

Open a book to read it in the built in reader. The bar at the top returns to the library, opens a random article, and searches the book you are reading.

The sample book's main page in the Kiwix reader

A Wikipedia article in the Kiwix reader

Search runs against the full text of the book, using the index built into the ZIM file, and lists matching articles with a snippet:

Full text search results across the sample book

The same library is also available as an OPDS catalog at https://<your-host>/catalog/v2/entries (with the same sign in), which Kiwix desktop and mobile apps and other OPDS readers can browse.

Step 7: Add your own books

The library lives in /var/lib/kiwix. Its manifest, library.xml, lists the books kiwix-serve offers, and kiwix-serve reloads it automatically when it changes. Find ZIM files in the Kiwix library or at download.kiwix.org. The directory and files belong to root and are readable by the kiwix account, which can read but never change them. To add a book (this example is a small Wikipedia selection; use any ZIM file you like):

cd /var/lib/kiwix
sudo curl -fLO https://download.kiwix.org/zim/wikipedia/wikipedia_en_ray-charles_maxi_2026-08.zim
sudo chown root:kiwix wikipedia_en_ray-charles_maxi_2026-08.zim && sudo chmod 0640 wikipedia_en_ray-charles_maxi_2026-08.zim
sudo kiwix-manage /var/lib/kiwix/library.xml add /var/lib/kiwix/wikipedia_en_ray-charles_maxi_2026-08.zim

To list the books, and to remove one (by the id show prints; delete the file afterwards):

sudo kiwix-manage /var/lib/kiwix/library.xml show | grep -E '^(id|path|title):'
id:     0f31ce81-5ccc-a70c-bab7-4e40276eb7f4
path:       /var/lib/kiwix/wikipedia_en_climate-change_mini_2026-10.zim
title:      Climate change by Wikipedia
sudo kiwix-manage /var/lib/kiwix/library.xml remove <book-id>

For large collections, attach an EBS volume, format it and mount it at /var/lib/kiwix (copy the existing files across first), with an /etc/fstab entry by UUID and the nofail option. Keep the owner root:kiwix and the modes 0750 for the directory and 0640 for the files.

Step 8: Change the password

To generate a new password (for example after sharing the old one), run the command below. The new password is written to /root/kiwix-serve-credentials.txt and the old one stops working at once:

sudo kiwix-reset-password

To give several people their own sign in, add lines to /etc/nginx/kiwix.htpasswd in the same name:hash form (create a hash with openssl passwd -6, which prompts for the password) and run sudo systemctl reload nginx. To publish the library without a sign in, remove the two auth_basic lines from /etc/nginx/sites-available/cloudimg-kiwix and reload nginx; do this only if everyone who can reach port 443 may read every book.

Step 9: Use your own host name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address across stop and start), then tell the instance its name. This mints a new self signed certificate for that name, updates the nginx host rule and the address in the credentials file, and keeps the name across reboots:

sudo kiwix-set-hostname library.example.com

To use a certificate from a public authority instead, replace /etc/ssl/kiwix/kiwix.crt (full chain) and /etc/ssl/kiwix/kiwix.key (mode 0600, owned by root) with your own and run sudo systemctl reload nginx. Running kiwix-set-hostname again later would replace them with a new self signed pair.

Step 10: Check persistence and updates

Every service is enabled, so the library returns after a reboot or a stop and start. If the public address changes, the next boot re-issues the certificate and the address for the new name (unless you set your own name in Step 9). Unattended security upgrades keep the operating system and nginx patched:

systemctl is-enabled kiwix-serve kiwix-set-host nginx unattended-upgrades
enabled
enabled
enabled
enabled

kiwix-serve itself is the official static release from the Kiwix project. To move to a newer release later, download its kiwix-tools_linux-x86_64-musl-<version>.tar.gz from download.kiwix.org, check its checksum, replace the three files in /usr/local/bin and run sudo systemctl restart kiwix-serve.

Step 11: Back up your library

The books are plain ZIM files you can download again; the only state is /var/lib/kiwix/library.xml and any books you added. An EBS snapshot of the volume that holds /var/lib/kiwix (or AWS Backup on the instance) keeps both. For a file level copy:

sudo tar czf kiwix-library-backup.tar.gz -C /var/lib/kiwix library.xml

Security notes

  • No shared secret ships in the image. No password, password file or TLS key exists until your instance's first boot generates them, and the site is not published until then.
  • Fail closed. If first boot cannot complete, nothing is published: nginx has nothing to serve and kiwix-serve does not start.
  • kiwix-serve is confined. It listens on 127.0.0.1 only, runs as an unprivileged account with a read only view of the system and no write access to the library, and may open network connections to the instance itself only, so it cannot reach the internet or the EC2 instance metadata service. nginx is blocked from the metadata service too.
  • No request can make the server fetch a URL or change state. kiwix-serve only reads the books in its library. The statically linked release includes the curl library (8.4.0), used by Kiwix only to fetch a book illustration from a remote address when a library entry names one and carries no picture of its own; kiwix-manage add stores the picture with the book, the shipped library names no remote address, and the connection wall above would refuse it anyway, so the curl advisories published since that version cannot be reached from a web request.
  • Restrict 22/tcp to your management network, and 80/443 to the networks that use the library.

Architecture summary

Component Detail
Content server kiwix-serve 3.8.2 (kiwix-tools, GPL-3.0), kiwix-serve.service, 127.0.0.1:8080, account kiwix
Web server nginx on 443 (HTTPS, per instance certificate in /etc/ssl/kiwix, HTTP Basic authentication), 80 redirects to HTTPS
Library /var/lib/kiwix (library.xml and the ZIM files), owner root:kiwix, read only to kiwix-serve
Sample book wikipedia_en_climate-change_mini_2026-10.zim, Wikipedia text under CC BY-SA
Credentials /root/kiwix-serve-credentials.txt, mode 0600, root only; password hash in /etc/nginx/kiwix.htpasswd
First boot kiwix-serve-firstboot.service; host name and certificate kiwix-set-host.service (every boot)
Tools kiwix-manage (library), kiwix-reset-password, kiwix-set-hostname, kiwix-verify.sh
Ports 22 SSH, 80 redirect, 443 library, reader, search and OPDS catalog
Base image Ubuntu 24.04 LTS, fully patched, unattended security upgrades enabled, IMDSv2 required

Support

cloudimg images come with 24/7 support. Email support@cloudimg.co.uk with your AWS account ID and the instance ID. For kiwix-serve itself, see the kiwix-tools project on GitHub and the kiwix-serve documentation.

kiwix-serve and Kiwix are projects of the Kiwix association; Wikipedia is a trademark of the Wikimedia Foundation. cloudimg is not affiliated with or endorsed by either.