OpenOLAT on Ubuntu 24.04 on Azure User Guide
Overview
OpenOLAT is a mature open source learning management system used by universities, schools and training organisations, among them the Universities of Zurich, Bern and Innsbruck. It brings course design and delivery together in one web platform: a visual course editor with learning paths, SCORM, xAPI and IMS content packages, tests and a shared question bank built on QTI 2.1, assessment and grading tools, groups with forums, wikis and file sharing, e-portfolios, curriculum management, certificates and badges, calendars and virtual classroom integrations. The cloudimg image delivers the official OpenOLAT 21.0.3 release ready to use on Ubuntu 24.04, served over HTTPS, with every per-VM secret generated on first boot. Backed by 24/7 cloudimg support.
OpenOLAT is free software published under the Apache License 2.0; the licence and the project's NOTICE file ship in the image at /opt/openolat/LICENSE and /opt/openolat/NOTICE.TXT. OpenOlat and the OpenOlat logo are trademarks of frentix GmbH, Zurich; cloudimg is not affiliated with, endorsed by, or sponsored by frentix GmbH. This image packages the upstream open source release with cloudimg's provisioning, hardening and support.
What is included:
- OpenOLAT 21.0.3 from the official release (built from the upstream
OpenOLAT_21.0.3tag), deployed at/opt/openolat/webappwith its file store at/var/lib/openolat/olatdata - A dedicated Apache Tomcat 10.1 on Ubuntu's OpenJDK 21, listening on
127.0.0.1:8088only, with a Java heap sized automatically at 40% of the VM's memory - A local PostgreSQL 16 database, bound to
127.0.0.1only - nginx serving OpenOLAT over HTTPS at
https://<vm-ip>/; port 80 only ever redirects to HTTPS and serves no content of its own - A per-VM administrator password, database password, maintenance tokens, installation 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, and the web server does not start until first boot has finished
- The database schema is created during the image build, so there is no setup wizard and nothing to configure before you sign in
- Self-registration, guest access and the REST API are switched off until you choose to enable them
- 24/7 cloudimg support

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 starting size: OpenOLAT is a Java application with a local database, and on an 8 GiB VM the Java heap grows to about 3.2 GB automatically. Scale up for large course catalogues, many concurrent learners, or heavy video and SCORM use. 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 OpenOLAT 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 openolat \
--image <marketplace-image-urn> \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Open HTTPS so learners can reach the platform:
az vm open-port --resource-group <your-rg> --name openolat --port 443 --priority 900
Step 3: Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4: Confirm the OpenOLAT stack is running
First boot generates this VM's secrets and only then starts the application and the web server, so allow two or three minutes after the VM is created before you connect. When the three units are active, the platform is ready:
systemctl is-active postgresql openolat nginx
active
active
active
Confirm OpenOLAT answers over HTTPS on the VM itself and check the release. The image ships a self-signed certificate, so -k is expected here until you install your own certificate in Step 11:
curl -sk https://127.0.0.1/dmz/ | grep -oE 'OpenOlat( | )[0-9.]+' | sed 's/ / /' | sort -u
OpenOlat 21.0.3

Step 5: Check what the network can reach
Only SSH and the two web ports listen on the VM's network interfaces. Tomcat and PostgreSQL are bound to the loopback address, and systemd's DNS stub resolver is local only:
sudo ss -H -lnt | awk '{print $4}' | sort -u
0.0.0.0:22
0.0.0.0:443
0.0.0.0:80
127.0.0.1:5432
127.0.0.1:8088
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
[::]:443
[::]:80
Port 80 serves nothing but a permanent redirect to HTTPS:
curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' http://127.0.0.1/
301 -> https://127.0.0.1/

Step 6: 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/openolat-credentials.txt
# OpenOLAT 21.0.3 on Ubuntu 24.04 by cloudimg - per-VM credentials (generated at first boot)
# Sign in at the URL below as 'administrator'. Your browser will warn about the
# self-signed certificate until you install a certificate for your own domain.
OPENOLAT_URL=https://<vm-public-ip>/
openolat.admin.user=administrator
openolat.admin.pass=<unique to this VM>
openolat.db.name=openolat
openolat.db.user=openolat
openolat.db.pass=<unique to this VM>
administrator is OpenOLAT's built-in system administrator account. OpenOLAT's published default password for that account never exists in this image: the build seeds the account with a random value instead, and replaces it again before capture with a value nobody records. Your VM mints its own password on first boot, and the first-boot log records each step:
sudo tail -n 3 /var/log/cloudimg-firstboot.log
[...] openolat-firstboot: writing /root/openolat-credentials.txt
[...] openolat-firstboot: secrets minted - releasing the web stack
[...] openolat-firstboot: first boot complete - OpenOLAT is at https://<vm-public-ip>/

Step 7: Sign in
Browse to https://<vm-public-ip>/. Your browser warns about the self-signed certificate; accept it to continue, or install your own certificate first (Step 11). OpenOLAT signs you in in two steps: enter the username administrator and select Login, then enter the password from Step 6. The first time you sign in, OpenOLAT asks you to accept its terms of use.
You can also prove the credential from the VM itself. The image includes a small checker that signs in through the real OpenOLAT login form, reading the password from standard input so it never appears on a command line:
sudo sed -n 's/^openolat\.admin\.pass=//p' /root/openolat-credentials.txt | sudo /usr/local/sbin/openolat-login-check administrator
LOGIN_OK
OpenOLAT's published default password is rejected:
printf 'openolat' | sudo /usr/local/sbin/openolat-login-check administrator || true
LOGIN_REJECTED

Change the administrator password after your first sign-in: open the menu under your initials at the top right and choose Password. OpenOLAT requires at least 12 characters with a letter and a digit or symbol.
Step 8: Build and publish your first course
Choose Authoring in the top navigation, then Create and Course. Give the course a title, keep the default course design (With learning path) and select Create. OpenOLAT opens the new course's settings, and the course appears in Authoring under My entries with the status Preparation.

Open Administration in the course toolbar and choose Course editor. Use Insert course elements to add content, for example a Page for the course introduction, a Forum for discussion and a Folder for course materials. Rename each element on its Title and description tab and select Save.

Close the editor by selecting the course title in the breadcrumb and choose Publish automatically. The course now shows its elements in the learning path on the left. When you are ready for learners, change the course Status from Preparation to Published and add participants under Administration, Members management.

Step 9: Add users
Choose User management in the top navigation to create accounts one by one or import a list, and assign roles such as author, coach or learner administrator. For a larger institution, OpenOLAT can also sign users in through LDAP, Shibboleth or OpenID Connect identity providers instead of local accounts; see the OpenOLAT administrator manual for each option.
Step 10: Configure outbound email
OpenOLAT sends account, notification and password-reset mail. Outbound mail is switched off in this image until you configure a relay, and Azure blocks outbound port 25 on most subscriptions, so use an authenticated provider on port 587. Open More, Administration, Core functions, E-mail, enter your provider's host, port, username and password, then send yourself a test message.
Step 11: Use a domain name and your own certificate
Point a DNS A record at the VM's public IP. Then tell OpenOLAT the name it should use in the links it builds, such as those in notification mail. Until you do, the image keeps OpenOLAT pointed at the VM's current public IP on every boot; once you set your own name it is never overwritten:
sudo sed -i 's/^server\.domainname=.*/server.domainname=lms.example.com/' /opt/openolat/lib/olat.local.properties
sudo systemctl restart openolat
With the name resolving publicly, obtain a certificate for it. Certbot's nginx plugin installs it and renews it automatically:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d lms.example.com
Step 12: Security model
- No default or shared credential ships in the image. The OpenOLAT administrator password, the database password, OpenOLAT's maintenance and session-administration URL tokens, its installation identifier and the HTTPS certificate are all generated on this VM's first boot.
- The database role has no password at all in the captured image, and Tomcat and nginx are both held back until first boot has minted this VM's secrets, so a VM is never reachable half-configured.
- Only
22/tcp,80/tcpand443/tcplisten off the VM.80/tcpissues a permanent redirect to HTTPS and serves nothing else. Tomcat is bound to127.0.0.1:8088with no shutdown port and no sample applications, and PostgreSQL is bound to127.0.0.1. - Self-registration, guest access and the REST API are off by default:
sudo grep -E '^(server\.domainname|registration\.enableSelfRegistration|login\.enableGuestLoginLinks|restapi\.enable|smtp\.host)=' /opt/openolat/lib/olat.local.properties
server.domainname=<vm-public-ip>
smtp.host=disabled
registration.enableSelfRegistration=false
login.enableGuestLoginLinks=false
restapi.enable=false
Turn self-registration on under More, Administration, Login, Self-registration and guest access under Anonymous and external user, only when you intend to accept public sign-ups or anonymous visitors. - Ubuntu's unattended security upgrades remain enabled, and every package in the stack comes from Ubuntu's main archive except Apache Tomcat, which is the upstream 10.1 release.
Step 13: Memory and logs
The Java heap follows the VM size, so resizing the VM is all it takes to give OpenOLAT more memory:
ps -o args= -u openolat | tr ' ' '\n' | grep -E '^-XX:(Max|Initial)RAMPercentage'
-XX:InitialRAMPercentage=12
-XX:MaxRAMPercentage=40
OpenOLAT's application log is /opt/openolat/logs/olat.log and rolls over daily, keeping 30 days; Tomcat's own output goes to the systemd journal (journalctl -u openolat):
sudo tail -n 5 /opt/openolat/logs/olat.log
Step 14: Back up your platform
OpenOLAT keeps state in two places: the PostgreSQL database and the file store at /var/lib/openolat/olatdata. Stop the application briefly for a consistent pair:
sudo systemctl stop openolat
sudo -u postgres pg_dump -Fc openolat > ~/openolat-db-$(date +%F).dump
sudo tar czf ~/openolat-files-$(date +%F).tar.gz /var/lib/openolat/olatdata
sudo systemctl start openolat
Copy both off the VM, and take an Azure disk snapshot before any upgrade.
Step 15: Maintenance and upgrades
Ubuntu security updates, including OpenJDK, PostgreSQL and nginx, are applied automatically. To move to a later OpenOLAT 21 patch release, back up first (Step 14), then replace the web application with the new release and restart; OpenOLAT upgrades its own database schema on start. The release files are listed at openolat.com/releases; the example below uses openolat_2104.war, so substitute the file name of the release you are installing:
cd /tmp && curl -fsSLO https://www.openolat.com/releases/openolat_2104.war
sudo systemctl stop openolat
sudo mv /opt/openolat/webapp /opt/openolat/webapp.previous
sudo mkdir /opt/openolat/webapp && sudo unzip -q /tmp/openolat_2104.war -d /opt/openolat/webapp
sudo chown -R root:openolat /opt/openolat/webapp && sudo chmod -R g+rX,o+rX /opt/openolat/webapp
sudo systemctl start openolat
Watch sudo journalctl -u openolat -f until Tomcat reports that the server has started, then sign in and check the release shown at the bottom right of every page.
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 OpenOLAT itself, see the OpenOLAT documentation.