Omeka S on Ubuntu 24.04 on Azure User Guide
Overview
Omeka S is a web publishing platform for galleries, libraries, archives and museums. It keeps one shared collection of items, item sets and media, each described with Dublin Core and other linked data vocabularies such as the Bibliographic Ontology and FOAF, using resource templates your team defines. From that single collection you can build any number of independent public sites, each with its own pages, navigation, theme and selection of items, and every resource is also published through a REST API that speaks JSON-LD. The cloudimg image delivers the official Omeka S 4.2.1 release fully installed on Ubuntu 24.04, served over HTTPS, with every per VM secret generated on first boot, so a working collections platform is serving within minutes of launch. Backed by 24/7 cloudimg support.
Omeka S is free software published under the GNU General Public License version 3. Omeka is a trademark of Digital Scholar; cloudimg is not affiliated with, endorsed by, or sponsored by Digital Scholar or the Omeka project. This image packages the upstream open source release together with cloudimg's provisioning, hardening and support.
What is included:
- Omeka S 4.2.1, served from
/var/www/omeka-s - PHP 8.3 (
php8.3-fpm, over a local UNIX socket) behind Apache 2.4, reachable athttps://<vm-ip>/; port 80 only ever redirects to HTTPS and serves no content of its own - A local MariaDB database, bound to
127.0.0.1only - A per VM administrator password, database password and HTTPS certificate, all generated on first boot and written to a root only file. No default, shared or published credential ships in the image
- The Omeka S installer, which creates the first administrator and is open to anyone until it has been run, was completed when the image was built. The web server refuses it, so there is no setup page for a stranger to reach
- Thumbnails generated with PHP's GD library for JPEG, PNG, GIF and WebP uploads
- Password reset links always point at this VM's own address, never at a hostname supplied by a browser
- 24/7 cloudimg support

Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is the recommended starting size for a single institution's collection; scale up for large collections, many concurrent editors or heavy public traffic, and add a data disk if you expect many gigabytes of media. NSG inbound: allow 22/tcp from your management network and 443/tcp (HTTPS) from wherever staff and visitors will browse. 80/tcp is optional and only redirects to HTTPS.
Step 1: Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Omeka S by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2s or larger); under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTPS (443). Then Review + create and Create.
Step 2: Deploy from the Azure CLI
cloudimg images carry a Marketplace purchase plan, so accept its terms once per subscription, then create the VM and open HTTPS:
az vm image terms accept --urn cloudimg1647283583153:omeka-s-ubuntu-24-04:default:latest
az vm create \
--resource-group my-omeka-rg \
--name omeka-s \
--image cloudimg1647283583153:omeka-s-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group my-omeka-rg --name omeka-s --port 443 --priority 900
Step 3: Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4: Confirm the Omeka S stack is running
First boot generates this VM's secrets and only then opens the front door, so if the web server is running the installation is ready. Check the three services:
systemctl is-active mariadb php8.3-fpm apache2
All three report active:
active
active
active
Confirm Omeka S answers over HTTPS on the VM itself. The image ships a self signed certificate, so -k is expected here until you install your own certificate in Step 11:
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/login
That prints 200. Only SSH and HTTPS are reachable from off the VM; the database and PHP-FPM deliberately are not:
sudo ss -lnt | grep -E ':(22|80|443|3306) ' | sort
LISTEN 0 4096 [::]:22 [::]:*
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 *:443 *:*
LISTEN 0 511 *:80 *:*
LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*
MariaDB appears only on 127.0.0.1:3306. PHP-FPM does not appear at all: it listens on a UNIX socket, not a TCP port.

Step 5: Retrieve the first boot credentials
Every secret on this VM was generated on its first boot and written to a file only root can read. Nothing here is shared with any other deployment:
sudo cat /root/omeka-s-credentials.txt
# cloudimg :: Omeka S credentials
# Generated on this VM's first boot. This file is readable only by root.
# Sign in at OMEKA_S_URL with the e-mail address and password below, then change
# both under your user account (top left) and set your real administrator e-mail
# under Settings.
OMEKA_S_URL=https://<vm-public-ip>/
omeka-s.admin.email=admin@example.com
omeka-s.admin.pass=<unique to this VM>
omeka-s.db.name=omeka_s
omeka-s.db.user=omeka
omeka-s.db.pass=<unique to this VM>
Omeka S signs users in by e-mail address, and its first administrator is admin@example.com, a placeholder you replace with your own address after signing in. The database password is the one Omeka S itself uses, stored in /var/www/omeka-s/config/database.ini (readable only by root and the web server). You can prove it works the same way Omeka S connects:
MYSQL_PWD="$(sudo grep '^omeka-s.db.pass=' /root/omeka-s-credentials.txt | cut -d= -f2-)" mariadb -u omeka omeka_s -Nse "SELECT value FROM setting WHERE id = 'version';"
That prints "4.2.1", the schema version of your database.

Step 6: Sign in to the admin dashboard
Browse to https://<vm-public-ip>/login. Your browser will warn about the self signed certificate; accept it to continue, or install your own certificate first (Step 11). Sign in with the e-mail address admin@example.com and the omeka-s.admin.pass value from Step 5.
The admin dashboard opens with the resource and site management menus:

Before anything else, make the account yours:
- Select Administrator (top left) and change the Email to your own address and the Password to one you choose. Passwords on this image must be at least 12 characters and mix upper case, lower case and a number.
- Open Settings and set Administrator email to the address outgoing mail should come from, and the Installation title to your institution's name.
Step 7: Create your first site and item
Omeka S keeps one collection and publishes it through sites. Choose Sites → Add site, give it a Title and a URL slug (for example harbour), and select Add. Then choose Items → Add new item: fill in Title and Description (Dublin Core), open the Media tab, select Upload and pick an image, and check that your site is listed on the Sites tab. Select Add.
Omeka S stores the original file and generates its thumbnails, which appear beside the item's metadata:

The item is immediately published on the public site at https://<vm-public-ip>/s/<slug>/item/<id>, where any visitor can browse and search the collection without signing in:

JPEG, PNG, GIF and WebP uploads get thumbnails; other formats, such as PDF and TIFF, are stored and can be downloaded but are shown with a generic icon. Build out the site under Sites → your site: Pages for exhibit and about pages, Navigation for the menu, Resources for which items the site shows, and Theme for its look.
Step 8: The installer is locked and only one account exists
The image contains exactly one account, the global administrator, and no API keys:
sudo mariadb -t omeka_s -e "SELECT id, email, role, is_active FROM user;"
+----+-------------------+--------------+-----------+
| id | email | role | is_active |
+----+-------------------+--------------+-----------+
| 1 | admin@example.com | global_admin | 1 |
+----+-------------------+--------------+-----------+
The Omeka S installer and the files that carry configuration, logs and dependency metadata are refused by the web server, while the sign in page is served normally:
for p in /login /install /index.php/install /config/database.ini /logs/application.log /composer.lock; do printf '%-24s %s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1$p)"; done
/login 200
/install 403
/index.php/install 403
/config/database.ini 403
/logs/application.log 403
/composer.lock 403

Uploaded media is stored under /var/www/omeka-s/files, which the web server serves as static files and never executes. Prove it on your own VM by placing a PHP file there and asking for it:
sudo install -d -o www-data -g www-data /var/www/omeka-s/files/original
printf '<?php echo "executed";\n' | sudo tee /var/www/omeka-s/files/original/probe.php >/dev/null
curl -sk -o /dev/null -w 'probe.php -> %{http_code}\n' https://127.0.0.1/files/original/probe.php
sudo rm -f /var/www/omeka-s/files/original/probe.php
probe.php -> 403
The request is refused outright, so nothing in it is ever run.
Step 9: How Omeka S learns its address
Omeka S builds absolute links from the address a browser uses, which is what lets it work on the public IP, the private IP or a domain name without configuration. The one place that matters for security is the password reset e-mail: if the reset link were built from whatever Host a stranger's browser sent, they could request a reset for one of your users and have the link point at a site they control. On this image the forgot password page always uses this VM's own name. omeka-s-hostname.service runs on every boot, finds the VM's public IP address (or its private address if it has none), and writes it here:
grep '^Define' /etc/apache2/conf-available/omeka-s-canonical-host.conf
That prints Define OMEKA_S_CANONICAL_HOST followed by your VM's public IP address. The same service issues the self signed HTTPS certificate for that address, and because it runs on every boot, an Azure public IP that changes across a stop and start is picked up automatically:
systemctl is-enabled omeka-s-hostname.service && sudo openssl x509 -in /etc/ssl/omeka-s/omeka-s.crt -noout -subject

The session cookie is issued with Secure, HttpOnly and SameSite=Lax and without a Domain attribute, so it works on the bare IP address in every browser.
Step 10: Configure outbound email
Omeka S sends password reset links and new user activation e-mails. This image does not ship a mail transfer agent, so no mail leaves the VM until you configure one. Azure blocks outbound port 25 on most subscriptions, so relay through an authenticated SMTP provider on port 587. Add a mail block to /var/www/omeka-s/config/local.config.php (inside the returned array) with your provider's details:
'mail' => [
'transport' => [
'type' => 'smtp',
'options' => [
'name' => 'collections.example.org',
'host' => 'smtp.example.org',
'port' => 587,
'connection_class' => 'login',
'connection_config' => [
'username' => 'omeka@example.org',
'password' => 'your-smtp-password',
'ssl' => 'tls',
],
],
],
],
Edit the file as root (sudo nano /var/www/omeka-s/config/local.config.php), then reload PHP with sudo systemctl reload php8.3-fpm. Set the Administrator email under Settings to an address your provider allows you to send from.
Step 11: Use a domain name and your own certificate
Point a DNS A record at the VM's public IP, then pin that name so Apache (and every password reset link Omeka S e-mails) uses it instead of the IP address:
echo 'collections.example.org' | sudo tee /etc/omeka-s/server-name
sudo /usr/local/sbin/omeka-s-hostname.sh
With the name resolving publicly, obtain a Let's Encrypt certificate and point Apache at it:
sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --webroot -w /var/www/omeka-s -d collections.example.org --deploy-hook 'systemctl reload apache2'
sudo sed -i -e 's#/etc/ssl/omeka-s/omeka-s.crt#/etc/letsencrypt/live/collections.example.org/fullchain.pem#' \
-e 's#/etc/ssl/omeka-s/omeka-s.key#/etc/letsencrypt/live/collections.example.org/privkey.pem#' \
/etc/apache2/sites-available/omeka-s.conf
sudo systemctl reload apache2
Port 80 must be open in your NSG while certbot validates, because the challenge arrives there and is redirected to HTTPS. Certbot renews the certificate automatically and reloads Apache after each renewal.
Step 12: Add modules and themes
Omeka S is extended with modules (for example CSV Import, Mapping, Value Suggest) and themes, published at omeka.org/s. The application code on this image is owned by root and cannot be modified by the web server, so a stolen administrator session can never be turned into code running on your server; install add ons from the shell instead. Check which are present:
ls /var/www/omeka-s/modules /var/www/omeka-s/themes
A new image carries only the default theme. To add a module, download its release zip, unpack it into modules as root and keep it root owned. For example, the official CSV Import module:
cd /tmp && curl -fsSLO https://github.com/omeka-s-modules/CSVImport/releases/download/v2.6.2/CSVImport-2.6.2.zip
sudo unzip -q CSVImport-2.6.2.zip -d /var/www/omeka-s/modules/
sudo chown -R root:root /var/www/omeka-s/modules/CSVImport
Then open Modules in the admin, select Install beside the module and configure it. Themes work the same way under /var/www/omeka-s/themes, and are chosen per site under Sites → your site → Theme.
Step 13: Security model
- No default or shared credential ships in the image. The Omeka S administrator password, the database password and the HTTPS certificate are all generated on this VM's first boot.
- The installer was completed when the image was built and is refused at the web server, as are
config,logs,vendor, the application source and the project's metadata files. - The web server stays closed until first boot has generated this VM's secrets, so a VM is never reachable half configured.
- The application code is owned by
rootand read only to the web server; onlyfiles(uploads and thumbnails) andlogsare writable, and nothing uploaded is ever executed as code. - Only
22/tcpand443/tcpare reachable from off the VM.80/tcpissues a permanent redirect to HTTPS and serves nothing else. MariaDB is bound to127.0.0.1and PHP-FPM uses a UNIX socket. - Password reset links use the name this VM writes for itself, never a browser supplied host name. The session cookie is
Secure,HttpOnlyandSameSite=Lax, and only TLS 1.2 and 1.3 are accepted. - SSH refuses root and password logins; sign in as
azureuserwith your key. Ubuntu's unattended security upgrades remain enabled.
Step 14: Back up your collection
Omeka S keeps its state in the MariaDB database and in the files directory (originals and thumbnails):
sudo mariadb-dump --single-transaction omeka_s > ~/omeka-s-db-$(date +%F).sql
sudo tar czf ~/omeka-s-files-$(date +%F).tar.gz -C /var/www/omeka-s files config/database.ini config/local.config.php
Copy both off the VM, and take an Azure disk snapshot before any upgrade.
Step 15: Maintenance and upgrades
Ubuntu security updates are applied automatically. Check which Omeka S release is installed:
grep "const VERSION" /var/www/omeka-s/application/Module.php
To move to a later release, back up first (Step 14), then replace the code while keeping your config, files, modules and themes:
cd /tmp && curl -fsSLO https://github.com/omeka/omeka-s/releases/download/v4.2.2/omeka-s-4.2.2.zip
sudo unzip -q omeka-s-4.2.2.zip -d /tmp/omeka-s-new
sudo rsync -a --delete --exclude config/ --exclude files/ --exclude modules/ --exclude themes/ --exclude logs/ /tmp/omeka-s-new/omeka-s/ /var/www/omeka-s/
sudo chown -R root:root /var/www/omeka-s && sudo chown -R www-data:www-data /var/www/omeka-s/files /var/www/omeka-s/logs
sudo chown root:www-data /var/www/omeka-s/config/*.ini /var/www/omeka-s/config/local.config.php
Replace 4.2.2 with the release you are installing. Then sign in: Omeka S detects the new version and asks you to run its database migration from the admin, which only a signed in global administrator can do.
Support
cloudimg provides 24/7 support for this image. Contact us at support@cloudimg.co.uk or through the cloudimg support page. For questions about Omeka S itself, see the Omeka S user manual and the Omeka forums.