Deployment guide

TCExam

Overview

TCExam is an open-source platform for computer-based assessment (CBA). You author a question bank organized into modules, subjects and questions, assemble tests, exams and quizzes, and deliver them to candidates through a public test-taking area. You then review the results, reporting and statistics, with PDF export.

This SecureAnyCloud image ships TCExam 17.2.4 served by nginx and PHP 8.3 FPM on a hardened Ubuntu 24.04 LTS base, patched at build time. It includes a bundled local MariaDB server, so the appliance is complete and useful on its own.

What you get:

  • 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
  • TCExam, ready to use, with a small example question bank and a Sample Quiz test, waiting for your own content
  • TCExam reachable over HTTP on port 80 and HTTPS on port 443
  • A per-VM administrator password generated on the first boot and recorded in a root-only file
  • No shipped default login: the default admin / 1234 account is rotated to a unique per-VM secret, and no known or blank credential authenticates
  • No installer or setup wizard reachable on the network, because 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.1 only, never exposed to the network
  • nginx.service, php8.3-fpm.service and mariadb.service as enabled systemd units
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size. Choose a larger size for bigger candidate pools or busier exam windows.

In the NSG, allow inbound 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 SecureAnyCloud, and select Create.

On the Basics tab, 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 select Review + create and Create.

Step 2 - Deploy from the Azure CLI

Accept the Marketplace terms, then create the VM:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:tcexam-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name tcexam \
  --image sac1647283583153:tcexam-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

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 that nginx, PHP FPM and MariaDB are all active. 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 the first boot. It writes the password, the login user and the admin area URL to a root-only credentials file. Read the file with sudo:

sudo cat /root/tcexam-credentials.txt

Sign in to the admin area as user admin with the TCEXAM_ADMIN_PASSWORD from this file. On the VM 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/. You can also use https://<vm-public-ip>/admin/code/ and accept the self-signed certificate. The TCExam administration sign-in page opens. Enter username admin and the password from Step 4.

After you sign in, the TCExam admin dashboard opens. The top navigation gives you Users, Questions, Tests, Results and the other management areas.

Step 6 - Build your question bank and tests

TCExam organizes content as Modules that contain Subjects. 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, the scoring and how questions are drawn from subjects, then schedule the tests 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 in the admin Results area. Export reports to PDF where needed.

Step 8 - No known or default credentials

TCExam ships upstream with a default admin / 1234 account. On the first boot, this image rotates that account to a unique per-VM secret, removes the installer directory entirely and generates a per-VM random security salt.

Prove that no known credential authenticates with the built-in round-trip check. It confirms that 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. Its 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, set your own address and a CA-signed certificate.

TCExam builds its links from the base URL configured on the first boot. 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 honors the X-Forwarded-Proto header.

If you move to a fixed hostname, re-point the base URL by editing K_PATH_HOST in /var/www/tcexam/shared/config/tce_paths.php.

Security notes

  • Encrypt web traffic. 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.
  • Keep MariaDB private. The bundled MariaDB listens on 127.0.0.1 only and is never reachable from the network. Administer it through TCExam or over SSH.
  • Protect the administrator password. The password is unique per VM, and no known or blank credential authenticates. The default admin / 1234 is rotated away on the first boot. Keep /root/tcexam-credentials.txt protected, and change the password from within TCExam if you share access.
  • No installer exposed. The installer and setup wizard directory is removed from the image, so no unauthenticated install flow is reachable.
  • Locked-down web paths. nginx denies direct web access to the configuration, shared code, backup, cache, vendor and installer directories, and to dotfiles.
  • Restrict inbound ports. Limit inbound 80/tcp and 443/tcp in your NSG to the networks that need the exam site.

Trademark

TCExam and its logo are trademarks of Tecnick.com LTD. SecureAnyCloud packages the free, AGPL-licensed TCExam independently. This image is not affiliated with, sponsored by, or endorsed by Tecnick.com LTD.

Support

SecureAnyCloud maintains this image and provides 24/7 support. For help deploying or operating TCExam on Azure, contact us at secureanycloud.com.

Deploy on Azure

Launch TCExam on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure