Dolos on Ubuntu 24.04 LTS on Azure
Overview
Dolos is an open source source-code plagiarism detection tool from Team Dodona at Ghent University. It parses submissions with tree-sitter, fingerprints them with a winnowing k-gram algorithm, and surfaces the most similar file pairs in an interactive web dashboard: a similarity graph, a ranked list of file pairs, and a side-by-side comparison that highlights the matching fragments. Educators use it to detect copied programming assignments; teams use it to find duplicated code. It supports most common programming languages out of the box.
The cloudimg image serves Dolos 2.9.3, a Node/TypeScript application, on a hardened, fully patched Ubuntu 24.04 LTS base. Because Dolos has no authentication of its own, this image places it behind nginx: the Dolos server is bound to the loopback interface only, and nginx on port 80 is the single public entry point, protected by HTTP basic authentication.
The image is deliberately shipped without a credential. On the first boot of every VM a one-shot service generates a unique basic-auth password, writes it to a root-only file, and only then publishes the dashboard on port 80. Until that finishes, nginx serves only a loopback bootstrap socket and nothing is published on port 80 — so no instance is ever reachable from the network without a credential, and no password is ever shared between customers. A small sample analysis ships pre-loaded so the dashboard works out of the box. Backed by 24/7 cloudimg support.
What is included:
- Dolos 2.9.3 (the
@dodona/dolosCLI and its bundled web dashboard) on Node.js 22 LTS, managed by systemd asdolos.service - The interactive dashboard on
:80, behind nginx HTTP basic authentication - A per-VM basic-auth password generated on first boot and recorded in a root-only file
- A pre-loaded sample analysis so the dashboard is populated immediately
- The Dolos server bound to
127.0.0.1:3000only — never exposed directly to the network dolos.serviceandnginx.serviceas enabled systemd units- Automatic security updates, including for Node.js from the NodeSource repository
- 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 and is comfortable for typical assignment-sized datasets; size up for very large collections. NSG inbound: allow 22/tcp from your management network, and 80/tcp (plus 443/tcp once you terminate TLS on the VM) so your browser can reach the dashboard.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Dolos 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). Then Review + create and Create.
Step 2 - Deploy from the Azure CLI
Alternatively, deploy the same image from the Azure CLI. Replace the placeholders with your own resource group, region, VNet and SSH key.
az vm create \
--resource-group my-resource-group \
--name dolos \
--image <the-dolos-marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
Open port 80 to your browser once the VM exists:
az vm open-port --resource-group my-resource-group --name dolos --port 80
Step 3 - Retrieve your per-VM credentials
The dashboard password is generated on this VM's first boot and written to a root-only file. SSH in as azureuser and read it:
sudo cat /root/dolos-credentials.txt
You will see the dashboard URL, the username (admin) and the unique password for this VM. Keep it safe — it is the only account that can reach the dashboard.
Step 4 - Confirm the services are healthy
Check that the Dolos server and nginx are both running, and that Dolos reports the expected version:
systemctl is-active dolos.service nginx.service
systemctl --no-pager --lines=0 status dolos.service | head -n 6
dolos --version
Both services report active, and Dolos reports v2.9.3 on Node 22.

Step 5 - Sign in to the dashboard
Open http://<your-vm-public-ip>/ in a browser. It prompts for HTTP basic authentication: enter admin and the password from Step 3. The dashboard opens on the analysis overview, showing the highest and average similarity across the pre-loaded sample dataset, the number of submissions and clusters, and a similarity distribution.

Step 6 - Explore the similarity graph
Select View by graph in the left navigation. Dolos draws a force-directed graph where each node is a submission and an edge connects files whose similarity is above the threshold. Drag the Threshold slider to reveal more or fewer relationships; lowering it here reveals the cluster of three related bubble-sort submissions.

Step 7 - Review the ranked file pairs
Select View by pair. Dolos ranks every pair of files by similarity, with the longest matching fragment and the total overlap. In the sample dataset the two near-identical bubble-sort files score 100%, while a genuinely different quicksort scores in the single digits.

Click any row to open the side-by-side comparison. Dolos highlights the matching code fragments between the two files, so you can see exactly which sections overlap — even when variables have been renamed.

Step 8 - Understand the security model
Dolos itself has no login, so this image makes nginx basic authentication the protection layer. The Dolos server listens on 127.0.0.1:3000 only; nginx on :80 is the sole public door and requires the per-VM credential. The credential is generated on first boot — nothing is baked into the image.
ss -tlnH | awk '{print $1, $4}' | grep -E ':(80|3000)$' | sort -u
You will see nginx listening on 0.0.0.0:80 and the Dolos server on 127.0.0.1:3000 (loopback only).

Confirm the authentication is enforced — an unauthenticated request and a wrong password are both rejected with 401, while the per-VM credential returns 200:
U=$(sudo grep '^dolos.admin.user=' /root/dolos-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^dolos.admin.pass=' /root/dolos-credentials.txt | cut -d= -f2-)
echo "no credentials : $(curl -s -o /dev/null -w '%{http_code}' http://localhost/)"
echo "wrong password : $(curl -s -o /dev/null -w '%{http_code}' -u "$U:wrong" http://localhost/)"
echo "per-VM password: $(curl -s -o /dev/null -w '%{http_code}' -u "$U:$P" http://localhost/)"
curl -s http://localhost/healthz

Step 9 - Analyse your own source files
The dashboard renders a report stored at /opt/dolos/report, generated from the sample dataset that ships in the image:
ls -1 /opt/dolos/report
To analyse your own submissions, copy your source files onto the VM, regenerate the report with dolos run, and restart the service. Dolos compares files in one language at a time — pass the language with -l. For example, for a directory of Python submissions:
sudo -u dolos dolos run -f csv -o /opt/dolos/report -l python /path/to/your/files/*
sudo systemctl restart dolos
Refresh the dashboard and it now shows your analysis. You can also run a quick analysis straight to the terminal, which prints a ranked similarity table without touching the dashboard:
dolos run -l javascript /path/to/your/files/*

Step 10 - Put the dashboard behind HTTPS
Basic authentication protects who can reach the dashboard, but you should terminate TLS before exposing it to the internet so the credential is never sent in clear text. Point a DNS record at the VM, open 443/tcp on the NSG, and issue a certificate. The certbot nginx plugin will provision one and rewrite the vhost for you:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d dolos.example.com
Notes
- The per-VM credential in
/root/dolos-credentials.txtis unique to this VM and is never shared between customers. Change it at any time withsudo htpasswd -B /etc/nginx/.dolos_htpasswd adminand update your records. - Dolos and the sample dataset are redistributed unmodified under the MIT License; the licence text ships in the image at
/usr/share/doc/cloudimg/DOLOS-LICENCE-ATTRIBUTION.txt. - Security updates, including Node.js from the NodeSource repository, are applied automatically by
unattended-upgrades. - Questions or issues: support@cloudimg.co.uk.