Gs
Applications Azure

Gibbon School MIS on Ubuntu 24.04 on Azure User Guide

| Product: Gibbon School MIS on Ubuntu 24.04 LTS on Azure

Overview

Gibbon is a free and open source school management platform, built for teachers, students, parents and school leaders. One web application covers student records and enrolment, the timetable and course catalogue, attendance by day and by period, the teacher markbook and reports, behaviour and pastoral care, a school calendar and student alerts, planners and homework, admissions, library, finance and billing, staff records, and a portal where parents and students follow their own timetables, grades and attendance. The cloudimg image delivers the official Gibbon v30.0.01 release fully installed on Ubuntu 24.04, served over HTTPS, with every per VM secret generated on first boot, so a working school administration system is serving within minutes of launch. Backed by 24/7 cloudimg support.

Gibbon is free software published under the GNU General Public License version 3. Gibbon is a trademark of its respective owner; cloudimg is not affiliated with, endorsed by, or sponsored by the Gibbon Foundation or Gibbon Education Ltd. This image packages the upstream open source release together with cloudimg's provisioning, hardening and support.

What is included:

  • Gibbon v30.0.01, served from /var/www/gibbon
  • PHP 8.3 behind Apache 2.4, reachable at https://<vm-ip>/; port 80 only ever redirects to HTTPS and serves no content of its own
  • A local MySQL 8.0 database, bound to 127.0.0.1 only
  • A per VM administrator password, database password, database maintenance password, installation id 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 database is installed at build time from the command line, and Gibbon's setup wizard is blocked outright, so there is no route for a stranger to claim your school
  • Password reset and notification links always point at this VM's own address, never at a hostname supplied by a browser
  • No demo or sample school data, so you start from a clean system
  • 24/7 cloudimg support

The Gibbon 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_B2s (2 vCPU / 4 GiB RAM) is the recommended starting size for a single school; scale up for a large school, many concurrent teachers taking registers or entering marks, or heavy report runs. NSG inbound: allow 22/tcp from your management network and 443/tcp (HTTPS) from wherever staff, parents and students will browse. 80/tcp is optional and only redirects to HTTPS.

Step 1: Deploy from the Azure Marketplace

In the Azure portal choose Create a resource, search for the cloudimg Gibbon School MIS offering, and select Create. Pick your subscription, resource group and region, set the VM size to Standard_B2s, choose SSH public key authentication with the username azureuser, and under Inbound port rules allow SSH (22) and HTTPS (443). Review and create.

Step 2: Deploy from the Azure CLI

az vm create \
  --resource-group my-resource-group \
  --name gibbon-01 \
  --image cloudimg:gibbon-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --storage-sku StandardSSD_LRS \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open the two ports you need:

az vm open-port --resource-group my-resource-group --name gibbon-01 --port 443 --priority 1001
az vm open-port --resource-group my-resource-group --name gibbon-01 --port 22  --priority 1002

Step 3: Connect to your VM

ssh azureuser@<vm-public-ip>

The build account is removed before the image is captured, so azureuser (or whichever admin name you chose at launch) is the only login on the VM.

Step 4: Confirm the Gibbon stack is running

First boot generates this VM's secrets and only then starts the web server, so allow two to three minutes after launch. Apache is deliberately held closed until that has finished, which means a VM that answers on 443 is a VM whose secrets are already in place.

systemctl is-active mysql apache2 gibbon-firstboot gibbon-baseurl

All four report active. Check what is actually listening, and that the database is not:

sudo ss -lnt | grep -E ':(22|80|443|3306) ' | sort

MySQL appears only on 127.0.0.1:3306. Confirm Gibbon answers and check the version:

curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/index.php
grep '^\$version' /var/www/gibbon/version.php

Services active, MySQL on loopback only, and the Gibbon version

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:

sudo cat /root/gibbon-credentials.txt
# cloudimg :: Gibbon School MIS appliance credentials
# Generated on this VM's first boot. This file is readable only by root.
# Sign in at https://<this-vm-address>/ and change the password afterwards.
gibbon.admin.user=admin
gibbon.admin.pass=<unique to this VM>
gibbon.db.name=gibbon
gibbon.db.user=gibbon
gibbon.db.pass=<unique to this VM>

The file is 0600 root:root, Gibbon's own config.php is 0640 root:www-data, and the TLS private key is 0600:

sudo stat -c '%a %U:%G %n' /root/gibbon-credentials.txt /var/www/gibbon/config.php /etc/ssl/gibbon/gibbon.key

The root only credentials file, with the per VM passwords hidden

Step 6: Sign in

Browse to https://<vm-public-ip>/. Your browser will warn about the self signed certificate until you install your own (Step 11). Sign in with the username admin and the password from Step 5.

The Gibbon dashboard after signing in

Change the administrator password now. Use the user menu at the top right, then Preferences, and set a password only you know. The password in /root/gibbon-credentials.txt exists so that you can get in the first time; it is not meant to be your long term credential.

Step 7: Set your school's details

Gibbon ships with the system name Gibbon and the placeholder organisation name Your School. Set your own under Admin → System Admin → System Settings, where you can also set your country, timezone and currency. Your school's year groups are already created (Year 7 to Year 13); rename or replace them under Admin → School Admin → Manage Year Groups to match your school's own naming.

Two school years are seeded, 2025-2026 and 2026-2027, and the Year Switcher on the dashboard moves between them.

Step 8: Build your school structure

Gibbon hangs enrolment, timetabling and reporting off a small amount of structure, so this is the first thing to create. Under Admin → School Admin you will find Manage Year Groups, Manage Form Groups, Manage Houses and Manage Departments. Houses, form groups and departments start empty.

Creating a house under School Admin

Add your people under Admin → User Admin → Manage Users. The image ships with exactly one account — the administrator you signed in as — so every other user is one you create.

Manage Users, showing the single administrator account the image ships with

Step 9: The setup wizard is blocked, on purpose

Gibbon's installer (installer/install.php) is an unauthenticated three step wizard, and upstream ships it with no guard against being run again on a system that is already installed. Reaching it on a live server lets a stranger point the site at their own database and create themselves an administrator. This image installs the database during the build and then blocks the installer at the web server, so it is refused no matter how the path is spelled, and no matter what state the database is in:

for p in /index.php /installer/install.php /installer/ /Installer/install.php /config.php /gibbon.sql; do
  printf '%-30s %s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' https://127.0.0.1$p)"
done

/index.php answers 200; everything else answers 403. A POST is refused too:

curl -sk -o /dev/null -w '%{http_code}\n' -d 'step=4' https://127.0.0.1/installer/install.php

And the image really does contain a single account:

sudo mysql --protocol=socket -u root -D gibbon -e "SELECT username, status, canLogin FROM gibbonPerson;"

The blocked setup wizard and the single account

Step 10: If you are locked out

Gibbon locks an account after three failed sign in attempts and then refuses even the correct password, showing "Too many failed logins: please reset password." This is Gibbon's own brute force protection, and it applies to the administrator too.

If outbound email is configured (Step 12), the Forgot Password? link on the sign in page is the normal way back in. If it is not, clear the counter from the VM:

sudo mysql --protocol=socket -u root -D gibbon -e "UPDATE gibbonPerson SET failCount=0 WHERE username='admin';"

If you have also forgotten the password itself, set a new one from the VM. Gibbon stores sha256(salt + password):

sudo NEWPW='<new-password>' php -r '
$pw = getenv("NEWPW");
$a = "./aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
$salt = ""; for ($i=0;$i<22;$i++) { $salt .= $a[random_int(0, strlen($a)-1)]; }
$h = hash("sha256", $salt.$pw);
echo "UPDATE gibbonPerson SET passwordStrong=\"$h\", passwordStrongSalt=\"$salt\", failCount=0 WHERE username=\"admin\";\n";
' | sudo mysql --protocol=socket -u root -D gibbon

Step 11: How Gibbon learns its address

Gibbon stores an absolute base URL and builds password reset and notification links from it. Baking that into an image would be wrong, so this image writes it on every boot from the VM's own address, along with Apache's ServerName and the HTTPS certificate:

grep '^ServerName' /etc/apache2/conf-available/gibbon-servername.conf
sudo mysql --protocol=socket -u root -D gibbon -N -B -e "SELECT CONCAT('absoluteURL = ', value) FROM gibbonSetting WHERE scope='System' AND name='absoluteURL';"

Both name this VM's public address. Azure's instance metadata service returns an empty value for a Standard SKU public IP, so the image reads the load balancer endpoint first and falls back to the private address only if there is genuinely no public one. That means a VM which is stopped, deallocated and restarted with a new public IP picks the new address up by itself.

The certificate names the same address, and port 80 only redirects:

openssl x509 -in /etc/ssl/gibbon/gibbon.crt -noout -subject -ext subjectAltName
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://127.0.0.1/

Base URL, certificate and the port 80 redirect

Step 12: Configure outbound email

Gibbon sends password resets, notifications and messenger mail. Set your SMTP details under Admin → System Admin → Third Party Settings, in the Email section: host, port, username, password and whether to use TLS. Azure blocks outbound port 25 on most subscriptions, so use a relay on port 587 or an email API rather than direct delivery. Send yourself a test from Other → Messenger once it is set.

Step 13: Use a domain name and your own certificate

Point a DNS A record at the VM's public IP, then pin the name so Gibbon and Apache use it instead of the IP address:

echo '<your-domain>' | sudo tee /etc/gibbon/server-name
sudo /usr/local/sbin/gibbon-baseurl.sh

Then replace the self signed certificate with a real one:

sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --webroot -w /var/www/gibbon -d <your-domain>
sudo ln -sf /etc/letsencrypt/live/<your-domain>/fullchain.pem /etc/ssl/gibbon/gibbon.crt
sudo ln -sf /etc/letsencrypt/live/<your-domain>/privkey.pem  /etc/ssl/gibbon/gibbon.key
sudo systemctl reload apache2

The base URL helper leaves your pinned name and your certificate alone on later boots.

Step 14: Security model

  • Only 22/tcp, 80/tcp and 443/tcp are reachable from outside the VM. MySQL listens on 127.0.0.1 only, and MySQL's X Protocol plugin is switched off so nothing answers on 33060
  • Port 80 issues a permanent redirect to HTTPS and serves no content of its own
  • The setup wizard, the database configuration, the SQL schema and Gibbon's internal source directories are refused by the web server
  • Files uploaded through Gibbon are served as files and never executed; the code tree is read only to the web server and only uploads/ is writable
  • root cannot sign in over SSH and password authentication is disabled
  • MySQL's root account authenticates through the local UNIX socket and has no password to ship
  • Every per VM secret — administrator password, database password, database maintenance password, installation id, TLS key — is generated on this VM's first boot, so two VMs from this image never share one

Step 15: Back up your school data

Gibbon's state is the MySQL database plus anything uploaded into /var/www/gibbon/uploads:

sudo mysqldump --protocol=socket -u root --single-transaction --routines gibbon \
  | gzip > "<backup-dir>/gibbon-db-$(date +%F).sql.gz"
sudo tar czf "<backup-dir>/gibbon-uploads-$(date +%F).tar.gz" -C /var/www/gibbon uploads

Copy both off the VM, and take Azure disk snapshots as well if you want a whole machine restore point.

Step 16: Maintenance and upgrades

The image keeps receiving Ubuntu security updates automatically through unattended-upgrades. For Gibbon itself, upstream publishes a new major release each year and patch releases in between; read the release notes, back up first (Step 15), then follow upstream's upgrade instructions. Gibbon's own in application "cutting edge" auto updater is switched off in this image on purpose, so the appliance never pulls code at runtime.

Usage statistics reporting is also off, so this VM does not phone home.

Support

cloudimg provides 24/7 technical support for this product by email (support@cloudimg.co.uk) and live chat. We help with deployment, retrieving the first boot credentials, signing in, school setup and structure, users and roles, outbound email, custom domain names and HTTPS certificates, backups, upgrades and performance tuning. Questions about Gibbon feature behaviour are answered on a best effort basis and, where appropriate, directed to the Gibbon documentation at gibbonedu.org.