WeBWorK 2 on Ubuntu 24.04 on Azure User Guide
Overview
WeBWorK is the free, open source online homework system used by universities and colleges worldwide to deliver individualised problem sets in mathematics and the sciences. Instructors author problems in the PG language or draw on the Open Problem Library of tens of thousands of peer-reviewed problems; students submit answers and get instant, automated feedback. The cloudimg image delivers WeBWorK 2.21 fully installed and configured on Ubuntu 24.04 — the Perl/Mojolicious application served by Hypnotoad behind nginx, backed by MariaDB, with a Minion job queue for hardcopy PDF generation and email. Equations render client-side with MathJax, and a full TeX Live stack is installed for PDF hardcopy and PGtikz/PGlateximage problems. Backed by 24/7 cloudimg support.
What is included:
- WeBWorK 2.21 and PG 2.21 (dual-licensed Artistic-2.0 OR GPL-2.0), served at
/webwork2 - nginx reverse proxy on port 80 → Mojolicious/Hypnotoad on
127.0.0.1:8080, MariaDB, and thewebwork2-job-queueMinion worker — all systemd units, enabled and active - The Open Problem Library (~49,000 problems) cloned and indexed into the database so the Library Browser works out of the box
- A ready-to-explore demo course with an assigned, MathJax-rendered sample problem set
- A full TeX Live stack (
texlive,texlive-latex-extra,texlive-science,texlive-xetex,cm-super,dvipng,dvisvgm) for hardcopy PDF and image-mode problems - A dedicated Azure data disk at
/var/lib/mysql(database) and a second at/opt/webwork(application, PG, OPL and courses) — each independently resizable, separate from the OS disk and re-provisioned with every VM - Per-VM administrator password, MariaDB password and Mojolicious session secret, all generated at first boot and written to a root-only file — no shipped default login
- 24/7 cloudimg support

Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is a good starting point; scale up — and raise the Hypnotoad workers count in /opt/webwork/webwork2/conf/webwork2.mojolicious.yml — for larger cohorts. NSG inbound: allow 22/tcp from your management network and 80/tcp (plus 443/tcp once you enable HTTPS) from your users.
Step 1 — Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for WeBWorK by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Review the two dedicated data disks on the Disks tab, then Review + create → Create.
Step 2 — Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name webwork \
--image <marketplace-image-urn> \
--size Standard_B2ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
Then open HTTP to your users:
az vm open-port --resource-group <your-rg> --name webwork --port 80
Step 3 — Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 — Confirm the services are running
WeBWorK runs as four systemd units: nginx, mariadb, webwork2 (the Hypnotoad app) and webwork2-job-queue (the Minion worker). The login page is served at /webwork2/.
systemctl is-active nginx mariadb webwork2 webwork2-job-queue
curl -s -o /dev/null -w 'login page -> HTTP %{http_code}\n' http://127.0.0.1/webwork2/
Expected output:
active
active
active
active
login page -> HTTP 200

Step 5 — Retrieve your administrator credentials
On first boot the image generates a unique WeBWorK admin password, MariaDB password and Mojolicious session secret — there is no shipped default login. They are written to a root-only file:
sudo cat /root/webwork-credentials.txt
You will see the admin username (admin), the generated admin password, the admin and demo course URLs, and the database credentials, all unique to this VM.

Step 6 — Sign in to the admin course
Browse to http://<vm-public-ip>/webwork2/admin and sign in with the username admin and the password from the credentials file. The admin course is the site console: from here you create, rename, archive and manage courses, manage accounts, and send email.
# Prove the generated admin credentials authenticate (from the VM):
CJ=$(mktemp)
curl -s -c "$CJ" -o /dev/null http://127.0.0.1/webwork2/admin
curl -s -b "$CJ" -c "$CJ" -o /dev/null \
--data-urlencode "user=admin" \
--data-urlencode "passwd=<WEBWORK_ADMIN_PASSWORD>" \
--data-urlencode "submit=Login" \
http://127.0.0.1/webwork2/admin
curl -s -b "$CJ" http://127.0.0.1/webwork2/admin | grep -qi 'Log ?Out' && echo "admin login OK" || echo "login check"
rm -f "$CJ"

Step 7 — Explore the demo course and a rendered problem
The image ships a demo course with an assigned problem set (DemoProblems) so a fresh VM shows a real, MathJax-rendered WeBWorK problem straight away. From the admin console, or by browsing to http://<vm-public-ip>/webwork2/demo, open DemoProblems → Problem 1. WeBWorK renders the problem with MathJax and offers the instructor tools to preview, check and submit answers, and to act as any student.
To build your own course, use Add Course in the admin console, then import problem sets from the Library Browser (the Open Problem Library is already indexed) or upload your own PG files.

Step 8 — Confirm the versions, the library and the data tiers
echo "webwork2 $(sed -n 's/.*=//p' /opt/webwork/webwork2/VERSION | tr -d ' \";' | head -1)"
echo "pg $(sed -n 's/.*=//p' /opt/webwork/pg/VERSION | tr -d ' \";' | head -1)"
mariadb webwork -e "SELECT COUNT(*) AS opl_problems FROM OPL_pgfile;" 2>/dev/null
df -h /var/lib/mysql /opt/webwork | grep -v Filesystem
The database lives on the dedicated /var/lib/mysql data disk and the application, PG, OPL and courses on the /opt/webwork data disk — both captured into the image and re-provisioned with every VM.

Administration from the CLI
WeBWorK ships command-line tools under /opt/webwork/webwork2/bin (run them as the web user). To rotate a user's password, for example:
sudo -u www-data WEBWORK_ROOT=/opt/webwork/webwork2 PG_ROOT=/opt/webwork/pg \
/opt/webwork/webwork2/bin/newpassword <course> <user> <new-password>
Create a course with bin/addcourse, and refresh the Open Problem Library index with SKIP_UPLOAD_OPL_STATISTICS=1 bin/OPL-update. The demo course's sample problem is at /opt/webwork/courses/demo/templates/cloudimgDemo/demoProblem1.pg.

Enabling HTTPS
For production, put a certificate in front of nginx. Install certbot and request a certificate for your DNS name (point an A record at the VM first, and open 443/tcp in the NSG):
sudo snap install --classic certbot
sudo certbot --nginx -d your-domain.example.edu
Then set $server_root_url to your https:// URL and $CookieSecure = 1; in /opt/webwork/webwork2/conf/localOverrides.conf, and restart with sudo systemctl restart webwork2.
Two-factor authentication (TOTP) is available but shipped opt-in. To require it, set $twoFA{enabled} = 1; (or a list of course IDs) in localOverrides.conf and restart webwork2.
Backup and maintenance
- Database:
mysqldump webwork > webwork-backup.sql(or snapshot the/var/lib/mysqldata disk). - Courses and problems: back up
/opt/webwork/courses(on the/opt/webworkdata disk). - OS updates: unattended-upgrades is enabled; apply the rest with
sudo apt update && sudo apt upgrade. - Restart the app:
sudo systemctl restart webwork2 webwork2-job-queue.
Support
This image is maintained by cloudimg with 24/7 support. For assistance, contact the cloudimg support channel associated with your Marketplace subscription.