S2
Applications Azure

Sakai 25 on Ubuntu 24.04 on Azure User Guide

| Product: Sakai 25 on Ubuntu 24.04 LTS on Azure

Overview

Sakai is a mature open source learning management system built for higher education: course and project sites, the Lessons page builder, Assignments with rubrics and peer review, Tests & Quizzes, a full Gradebook, Resources with versioned file storage, Forums, Announcements, Calendar, Sign-up, Polls, Wiki, Chat, Site Statistics and LTI 1.3 tool integration. It is stewarded by the Apereo Foundation and is in production at universities across North America and the Spanish-speaking world. The cloudimg image delivers the official Sakai 25.2 release fully installed on Ubuntu 24.04, served over HTTPS, with every per-VM secret generated on first boot — so a working LMS is serving within minutes of launch. Backed by 24/7 cloudimg support.

Sakai is free software published under the Educational Community License version 2.0, an Apache 2.0 derivative. Sakai is a trademark of the Apereo Foundation; cloudimg is not affiliated with, endorsed by, or sponsored by the Apereo Foundation. This image packages the upstream open source release with cloudimg's provisioning, hardening and support.

What is included:

  • Sakai 25.2, deployed into Apache Tomcat 9.0.122 at /opt/tomcat, running on OpenJDK 17
  • nginx 1.24 terminating HTTPS in front of Tomcat, reachable at https://<vm-ip>/portal; port 80 only ever redirects to HTTPS and serves no content of its own
  • A local MySQL 8.4 LTS database, bound to 127.0.0.1 only
  • Sakai's Quartz scheduler running the scheduled jobs in-process, rather than through a web-triggered endpoint
  • A per-VM administrator password, database password, Sakai server identifier 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
  • Sakai's database schema is built during the image build, so there is no installation wizard exposed on your VM and nothing to configure before you sign in
  • Sakai's sample-user provider and demo dataset are removed from the image entirely, so the published demo accounts cannot exist
  • Tomcat's manager, host-manager, examples and docs web applications are removed, the AJP connector is deleted, and the Tomcat shutdown port is disabled
  • 24/7 cloudimg support

The Sakai sign-in page served over HTTPS

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region.

Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended minimum size and is what this image is tuned for. Sakai deploys roughly one hundred web applications into a single JVM, so it is demanding of both heap and metaspace: the image runs Tomcat with a 3 GB maximum heap and 768 MB of metaspace alongside MySQL and the operating system. A 4 GiB Standard_B2s is not supported — it cannot hold that footprint and the JVM will fail. Scale up to Standard_B4ms or larger for a real cohort: more vCPUs materially shorten Sakai's start-up and improve concurrency under load.

NSG inbound: allow 22/tcp from your management network and 443/tcp (HTTPS) from wherever your learners and staff 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 Sakai by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2ms 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

az vm create \
  --resource-group <your-rg> \
  --name sakai \
  --image <marketplace-image-urn> \
  --size Standard_B2ms \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_rsa.pub \
  --public-ip-sku Standard \
  --os-disk-delete-option Delete \
  --nic-delete-option Delete

Then open the ports you need:

az vm open-port --resource-group <your-rg> --name sakai --port 443 --priority 1010
az vm open-port --resource-group <your-rg> --name sakai --port 80  --priority 1020

Step 3: Wait for first boot, then retrieve your credentials

The first boot generates this VM's own secrets and then starts Sakai. Because Sakai deploys roughly one hundred web applications into a single JVM, this takes a while: on a Standard_B2ms it is about fifteen to twenty minutes before the sign-in page answers (measured: 18 minutes on a freshly launched VM). Subsequent reboots are quicker. Until first boot has finished, nginx deliberately refuses to start — so the VM is unreachable rather than serving a half-configured LMS. That is by design, not a fault.

Connect over SSH and read the credentials file:

Connect over SSH from your own machine:

ssh azureuser@<vm-public-ip>

Then, on the VM:

sudo cat /root/sakai-credentials.txt

You will see something like:

# cloudimg :: Sakai appliance credentials
# Generated on this VM's first boot. This file is readable only by root.
# Change the administrator password after your first sign-in.
sakai.admin.user=admin
sakai.admin.pass=<a unique 24-character password>
sakai.db.name=sakai
sakai.db.user=sakai
sakai.db.pass=<a unique 32-character password>
sakai.server.id=cloudimg-<unique>

The file is mode 600 and owned by root, so only a user who can sudo can read it. Note that admin here is Sakai's own administrator account, not the Linux root user.

If the page is not answering yet, check progress with:

systemctl is-active sakai-firstboot.service sakai.service nginx.service
sudo journalctl -u sakai.service --no-pager -n 20

Step 4: Sign in

Browse to https://<vm-public-ip>/portal. Your browser will warn about the self-signed certificate that first boot generated — that is expected until you install your own certificate (Step 8). Accept the warning, then sign in with the username admin and the password from /root/sakai-credentials.txt.

The Administration Workspace Users tool. A freshly launched VM has exactly two accounts, admin and postmaster: the Sakai demo dataset is removed from this image, so none of the published sample logins exist

Change the administrator password immediately after your first sign-in: choose Administration Workspace from the sites menu, then Users, search for admin, and set a new password. Then create a named account for each administrator rather than sharing admin.

Step 5: Create your first course site

From Administration Workspace, choose Sites, then New Site. Pick course site or project site, give it a title and description, choose the tools you want (Lessons, Assignments, Tests & Quizzes, Gradebook, Resources, Forums are the usual starting set), add participants with their roles, and publish it.

The Sites tool in the Administration Workspace, listing the sites Sakai creates for itself on a fresh installation

Course and project sites are created and managed from Worksite Setup. Once a site exists it appears in the sites menu at the top of the portal, with the tools you selected down the left-hand side.

Worksite Setup, where course and project sites are created and managed. Create New Site starts the wizard

Step 6: The scheduled job runner

Sakai runs its scheduled jobs through an in-process Quartz scheduler rather than a public web endpoint, so nothing needs to be exposed for jobs to run. The scheduler deliberately starts five minutes after Tomcat, so do not be alarmed if it is not yet registered immediately after boot.

Review and schedule jobs from Administration Workspace, then Job Scheduler. To confirm the scheduler is alive from the shell:

sudo mysql --protocol=socket -u root sakai \
  -e "SELECT TRIGGER_NAME, TRIGGER_STATE, PREV_FIRE_TIME, NEXT_FIRE_TIME FROM QRTZ_TRIGGERS;"

A trigger in WAITING state with a future NEXT_FIRE_TIME is an armed job. After a job has run, its PREV_FIRE_TIME moves off -1 — that is proof the scheduler actually executed something, not merely that it was configured. (QRTZ_SCHEDULER_STATE stays empty on this image: that table is Quartz's clustering check-in, and this is a single-node deployment.)

Step 7: Point a domain name at the VM

Sakai builds absolute links from the serverUrl it is configured with, so once you have a hostname you should tell Sakai about it. The image rewrites serverUrl from the VM's own address on every boot, which is what makes an Azure public IP that changes across a stop/start work transparently — but a real hostname should be set explicitly so it is not overwritten.

Create an A record pointing your hostname at the VM's public IP, then edit /opt/tomcat/sakai/sakai.properties:

sudo sed -i 's|^serverUrl=.*|serverUrl=https://lms.example.edu|' /opt/tomcat/sakai/sakai.properties
sudo sed -i 's|^serverName=.*|serverName=lms.example.edu|' /opt/tomcat/sakai/sakai.properties
sudo systemctl disable sakai-baseurl.service
sudo systemctl restart sakai.service

Disabling sakai-baseurl.service is what stops the per-boot rewrite from replacing your hostname with the VM's IP address again.

Step 8: Install a trusted HTTPS certificate

The image generates a self-signed certificate on first boot so that HTTPS works out of the box. Replace it with a real certificate once you have a hostname:

sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d lms.example.edu

Certbot edits the nginx server block in /etc/nginx/sites-available/sakai.conf and installs a renewal timer. Keep the existing proxy_cookie_domain line in that file: it strips the cookie Domain attribute, which is what allows sign-in to work when Sakai is reached by IP address rather than by name.

Step 9: Outbound email

Sakai sends notifications, and needs an SMTP relay to do it. Set the relay in /opt/tomcat/sakai/sakai.properties:

smtp@org.sakaiproject.email.api.EmailService=smtp.example.edu
smtp.port@org.sakaiproject.email.api.EmailService=587
setup.request=noreply@example.edu

Then restart Sakai:

sudo systemctl restart sakai.service

Send a test message from Administration Workspace, then Email Test.

Step 10: Backups

Everything that matters lives in two places: the MySQL database, and the uploaded content under /var/lib/sakai/files.

sudo mysqldump --protocol=socket -u root --single-transaction --routines --triggers \
  sakai | gzip > /var/backups/sakai-$(date +%F).sql.gz
sudo tar czf /var/backups/sakai-files-$(date +%F).tar.gz -C /var/lib/sakai files

Copy both off the VM — to Azure Blob Storage or your own backup target — and test a restore before you rely on it. A VM snapshot alone is not a substitute for a database dump taken with --single-transaction.

Step 11: Upgrades

For a Sakai 25 maintenance release (25.3, 25.4, …), replace the deployed application and let Sakai upgrade its own schema:

# Always take a backup first (Step 10).
sudo systemctl stop sakai.service
cd /tmp
curl -fsSLO https://source.sakaiproject.org/release/25.3/artifacts/sakai-bin-25.3.tar.gz
# Verify the download against the .MD5 published alongside it before extracting.
sudo rm -rf /opt/tomcat/components /opt/tomcat/webapps
sudo tar -xzf sakai-bin-25.3.tar.gz -C /opt/tomcat
sudo find /opt/tomcat/components -name 'components-demo.xml' -delete
sudo find /opt/tomcat/components -name 'sakai-sample-provider-*.jar' -delete
sudo chown -R sakai:sakai /opt/tomcat
sudo systemctl start sakai.service

auto.ddl=true is set in sakai.properties, so Sakai applies its own schema changes on the next start. Watch /opt/tomcat/logs/catalina.out until the portal answers again. Keep re-deleting the demo provider files after every upgrade — the upstream archive ships them each time.

Operating system patches are handled by unattended-upgrades, which is enabled in the image.

Troubleshooting

The page does not load. Sakai takes about fifteen to twenty minutes on its very first boot (it is deploying ~100 web applications and its scheduler starts on a five minute delay). Check systemctl status sakai.service and sudo tail -f /opt/tomcat/logs/catalina.out. Confirm your NSG allows 443/tcp.

nginx will not start. That is the fail-closed design working: nginx refuses to start until /var/lib/cloudimg/sakai-firstboot.done exists, which first boot writes only after the per-VM administrator password is in place. Check systemctl status sakai-firstboot.service.

Sign-in fails with the password from the credentials file. Confirm you are using the username admin and that you copied the whole password (it contains symbols). If you have changed serverUrl, make sure it matches the address you are browsing to.

Out of memory, or the JVM will not start. You are almost certainly on a VM smaller than Standard_B2ms. Resize to Standard_B2ms or larger; the heap settings in /opt/tomcat/bin/setenv.sh assume at least 8 GiB of RAM.

Scheduled jobs are not running. The scheduler starts five minutes after Tomcat by design. Confirm with the QRTZ_SCHEDULER_STATE query in Step 6 and check that LAST_CHECKIN_TIME advances.

Checking what is listening. The image exposes only SSH, HTTP (redirect) and HTTPS off-box. Tomcat, MySQL and Sakai's internal cache endpoints are bound to the loopback interface:

sudo ss -lntp

Support

cloudimg provides 24/7 support for this image by email at support@cloudimg.co.uk and via live chat. Questions about Sakai feature behaviour are answered on a best effort basis and, where appropriate, directed to the Sakai community documentation maintained by the Apereo Foundation.