What's new Download Reportworq
⬇ Guide PDF

Deploy on an Azure Linux VM#

This page takes you from an empty Azure subscription to a working Reportworq server reachable over HTTPS at your own web address. Every step is a command you can copy and paste, and every command is explained, so you do not need prior Linux experience to follow it.

Allow about 45 minutes, most of which is waiting for downloads.

If you have not chosen a deployment shape yet, read Deployment topology first. This page covers the Linux tarball on a virtual machine you control. It is the right choice when you want to decide for yourself when the Reportworq version changes, and when you want to import a Reportworq 5 repository, neither of which the container deployment offers.

What you will build#

A single Linux virtual machine running two pieces of software:

Alongside the machine you will attach a separate data disk, mounted at /var/lib/reportworq, which holds the Reportworq repository. The repository is the only durable state in the whole deployment, so keeping it on its own disk is what makes backup, restore and rebuild straightforward.

Only three ports are open to the internet: 22 for your own administrative access, 80 so the certificate can be issued and so browsers are redirected, and 443 for users.

Before you start#

HTTPS is not optional in practice. The Excel add-in and every Microsoft 365 feature, including Entra sign-in, SharePoint, Microsoft 365 email and Teams distribution, require it, and over plain HTTP they fail quietly. Unlike a fresh Windows install, a Linux server does not create a certificate for itself, so setting up HTTPS is a step in this runbook rather than an afterthought.

Step 1: Choose your settings#

Run these lines in your local terminal. Everything that follows reuses them, so set them once and keep the terminal window open.

RG=rg-reportworq
LOC=eastus2
VM=vm-reportworq-01
DNSLABEL=contoso-reportworq
ADMIN=rwadmin
MYIP=$(curl -s https://ifconfig.me)

What each one is:

Setting What it means
RG The resource group name. A resource group is a folder that holds everything you create here, so deleting it removes the whole deployment.
LOC The Azure region. Choose the one closest to your users and to your data sources.
VM The name of the virtual machine. Choose this deliberately and do not change it later, see the note on license activation.
DNSLABEL The first part of the free Azure web address. This example produces contoso-reportworq.eastus2.cloudapp.azure.com. It must be unique within the region.
ADMIN The administrative user name you will use to sign in to the server over SSH.
MYIP Your current public IP address, looked up automatically. It is used to restrict SSH access to you.

Step 2: Create the resource group and the firewall rules#

An Azure network security group is the firewall in front of the machine. Create it with exactly three inbound rules.

az group create -n "$RG" -l "$LOC"

az network nsg create -g "$RG" -n nsg-reportworq

az network nsg rule create -g "$RG" --nsg-name nsg-reportworq -n allow-ssh \
  --priority 100 --access Allow --protocol Tcp --direction Inbound \
  --source-address-prefixes "$MYIP" --destination-port-ranges 22

az network nsg rule create -g "$RG" --nsg-name nsg-reportworq -n allow-http \
  --priority 110 --access Allow --protocol Tcp --direction Inbound \
  --source-address-prefixes Internet --destination-port-ranges 80

az network nsg rule create -g "$RG" --nsg-name nsg-reportworq -n allow-https \
  --priority 120 --access Allow --protocol Tcp --direction Inbound \
  --source-address-prefixes Internet --destination-port-ranges 443

Do not open ports 8080 or 8081. Port 8080 is Reportworq itself, which is reached through the proxy on the machine's internal address. Port 8081 is the Real-time Event Hub, and on a single server it is an internal endpoint that never leaves the machine. The guidance elsewhere to open both ports applies to a multi-server cluster, where worker nodes contact the web server across the network, and not to a single machine, see Deployment topology.

Step 3: Create the virtual machine and its data disk#

The published requirement is 4 cores, 32 GB of RAM and 10 GB of disk, plus roughly 2 GB of RAM for each job that runs at the same time. Reportworq runs 4 jobs at once by default. Size against your busiest moment, not your average, because peak memory tracks the number of jobs in flight, see System requirements.

Workload Virtual machine size Cores and memory
Pilot or trial Standard_D4ds_v5 4 cores, 16 GB. Below the stated minimum. Fine to prove the install, not a production footprint.
Production baseline Standard_E4ads_v7 4 cores, 32 GB. Meets the published minimum.
Higher concurrency Standard_E8ads_v7 8 cores, 64 GB. Choose this when you raise parallel job execution above about 8.
Large workbooks, heavy Excel Standard_E16ads_v7 16 cores, 128 GB.

Choose a size whose name contains a d, such as E4ads_v7. Those sizes include a fast local temporary disk that Reportworq uses as scratch space while rendering, at no extra cost. No graphics card and no display adapter is required.

az vm create -g "$RG" -n "$VM" \
  --image Ubuntu2404 \
  --size Standard_E4ads_v7 \
  --admin-username "$ADMIN" \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --public-ip-address-dns-name "$DNSLABEL" \
  --public-ip-sku Standard \
  --nsg nsg-reportworq \
  --os-disk-size-gb 128 \
  --os-disk-delete-option Delete

Then attach the data disk that will hold the repository:

az vm disk attach -g "$RG" --vm-name "$VM" -n disk-reportworq-repo \
  --new --size-gb 512 --sku Premium_LRS --lun 0

Why a separate managed disk, and not Azure Files. Parts of the Reportworq repository are SQLite databases, which hold job execution history, write-back history, and the audit logs. SQLite needs reliable file locking, which a network file share emulates imperfectly, and a fast, low-latency disk, because job execution writes many small files. A managed disk gives you both, and its snapshots are instant, which makes them your backup and your upgrade rollback. A file share is the right answer only when several machines must share one repository, which means a load-balanced cluster.

512 GB is a comfortable production start. The repository grows with your content, run history, generated output and logs. You can grow a managed disk later without recreating it.

Now connect to the server. Every command from here to Step 11 runs on the server, not on your local machine.

ssh "$ADMIN@${DNSLABEL}.${LOC}.cloudapp.azure.com"

Step 4: Prepare the data disk#

A new Azure disk arrives blank. These commands give it a filesystem and attach it to the folder Reportworq will use. Do this before installing Reportworq, so the repository lands on the disk from the start and nothing has to be moved later.

sudo apt-get update
sudo apt-get install -y parted xfsprogs

DEV=/dev/disk/azure/scsi1/lun0
sudo parted "$DEV" --script mklabel gpt mkpart primary xfs 0% 100%
sudo partprobe "$DEV"
sudo mkfs.xfs "${DEV}-part1"

sudo mkdir -p /var/lib/reportworq
UUID=$(sudo blkid -s UUID -o value "${DEV}-part1")
echo "UUID=$UUID  /var/lib/reportworq  xfs  defaults,nofail  0  2" | sudo tee -a /etc/fstab
sudo mount -a
df -h /var/lib/reportworq

The last command should report a filesystem of roughly 512 GB mounted on /var/lib/reportworq. If it does not, stop and resolve that before continuing.

Two details in the /etc/fstab line matter more than they look:

Step 5: Install the operating system prerequisites#

Reportworq ships with everything it needs to run except three things the operating system must provide.

sudo apt-get install -y \
  libicu-dev \
  fontconfig libfontconfig1 libfreetype6 libgomp1 \
  fonts-liberation fonts-dejavu-core fonts-noto-core
What Why it is required
libicu-dev International text support. Without it Reportworq stops immediately at startup with the message "Couldn't find a valid ICU package installed on the system."
fontconfig, libfontconfig1, libfreetype6, libgomp1 The graphics libraries used to render images and charts into Excel, PDF and PowerPoint output.
The font packages Not optional. A new Linux server has almost no fonts installed, and report output renders blank or as rows of boxes without them.

If your reports must look identical to output produced on Windows, install your organization's own fonts here as well. You can also manage fonts as workspace files instead, see Server configuration.

Step 6: Download and install Reportworq#

First, see which versions are available. This command lists every published version and the files each one contains:

curl -s https://quelock.reportworq.com/details/all/RW6

Then download and install the one you want. Replace 6.0.1.1 with your chosen version and AAA-BBB-CCC-DDD with your license key.

RWVER=6.0.1.1
cd /tmp
curl -fL -o "reportworq-${RWVER}-linux-x64.tar.gz" \
  "https://quelock.reportworq.com/download/all/RW6/${RWVER}/reportworq-${RWVER}-linux-x64.tar.gz?licenseKey=AAA-BBB-CCC-DDD"

tar -xzf "reportworq-${RWVER}-linux-x64.tar.gz"
cd "reportworq-${RWVER}-linux-x64"
sudo ./install.sh

The download is about 485 MB. Make sure you take the file ending in -linux-x64.tar.gz. Each release also publishes a container image whose name ends in .tar.gz, and the two are not interchangeable.

The installer is safe to run more than once, which is also how you upgrade later. It creates a restricted reportworq user account for the service to run under, and lays out these locations:

What Where
Program files /opt/reportworq/lib/app
Repository, your only durable data /var/lib/reportworq/repository, on the disk you mounted
Logs /var/log/reportworq
Configuration /etc/reportworq/reportworq.env

A first install deliberately leaves Reportworq stopped, so that you can set the configuration before it starts for the first time. That is the next step.

Step 7: Configure and start Reportworq#

Open the configuration file:

sudo nano /etc/reportworq/reportworq.env

Make it read as follows. nano is a simple text editor: edit the text, then press Ctrl+O and Enter to save, and Ctrl+X to exit.

RW_PORT=8080
RW_REPOSITORY_PATH=/var/lib/reportworq/repository
RW_BEHIND_REVERSE_PROXY=true

RW_BEHIND_REVERSE_PROXY=true is the line people most often miss, and leaving it out causes failures that are hard to diagnose. It tells Reportworq that something in front of it is handling HTTPS, so that the web addresses Reportworq generates for itself, including Microsoft sign-in redirects and Excel add-in callbacks, begin with https:// rather than http://. Without it those integrations break while everything else appears to work.

Keep this setting in the file. It is read at each startup and is not written into Reportworq's own settings, so removing the line reverts the behavior the next time the service restarts.

Now start Reportworq and check it came up:

sudo systemctl start reportworq
systemctl status reportworq
curl -I http://localhost:8080

systemctl status should report active (running), and the curl command should return a response from the web server rather than a connection error. To watch the startup messages in detail, run journalctl -u reportworq -f and press Ctrl+C to stop watching.

Step 8: Install Caddy#

Caddy is the web server that will handle HTTPS. Install it from its official package repository:

sudo apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
  | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
  | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt-get update && sudo apt-get install -y caddy

Step 9: Configure HTTPS#

Edit Caddy's configuration file:

sudo nano /etc/caddy/Caddyfile

Replace its entire contents with the following, changing the first line to your own web address:

contoso-reportworq.eastus2.cloudapp.azure.com {
    encode zstd gzip

    reverse_proxy 127.0.0.1:8080 {
        transport http {
            read_timeout 30m
            write_timeout 30m
        }
    }

    request_body {
        max_size 512MB
    }
}

What each part does:

Line Purpose
The web address on the first line Tells Caddy which address to serve, and which address to request a certificate for.
encode zstd gzip Compresses responses, which makes the interface noticeably faster over slow links.
reverse_proxy 127.0.0.1:8080 Passes each request through to Reportworq on the machine's internal address.
read_timeout and write_timeout The Reportworq interface and the Excel add-in hold long-lived connections. The default timeouts are short enough to cut them.
request_body max_size Source workbooks and report output can be large. The default limit is too small for them.

The first line must be your web address, never an IP address. This is the single most common way to get this step wrong. An IP address cannot legally be used in the part of the TLS handshake that tells the server which site is being requested, so a configuration keyed on an IP address matches nothing on port 443 and the browser gets a failed connection, while port 80 still redirects into it. Caddy also quietly issues itself an untrusted certificate for an IP address instead of requesting a real one.

Check the configuration, then apply it:

caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Caddy now contacts a certificate authority, proves it controls the address over port 80, and installs the certificate. This normally takes a few seconds. Confirm it worked from your own machine, not from the server:

curl -I https://contoso-reportworq.eastus2.cloudapp.azure.com

A 200 response means HTTPS is working. If it fails, see Troubleshooting.

From here on, Caddy renews the certificate automatically before it expires, and redirects anyone who arrives over plain HTTP.

Use your own domain name#

To serve Reportworq at an address in your own domain, such as reportworq.contoso.com, create a DNS A record for that name in your DNS provider pointing at the machine's public IP address. Find the IP address with:

az vm show -g "$RG" -n "$VM" -d --query publicIps -o tsv

Wait until the name resolves, then put that name on the first line of the Caddyfile instead of the Azure address and reload Caddy. Because the certificate is issued against whatever name the Caddyfile carries, it is worth getting the final address right before you hand the server to users.

Step 10: Check what you built#

From your own machine:

curl -sI https://contoso-reportworq.eastus2.cloudapp.azure.com | head -5
curl -sI http://contoso-reportworq.eastus2.cloudapp.azure.com | head -5

The first should return HTTP/1.1 200 OK. The second should return 308 Permanent Redirect to the https:// address, which is Caddy sending plain HTTP visitors to the secure address.

Step 11: Finish setup and activate the license#

Browse to your address. An empty repository opens the first-run wizard: Welcome, Repository, License, Users, Finish. See First-run setup for the wizard in detail.

To confirm the reverse proxy is configured correctly, open Settings > Configuration > Web Server after signing in. The SSL Certificate switch shows as on and cannot be changed, with the text "HTTPS is terminated by the reverse proxy - no certificate is configured on this instance." That message is confirmation that RW_BEHIND_REVERSE_PROXY took effect.

Outbound access the server needs: the licensing service and version downloads at quelock.reportworq.com; Microsoft Graph and Microsoft sign-in for Microsoft 365 distribution and Entra sign-in; your mail server for email distribution; and your own IBM Planning Analytics, database and other data source endpoints. Add these to your outbound rules if your network denies outbound traffic by default.

One caution specific to virtual machines. License activation is tied to the machine name. Resizing, stopping, deallocating and restarting the machine are all safe, because the name does not change. Rebuilding the machine under a different name invalidates the activation. Release the license seat before you decommission a server, and keep the same name if you rebuild one.

Day-to-day operations#

systemctl status reportworq
sudo systemctl restart reportworq
journalctl -u reportworq -f
sudo tail -f /var/log/reportworq/*.log

For Caddy, the equivalents are sudo systemctl reload caddy to apply a configuration change without dropping connections, and journalctl -u caddy -f to watch its log.

Upgrading#

Two paths work on Linux, and both preserve your repository, logs and configuration. Take a disk snapshot before either one:

az snapshot create -g "$RG" -n snap-repo-$(date +%Y%m%d-%H%M) \
  --source disk-reportworq-repo

In the product, at Settings > Update Reportworq, is the normal path. Pick a version and Reportworq downloads it, installs it alongside the current one, backs up the repository and restarts into it. For a server without internet access, Update from a patch file accepts a tarball you supply. See Update Reportworq.

From the tarball is the right choice when you want the exact files in your hands, for example for a server without internet access or a scripted rollout across several machines. Repeat Step 6 with the new version number. The installer stops the service, replaces the program files and starts it again.

Two things to know before you upgrade:

If a newly installed version will not start, remove it and restart. Reportworq automatically falls back to the previous version, and then to the originally installed one, so a failed upgrade cannot leave the server unable to start:

sudo rm -rf /opt/reportworq/Versions/v<version>
sudo systemctl restart reportworq

Each installed version is a full copy of the application, about 1 GB, and they are stored on the operating system disk rather than the data disk. Remove versions you no longer need from the Update Reportworq screen.

Backups#

What How How often
The repository, your only durable data Azure Backup on the machine, or a snapshot policy on the data disk Daily, and before every upgrade
Startup settings, /opt/reportworq/settings.json Include the operating system disk in the backup, or copy the file aside When it changes
Service configuration, /etc/reportworq/reportworq.env The same When it changes
Reportworq's own backup Settings > Configuration > Web Server > Backup Before upgrades, remembering it lives inside the repository

Everything that matters is on the data disk. Rebuilding a server is: create a new machine, install the prerequisites, install the tarball, attach the restored disk at /var/lib/reportworq, keep the same machine name, and start.

Troubleshooting#

Symptom Cause What to do
Reports render blank or as boxes No fonts installed Install the font packages from Step 5 and restart Reportworq
Reportworq stops immediately, log says "Couldn't find a valid ICU package" libicu-dev missing sudo apt-get install -y libicu-dev
The browser cannot connect over HTTPS, but http:// redirects to it The Caddyfile names an IP address instead of a web address Put the web address on the first line and reload Caddy. Check certificate activity with journalctl -u caddy | grep acme
The certificate is never issued Port 80 is closed, or the address does not resolve to this machine Confirm the allow-http rule exists, and that the address resolves to the machine's public IP
The Excel add-in or Microsoft 365 sign-in fails silently RW_BEHIND_REVERSE_PROXY is not set, so Reportworq builds http:// addresses Add it to /etc/reportworq/reportworq.env and restart Reportworq
A tarball upgrade appears to do nothing A version installed in the product outranks the one you unpacked Re-run install.sh, which clears them
The operating system disk is filling up Each installed version is about 1 GB Remove old versions from the Update Reportworq screen
The license is invalid after a rebuild Activation is tied to the machine name Keep the machine name, and release the seat before decommissioning
The machine will not start after a disk change An /etc/fstab entry without nofail Mount by UUID with nofail, as in Step 4
Jobs cannot reach a network file share Reportworq runs as the restricted reportworq user Mount the share with a user and group matching that account

Notes and limits#

Going deeper. For the choice between Windows, Linux and containers, see Deployment topology. For the sizing figures behind Step 3, see System requirements. For the license model and how seats are counted, see Licensing and entitlements. For moving an existing instance onto this server, see Migrate to a new server.

Feedback on this page

Comments, questions, requests, or something missing or unclear? Email us - the page you are on is filled in for you.

Email feedback on this page

Or write to support@reportworq.com directly.