OpenRefine 3.10 Data Cleaning Workbench on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of OpenRefine 3.10 on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. OpenRefine is a free, open source power tool for working with messy data. You import tabular data (CSV, TSV, Excel, JSON, XML) into a project workbench, then explore it with facets and filters, clean and normalise values with GREL, Jython or Clojure expressions, cluster near duplicate entries, and reconcile your data against external sources such as Wikidata, all through a browser based interface. Every change is recorded as a reproducible operation history. OpenRefine is released under the BSD 3 Clause licence.
OpenRefine assumes a single trusted local user and ships with no built in authentication of its own, so this image never exposes it directly. The OpenRefine server is bound to loopback only (127.0.0.1:3333, headless) and fronted by nginx on port 80 with HTTP Basic Auth, so the workbench is never reachable without a credential. At first boot, openrefine-firstboot.service generates a unique per VM Basic Auth password (there is no default login baked into the image), reloads nginx, proves an authenticated round trip, and writes the password to /root/openrefine-credentials.txt (mode 0600, root only).
What is included:
-
OpenRefine 3.10.1 (official Linux distribution), pinned and sha256 verified, installed under
/opt/openrefine -
OpenJDK 17 headless runtime (OpenRefine requires Java 11 to 21), with the JVM heap pinned to a conservative 2 GB maximum so OpenRefine fits alongside the OS and nginx on a
Standard_B2s -
openrefine.servicesystemd unit running the workbench as the unprivilegedopenrefineuser, bound to loopback with a hardened service sandbox -
openrefine-firstboot.servicesystemd oneshot that generates the per VM HTTP Basic Auth password, reloads nginx, proves an authenticated round trip and writes/root/openrefine-credentials.txt -
nginx on port 80 reverse proxying to the loopback bound OpenRefine listener, with HTTP Basic Auth and an unauthenticated
/healthzfor load balancer probes -
The OpenRefine project workbench, reachable at
http://<vm-ip>/after signing in -
Ubuntu 24.04 LTS base with the latest security patches
-
Azure Linux Agent for seamless cloud integration and SSH key injection
-
24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
-
An active Azure subscription, SSH public key, VNet plus subnet in the target region
-
A subscription to the OpenRefine 3.10 on Ubuntu 24.04 listing on Azure Marketplace
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small to medium datasets. For large datasets and heavier transforms, use Standard_D2s_v5 or larger and raise the JVM heap in /opt/openrefine/openrefine-3.10.1/refine.ini (REFINE_MEMORY).
Step 1: Deploy from the Azure Portal
Search OpenRefine in Marketplace, select the cloudimg publisher entry, then click Create.
NSG rules: allow TCP 22 from your management IP and TCP 80 from your client IPs. The OpenRefine server is bound to loopback, so only nginx on port 80 is exposed. The workbench is protected by HTTP Basic Auth, but for any deployment beyond a private network put a TLS terminating reverse proxy in front of port 80 so credentials and data are encrypted in transit.
Step 2: Deploy from the Azure CLI
RG="openrefine-prod"; LOCATION="eastus"; VM_NAME="openrefine-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/openrefine/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name or-vnet --address-prefix 10.90.0.0/16 --subnet-name or-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name or-nsg
az network nsg rule create -g "$RG" --nsg-name or-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name or-nsg --name allow-http --priority 110 \
--source-address-prefixes "<your-client-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name or-vnet --subnet or-subnet --nsg or-nsg --public-ip-sku Standard
Step 3: Connect via SSH
ssh azureuser@<vm-ip>
openrefine.service and nginx.service start automatically, and openrefine-firstboot.service generates the per VM Basic Auth password on the first boot.
Step 4: Verify the OpenRefine Service
sudo systemctl is-active openrefine.service nginx.service
sudo test -f /var/lib/cloudimg/openrefine-firstboot.done && echo FIRSTBOOT_DONE
Both services should report active, and the first boot sentinel should be present.

Step 5: Inspect the Listeners and Runtime
The OpenRefine server is bound to 127.0.0.1:3333, and nginx serves it on port 80. Nothing but nginx listens on a public interface. The JVM heap is pinned in refine.ini.
sudo ss -tln | grep -E ':80 |:3333'
grep -E 'REFINE_MEMORY|REFINE_MIN_MEMORY' /opt/openrefine/openrefine-3.10.1/refine.ini
You will see nginx on port 80, OpenRefine on loopback 3333, and the pinned 2 GB maximum heap.

Step 6: Retrieve the Access Password
The per VM HTTP Basic Auth password is generated at first boot and stored in a root only file:
sudo cat /root/openrefine-credentials.txt
You will see the sign in user, the per VM password, and the endpoint URLs:
OPENREFINE_HTTP_USER=admin
OPENREFINE_BASIC_AUTH_PASSWORD=<OPENREFINE_BASIC_AUTH_PASSWORD>
OPENREFINE_URL=http://<vm-ip>/
OPENREFINE_HEALTHZ=http://<vm-ip>/healthz
OPENREFINE_LOCAL_HTTP=http://127.0.0.1:3333/

Step 7: Verify Access Control over HTTP
OpenRefine is reached only through the authenticated nginx proxy. Confirm that an unauthenticated request is rejected, that the per VM password works, and that the command API responds:
PW=$(sudo grep '^OPENREFINE_BASIC_AUTH_PASSWORD=' /root/openrefine-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'no creds: %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'workbench index: %{http_code}\n' -u "admin:$PW" http://127.0.0.1/
curl -s -u "admin:$PW" http://127.0.0.1/command/core/get-version
The unauthenticated request returns 401, the authenticated workbench index returns 200, and the command API returns the OpenRefine version JSON. The unauthenticated /healthz endpoint stays open for load balancer probes.

Step 8: Open the Workbench in a Browser
Open http://<vm-ip>/ from your workstation (assuming the NSG allows TCP 80). Your browser prompts for HTTP Basic Auth: sign in with user admin and the per VM password from /root/openrefine-credentials.txt. OpenRefine opens on the Create Project screen, where you choose a data source:

Step 9: Create a Project by Importing Data
On This Computer, choose a data file (CSV, TSV, Excel, JSON or XML) and click Next. OpenRefine shows a parsing preview where you confirm the column separator, header rows and value types, then click Create Project. Your data loads into the project workbench as a grid of rows and columns.
Step 10: Explore the Data Grid
The workbench shows your data as an editable grid. Each column header has a dropdown menu of operations, and the Facet / Filter panel on the left is where you slice and clean the data. This sample import of customer contacts shows the kind of inconsistency OpenRefine is built to fix, mixed spellings of the same country and inconsistent casing and whitespace:

Step 11: Facet and Filter
Open a column's dropdown menu and choose Facet, Text facet to see every distinct value in that column with a count. Here the country column reveals eight variants of what should be a handful of countries (United Kingdom, uk, U.K., France, FR, Germany, germany, Deutschland). Click Cluster to let OpenRefine group near duplicate values automatically, or click a value to filter the grid to just those rows:

Step 12: Clean and Transform with GREL
Open a column menu and choose Edit cells, Transform to run a GREL expression across every cell, with a live before and after preview. For example value.trim().toTitlecase() normalises casing and strips stray whitespace. Transforms are recorded in the operation history, so you can undo them or replay the whole cleanup on a fresh dataset:

Step 13: Export the Cleaned Data
When the data is clean, use the Export menu at the top right to write it back out as CSV, TSV, Excel, JSON, HTML or a custom template, or to export the operation history as JSON so the same cleanup can be applied to future imports. Projects are stored in the workspace at /var/lib/openrefine.
Step 14: Server Components
| Component | Path |
|---|---|
| OpenRefine install | /opt/openrefine/openrefine-3.10.1 |
| Launcher | /opt/openrefine/openrefine-3.10.1/refine |
| Heap config | /opt/openrefine/openrefine-3.10.1/refine.ini |
| Workspace / projects | /var/lib/openrefine |
| Systemd unit | /etc/systemd/system/openrefine.service |
| Firstboot script | /usr/local/sbin/openrefine-firstboot.sh |
| Firstboot service | /etc/systemd/system/openrefine-firstboot.service |
| Credentials file | /root/openrefine-credentials.txt (mode 0600) |
| Firstboot sentinel | /var/lib/cloudimg/openrefine-firstboot.done |
| nginx site | /etc/nginx/sites-available/cloudimg-openrefine |
| Basic Auth file | /etc/nginx/.openrefine_htpasswd |
Step 15: Managing the Service
sudo systemctl status openrefine.service --no-pager | head -6
sudo journalctl -u openrefine.service --no-pager | tail -5
To restart the workbench after changing the heap or options, run sudo systemctl restart openrefine.service.
Step 16: Security Recommendations
-
Rotate the Basic Auth password by regenerating
/etc/nginx/.openrefine_htpasswdwithsudo htpasswd -B /etc/nginx/.openrefine_htpasswd adminand reloading nginx, and store the password in your secrets manager -
Keep the OpenRefine listener on loopback as shipped; expose only nginx on port 80, and put TLS in front of it (Azure Application Gateway, or nginx with a real certificate)
-
Restrict the NSG so port 80 only reaches trusted client networks, because a data cleaning workbench often holds sensitive data
-
Make the workbench public only if intended by removing the
auth_basiclines from/etc/nginx/sites-available/cloudimg-openrefineand reloading nginx -
Back up the workspace at
/var/lib/openrefine, or take Azure disk snapshots, so your projects and operation histories are preserved -
Raise the JVM heap in
refine.ini(REFINE_MEMORY) when working with large datasets, and use a larger VM size accordingly -
Patch the OS monthly with
sudo apt-get update && sudo apt-get upgrade && sudo reboot
Step 17: Support and Licensing
OpenRefine is licensed under the BSD 3 Clause licence. There are no per node, per CPU, or per GB fees. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the OpenRefine project; OpenRefine is a trademark of its respective owner and is used here only to describe the software included in the image.
cloudimg provides commercial support for this image separately from the upstream project.
-
Email: support@cloudimg.co.uk
-
Website: www.cloudimg.co.uk
-
Support hours: 24/7 with guaranteed 24 hour response SLA
Deploy on Azure
Launch OpenRefine 3.10 Data Cleaning Workbench on Ubuntu 24.04 with 24/7 support from cloudimg.
View on Marketplace
Need Help?
Our support team is available 24/7.
support@cloudimg.co.uk