TCExam on Ubuntu 24.04 on Azure User Guide
Overview
TCExam is an open source platform for computer based assessment (CBA): you author a question bank organised into modules, subjects and questions, assemble tests, exams and quizzes, deliver them to candidates through a public test taking area, and review the results, reporting and statistics with PDF export. The cloudimg image ships TCExam 17.2.4 served by nginx and PHP 8.3 FPM on a hardened, fully patched Ubuntu 24.04 LTS base, together with a bundled local MariaDB server so the appliance is complete and useful on its own. TCExam is reachable over both HTTP on port 80 and HTTPS on port 443 (a self signed certificate generated per VM). The bundled MariaDB listens only on the loopback interface (127.0.0.1:3306). A unique administrator password is generated on the first boot of every VM. Backed by 24/7 cloudimg support.
What is included:
- TCExam 17.2.4 served by nginx and PHP 8.3 FPM, managed by systemd
- A bundled MariaDB server holding the TCExam database, already installed and ready
- A ready to use TCExam with a small example question bank and a Sample Quiz test, waiting for your own content
- A per VM administrator password generated on first boot and recorded in a root only file
- No shipped default login: the default
admin/1234account is rotated to a unique per VM secret, and no known or blank credential authenticates - No installer or setup wizard reachable on the network: the installer directory is removed from the image
- nginx hardening that denies direct web access to the configuration, shared library, backup, cache and vendor directories
- A per VM self signed TLS certificate on port 443, and a per VM random security salt for CSRF and result access tokens
- MariaDB bound to
127.0.0.1only, never exposed to the network nginx.service,php8.3-fpm.serviceandmariadb.serviceas enabled systemd units- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 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 a sensible starting point; size up for larger candidate pools or busier exam windows. NSG inbound: allow 22/tcp from your management network and 80/tcp and 443/tcp for the exam site. The image serves both HTTP and HTTPS (with a per VM self signed certificate); for production, put your own domain and a CA signed certificate in front. The bundled MariaDB is never exposed: it listens on 127.0.0.1 only, so port 3306 stays off the network.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for TCExam 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), HTTP (80) and HTTPS (443). Then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name tcexam \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Then open the exam site ports:
az vm open-port --resource-group <your-rg> --name tcexam --port 80 --priority 900
az vm open-port --resource-group <your-rg> --name tcexam --port 443 --priority 901
Step 3 - Confirm the services are running
SSH in as azureuser and confirm nginx, PHP FPM and MariaDB are all active. Note that MariaDB listens only on 127.0.0.1:3306 while nginx serves TCExam on ports 80 and 443.
systemctl is-active nginx php8.3-fpm mariadb
ss -tlnp | grep -E ':80 |:443 |:3306 ' | sed 's/ */ /g'

Step 4 - Retrieve the per VM administrator password
Every VM generates its own TCExam administrator password on first boot and writes it, along with the login user and the admin area URL, to a root only credentials file. Read it with sudo:
sudo cat /root/tcexam-credentials.txt

You sign in to the admin area as user admin with the TCEXAM_ADMIN_PASSWORD from this file. On the box itself you can also run sudo mariadb to reach the database directly over the local socket without a password.
Step 5 - Sign in to the admin area
Browse to http://<vm-public-ip>/admin/code/ (or https://<vm-public-ip>/admin/code/, accepting the self signed certificate). You land on the TCExam administration sign in page. Enter username admin and the password from Step 4.

Once signed in you land on the TCExam admin dashboard, where the top navigation gives you Users, Questions, Tests, Results and the other management areas.

Step 6 - Build your question bank and tests
TCExam organises content as Modules that contain Subjects, and each subject holds Questions with their answers (single choice, multiple choice, ordering and free text). The image ships a small example: an Example Module with a General Knowledge subject of three questions, and a Sample Quiz test drawn from it. Open Tests to edit or create tests, set the duration, scoring and how questions are drawn from subjects, then schedule and assign them to candidates.

Step 7 - Deliver exams to candidates
Candidates take their assigned tests through the public area at http://<vm-public-ip>/public/code/. They sign in, work through the questions in a clean, mobile friendly interface, and submit; you then review each attempt, the scores and the statistics from the admin Results area, exporting reports to PDF where needed.

Step 8 - No known or default credentials
TCExam ships upstream with a default admin / 1234 account. The cloudimg image rotates that account to a unique per VM secret on first boot, removes the installer directory entirely, and generates a per VM random security salt. You can prove no known credential authenticates with the built in round-trip check, which confirms the per VM administrator signs in through TCExam's own login form while the default 1234 and common weak guesses are all rejected:
sudo mariadb --protocol=socket -uroot -N -e "SELECT CONCAT(user_name,' (level ',user_level,' administrator)') FROM tcexam.tce_users WHERE user_name='admin'"
sudo bash /usr/local/sbin/tcexam-cred-roundtrip.sh

Step 9 - Verify the stack and where your data lives
Confirm the TCExam version, the health endpoint, and that MariaDB is bound to loopback only. All of your TCExam data (users, question banks, tests, results) lives in the bundled MariaDB, whose data directory is on the VM disk and rides with the image:
cat /var/www/tcexam/VERSION
curl -sI http://127.0.0.1/healthz | head -1
ss -tlnH 'sport = :3306' | sed 's/ */ /g'

Adding your own domain and TLS
The image serves HTTP on port 80 and HTTPS on port 443 with a per VM self signed certificate. For production you should set your own address and a CA signed certificate. TCExam builds its links from the base URL configured on first boot; you can front the appliance with your domain and terminate TLS at Azure Application Gateway, an nginx or Caddy reverse proxy, or a managed load balancer with a certificate for your domain (the appliance honours the X-Forwarded-Proto header). Re-point the base URL by editing K_PATH_HOST in /var/www/tcexam/shared/config/tce_paths.php if you move to a fixed hostname.
Security notes
- The image serves HTTP on port 80 and HTTPS on port 443 (self signed). For anything beyond a trusted network, put it behind your own TLS terminating reverse proxy or Azure Application Gateway with a certificate for your domain.
- The bundled MariaDB listens on
127.0.0.1only and is never reachable from the network. Administer it through TCExam or over SSH. - The administrator password is unique per VM and no known or blank credential authenticates. The default
admin/1234is rotated away on first boot. Keep/root/tcexam-credentials.txtprotected and change the password from within TCExam if you share access. - The installer and setup wizard directory is removed from the image, so no unauthenticated install flow is reachable.
- nginx denies direct web access to the configuration, shared code, backup, cache, vendor and installer directories, and to dotfiles.
- Restrict inbound
80/tcpand443/tcpin your NSG to the networks that need the exam site.
Trademark
TCExam and its logo are trademarks of Tecnick.com LTD. This image is an independent packaging of the free AGPL licensed TCExam by cloudimg and is not affiliated with, sponsored by, or endorsed by Tecnick.com LTD.
Support
This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating TCExam on Azure, contact us at cloudimg.co.uk.