Qcadoo MES on Ubuntu 24.04 on Azure User Guide
Overview
Qcadoo MES is an open source manufacturing execution system aimed at small and medium manufacturers. It plans and tracks production on the shop floor: you create production orders, schedule and sequence work, define technologies and bills of materials, manage materials and stock, log workers' time and output, and run basic quality control, all from a browser. The cloudimg image ships the AGPL-3.0 Qcadoo MES 3.1.0 release deployed on Apache Tomcat with the Eclipse Temurin 8 (OpenJDK 8) JRE behind nginx, which terminates TLS. PostgreSQL is the application database. Tomcat listens on 127.0.0.1:8080 and PostgreSQL on the loopback interface only; both are reached through nginx on port 443 (HTTPS).
The image is secure by default. Qcadoo ships two well known default logins — superadmin / superadmin and admin / admin; the cloudimg image poisons both passwords so they are dead in the shipped image, and on the first boot of every VM a one shot service generates unique passwords for both accounts and a unique database password, regenerates the application crypto key and a per-VM TLS certificate, writes the logins to /root/qcadoo-mes-credentials.txt (mode 0600), and only then starts the public web interface. Backed by 24/7 cloudimg support.
What is included:
- Qcadoo MES 3.1.0 deployed on Apache Tomcat with the Eclipse Temurin 8 (OpenJDK 8) JRE
- nginx terminating TLS on
:443in front of Tomcat (bound to loopback:8080);:80redirects to HTTPS - PostgreSQL as the application database, bound to loopback only
- Per-VM passwords for both
superadminandadmin, a per-VM database password and a per-VM application crypto key generated at first boot, in a root-only file; both shipped default logins are rotated so they never work - A per-VM self-signed TLS certificate generated on first boot
qcadoo-mes.service,postgresql.serviceandnginx.serviceas systemd units, enabled and active- 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 — Qcadoo MES runs the Tomcat JVM alongside PostgreSQL and benefits from memory headroom; scale up for more users, larger orders or heavier reporting. NSG inbound: allow 22/tcp from your management network and 443/tcp from the networks your users will reach Qcadoo on.
Step 1 — Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Qcadoo MES 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 HTTPS (443). Then Review + create → Create.
First boot initialisation takes approximately one to three minutes after the VM starts — Qcadoo rotates its secrets, generates the per-VM TLS certificate, starts Tomcat and brings the web interface online on first boot.
Step 2 — Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name qcadoo-mes \
--image <marketplace-image-urn> \
--size Standard_B2ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name qcadoo-mes --port 443 --priority 1010
Step 3 — Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 — Confirm the services are running
systemctl is-active postgresql qcadoo-mes nginx qcadoo-mes-firstboot
curl -fsSk -o /dev/null -w 'qcadoo login: %{http_code}\n' https://127.0.0.1/login.html
All four units report active and the login endpoint returns 200, confirming the full stack — nginx, Tomcat and PostgreSQL — is serving. Qcadoo MES is a JVM application: on the very first boot allow a short warm-up before the login page responds.

Step 5 — Confirm the network bindings
The application and the database bind the loopback interface only; nginx is the single public port. Confirm it:
ss -tln | grep -E ':(443|8080|5432)'
Port 443 is nginx (public, TLS); Tomcat listens on 127.0.0.1:8080 and PostgreSQL on 127.0.0.1:5432, so neither the application server nor the database is directly reachable from the network.

Step 6 — Retrieve your administrator login
The passwords for both accounts and the database password are generated uniquely on the first boot of your VM and written to a root-only file:
sudo cat /root/qcadoo-mes-credentials.txt
The qcadoo.superadmin.login (which is superadmin) and qcadoo.superadmin.pass values are your first sign-in; the file also records the admin login and the per-VM PostgreSQL password. First boot rotates both shipped default logins so they no longer work.

You can verify the security posture without exposing the password — the shipped defaults are rejected while the per-VM password authenticates through the real Qcadoo login:
B=http://127.0.0.1:8080
U=$(sudo grep '^qcadoo.superadmin.login=' /root/qcadoo-mes-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^qcadoo.superadmin.pass=' /root/qcadoo-mes-credentials.txt | cut -d= -f2-)
login() { cj=$(mktemp); pg=$(curl -s -c "$cj" "$B/login.html"); \
tok=$(printf '%s' "$pg" | grep -o 'name="_csrf" content="[^"]*"' | head -1 | sed 's/.*content="//;s/"$//'); \
curl -s -b "$cj" -c "$cj" --data-urlencode "j_username=$1" --data-urlencode "j_password=$2" \
--data-urlencode "_csrf=$tok" "$B/j_spring_security_check"; echo; rm -f "$cj"; }
echo -n 'default superadmin/superadmin -> '; login superadmin superadmin
echo -n 'per-VM superadmin -> '; login "$U" "$P"
The first call returns loginUnsuccessfull (the shipped default is dead) and the second returns loginSuccessfull.

Step 7 — First sign-in
Open a web browser and navigate to https://<vm-public-ip>/. The certificate is self-signed and unique to your VM, so your browser will warn on the first visit — accept the warning to continue (or install a CA-signed certificate, see Enabling a trusted certificate). At the Qcadoo MES sign-in page enter superadmin and the password from /root/qcadoo-mes-credentials.txt.

The Qcadoo MES sign-in page, served over HTTPS with the per-VM administrator password.
After signing in, open the main menu (the arrow next to the qcadoo logo) to reveal the full manufacturing navigation — Products, Technology, Warehouse, Supplies, Planning, Tracking, Sales, Maintenance and more.

The Qcadoo MES main menu — the full breadth of the manufacturing modules.
Step 8 — Explore and create products
The image ships with a small demo dataset so you can explore immediately. Open Products from the main menu to see a finished good (a dining table) and its components already loaded. Select Add new to create your own: give it a number and a name, choose a unit (for example pcs), and Save. Products are the items you manufacture or consume; they are the foundation of technologies (bills of materials) and production orders.

The Qcadoo MES products grid — the catalogue of manufactured and consumed items.
Step 9 — Plan a production order
Open Planning → Production orders. The image ships with a demo production order for the dining table so you can see the planning view in action. Select Add new to plan your own: give the order a number, pick the product to make and the quantity, set the planned dates, and Save. The production order is the central shop-floor document in Qcadoo MES — from it you plan work, issue materials and record output and time.

A Qcadoo MES production order — the product, quantity, deadline and state for a shop-floor job.
Step 10 — Confirm the data tier
Qcadoo MES keeps all of its state in its PostgreSQL application database. Confirm the schema is present:
sudo -u postgres psql -d mes -tAc "SELECT count(*) AS public_tables FROM pg_tables WHERE schemaname='public';"
The database reports its full set of application tables.
Enabling a trusted certificate
The image serves HTTPS with a per-VM self-signed certificate out of the box. For production, replace it with a CA-signed certificate so browsers trust it without a warning. The image ships with nginx, which certbot can configure automatically. The following assumes a DNS record pointing your fully qualified domain name at the VM's public IP:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d qcadoo.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example \
--redirect
After certbot finishes, reload nginx with sudo systemctl reload nginx. Sign in and change the administrator passwords from the Qcadoo user menu.
Backup and maintenance
Qcadoo MES keeps all of its state — products, technologies, production orders, materials, users and configuration — in its PostgreSQL application database. Back it up regularly:
sudo -u postgres pg_dump mes > /tmp/qcadoo-mes-$(date +%F).sql
Ship the dump to Azure Blob Storage or another object store, or snapshot the disk in Azure for point-in-time backups. Keep the OS patched with sudo apt update && sudo apt upgrade. Qcadoo MES is served by Apache Tomcat under /opt/qcadoo-mes; restart the application with sudo systemctl restart qcadoo-mes after configuration changes. Always back up first.
Support
This image is backed by 24/7 cloudimg support. Contact us by email and chat for help with deployment, technologies and bills of materials, production planning, materials and stock, TLS certificates and database administration. Contact support@cloudimg.co.uk.
For general Qcadoo questions consult the project at https://qcadoo.com/. Qcadoo is a trademark of Qcadoo Limited. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.