OpenRelik on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of OpenRelik on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. OpenRelik is an open source platform for collaborative digital forensics and incident response. Investigators create a folder for a case, upload the evidence they have collected, and run processing workflows over it from the browser. The processing runs on a pool of independent Celery workers, so a long job such as building a Plaso super timeline runs in the background while the team carries on working, and the results land back in the same case folder for everyone to review.
The cloudimg image ships the free and open source, Apache-2.0 licensed OpenRelik server, web UI, mediator, metrics exporter and four processing workers, run the officially supported way as the upstream containers pinned by image digest. All eleven containers are captured into the VM, so your instance starts without pulling several gigabytes. Because this platform holds evidence, nothing here ships with a known secret: the PostgreSQL password, the session secret, the JWT signing key and the administrator password are all generated for each VM on first boot, before the application is reachable, and Google single sign on ships deliberately unconfigured and closed rather than open. Backed by 24/7 cloudimg support.
OpenRelik is a trademark of its respective owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by OpenRelik or Google LLC. It ships the free and open source Apache-2.0 licensed software, unmodified.

What is included:
- OpenRelik server 0.7.0 (the Apache-2.0 licensed FastAPI backend), pinned by image digest
- OpenRelik web UI 0.7.0 (the Apache-2.0 licensed Vue application), pinned by image digest
- The OpenRelik mediator and Celery metrics exporter, pinned by image digest
- Four processing workers: Plaso (super timelining), strings, grep and archive/disk-image extraction
- PostgreSQL 17 for application data and Valkey 8 (BSD-3-Clause) as the Celery broker and result backend
- Prometheus for task queue metrics
- Docker Engine with the backend and UI published to the loopback interface only, fronted by nginx on port
80at/(UI),/api/(REST API) and/auth/(local sign in) openrelik.service,openrelik-firstboot.service,openrelik-postboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A per instance PostgreSQL password, session secret, JWT signing key and administrator password generated per VM on first boot, never baked into the image
- No default login, no shipped OAuth client secret, and an empty database on first boot
- Ubuntu 24.04 LTS base with latest security patches applied at build time
- Azure Linux Agent for seamless cloud integration and SSH key injection
- 24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
- Active Azure subscription, SSH public key, VNet + subnet in target region
- Subscription to the OpenRelik listing on Azure Marketplace
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) runs the whole stack and is the size this image is validated on. For real casework, and especially for Plaso super timelining over large disk images, use Standard_D4s_v5 or larger and attach a data disk for evidence. NSG inbound: allow 22/tcp from your management network and 80/tcp for the web UI from the networks your analysts use.
Step 1: Deploy from the Azure Portal
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OpenRelik 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
RG="openrelik-prod"; LOCATION="eastus"; VM_NAME="openrelik-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/openrelik-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name openrelik-vnet --address-prefix 10.100.0.0/16 --subnet-name openrelik-subnet --subnet-prefix 10.100.1.0/24
az network nsg create -g "$RG" --name openrelik-nsg
az network nsg rule create -g "$RG" --nsg-name openrelik-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 openrelik-nsg --name allow-http --priority 110 \
--source-address-prefixes "<your-analyst-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 openrelik-vnet --subnet openrelik-subnet --nsg openrelik-nsg --public-ip-sku Standard
Step 3: Connect to your VM
ssh azureuser@<vm-ip>
Step 4: Confirm the services are running
The platform runs as eleven containers under one openrelik.service, fronted by nginx. Confirm the services are active and list the containers:
sudo systemctl is-active docker openrelik nginx
sudo docker compose --env-file /opt/openrelik/config.env -f /opt/openrelik/docker-compose.yml ps
You will see the services report active and all eleven containers running. The backend (127.0.0.1:8710) and the web UI (127.0.0.1:8711) are bound only to the loopback interface; PostgreSQL, Valkey, Prometheus, the mediator, the metrics exporter and the four Celery workers publish no host port at all and are reachable only on the private container network. nginx on :80 is the single public front door.
Step 5: Verify the listener isolation
Because this platform holds evidence, it matters that only the intended ports face the network. List every listening TCP socket on the VM:
sudo ss -tln
Only 22 (SSH) and 80 (nginx) are bound to a routable address. Everything else is on 127.0.0.1 or on the private container bridge. This is asserted at build time by an automated check that first proves itself against a deliberate public bind before trusting its own verdict.

Step 6: Read the per instance credentials
A unique PostgreSQL password, session secret and JWT signing key were generated for this VM on the first boot, before any container started, and an administrator account was then seeded with a random password. Read them:
sudo cat /root/openrelik-credentials.txt
The file (mode 0600 root:root) holds ADMIN_USERNAME and ADMIN_PASSWORD (the account you sign in to the web UI with), plus WEB_URL and API_URL. None of these ship in the image; every value is unique to this VM, so no two instances share a credential and there is no default login to change.
Step 7: Verify the security model
The web UI loads without authentication, but every API endpoint that reads or writes case data requires a valid session. Confirm that an unauthenticated write is rejected, that a forged token is rejected, and that the per instance administrator credential authenticates the same call:
sudo /usr/local/sbin/openrelik-roundtrip.sh
The bundled prover reports OK after checking that a complete, well formed folder creation request is rejected with 401 when unauthenticated and again when sent with a forged signing key, that the byte identical request then succeeds with 201 using a real session from the per instance administrator, and that a wrong password and an empty password are both rejected. The positive control is the important half: it proves the rejections were authentication and not a malformed request.

Step 8: Prove a workflow really runs
Status codes do not prove a forensics platform works. The image ships an end to end prover that creates a real case folder, uploads a real evidence file containing a randomly generated marker, runs the real strings workflow on a real Celery worker, waits for it to finish, downloads the artefact the worker produced, and asserts the marker is inside it:
sudo /usr/local/sbin/openrelik-workflow-proof.sh
It reports WORKFLOW_OK with the folder, evidence, workflow and artefact identifiers, and tidies up the case it created.

Step 9: Open the web UI and sign in
Browse to http://<vm-ip>/ to reach OpenRelik. Sign in with the ADMIN_USERNAME and ADMIN_PASSWORD from Step 6. There is no self registration and no default account; additional users are created from the command line in Step 14.

Step 10: Create a case folder
After signing in you land on the folder list, which is your case list. Choose New folder and name it for the incident you are working. Folders are the unit of collaboration in OpenRelik: evidence, workflows and results all live in a folder, and a folder can be shared with colleagues from the Share button.

Step 11: Upload evidence and run a workflow
Open the case folder and choose Upload files to add the artefacts you collected, then Create workflow, select the uploaded file, and add a task such as Strings, Grep, Extract files from archives or Plaso Log2Timeline. Run it and the task is dispatched to the matching Celery worker. Workflows are named Untitled workflow until you rename them.

Step 12: Review the results
When the task completes it writes its output back into the case as a new file. Open it to read the artefact the worker produced directly in the browser, or use Download to pull it locally. Below, the strings worker has processed the collected artefact and produced a byte offset indexed listing in which the suspicious indicators, a staging URL, a persistence registry key, a command and control address and an encoded PowerShell invocation, are immediately readable.

Step 13: Call the API from your own machine
Everything the UI does is backed by the REST API. Sign in to obtain a session cookie and a CSRF token, then call an endpoint:
COOKIES=$(mktemp)
ADMIN_USERNAME=$(sudo grep '^ADMIN_USERNAME=' /root/openrelik-credentials.txt | cut -d= -f2-)
ADMIN_PASSWORD=$(sudo grep '^ADMIN_PASSWORD=' /root/openrelik-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -c "$COOKIES" -X POST http://localhost/auth/local \
--data-urlencode "username=$ADMIN_USERNAME" --data-urlencode "password=$ADMIN_PASSWORD"
CSRF=$(awk '/csrf_token/{print $7}' "$COOKIES" | tail -1)
curl -s -b "$COOKIES" -H "X-CSRF-Token: $CSRF" http://localhost/api/v1/folders/ | head -c 400
echo
curl -s -b "$COOKIES" -H "X-CSRF-Token: $CSRF" http://localhost/api/v1/taskqueue/tasks/registered | head -c 400
rm -f "$COOKIES"
The first call lists your case folders and the second lists every processing task registered on the queue. From your own workstation use http://<vm-ip>/ in place of http://localhost/.
Step 14: Manage user accounts
Accounts are managed with the server's admin.py utility. Add an analyst, or change a password:
cd /opt/openrelik
sudo docker compose --env-file config.env -f docker-compose.yml exec openrelik-server \
python admin.py create-user analyst --password '<choose-a-strong-password>'
Add --admin to grant administrator rights. Change the seeded administrator password the same way with python admin.py change-password admin. Every new user automatically joins the built in Everyone group, and folder sharing is controlled per folder from the UI.
Step 15: Enable Google single sign on (optional)
This image ships with local authentication only, and Google single sign on deliberately disabled and closed: client_id and client_secret are empty, the allowlist is empty and public_access is false. cloudimg never ships an OAuth client secret. To enable it, create an OAuth client in your own Google Cloud project, then edit /opt/openrelik/config/settings.toml and set client_id, client_secret, and either workspace_domain or an explicit allowlist of permitted email addresses. Add google to OPENRELIK_AUTH_METHODS on the openrelik-ui service in /opt/openrelik/docker-compose.yml, then restart:
sudo systemctl restart openrelik
Leave public_access = false unless you genuinely intend anyone with a Google account to be able to sign in.
Step 16: Scale the worker pool
The image ships a worker concurrency tuned to fit a 2 vCPU appliance. On a larger VM, raise it: edit /opt/openrelik/docker-compose.yml and increase --concurrency on the worker services (openrelik-worker-strings, openrelik-worker-grep, openrelik-worker-plaso, openrelik-worker-extraction), then restart the stack with sudo systemctl restart openrelik. Plaso and extraction are the memory hungry workers; raise those last and watch memory before doing so.
Step 17: Server components
| Component | Version / Detail |
|---|---|
| Backend | OpenRelik server 0.7.0 (FastAPI, pinned by image digest) |
| Web UI | OpenRelik UI 0.7.0 (Vue, pinned by image digest) |
| Orchestration bridge | OpenRelik mediator 0.7.0 |
| Processing workers | Plaso 0.5.0, strings 0.3.0, grep 0.2.0, extraction 0.5.0 |
| Application database | PostgreSQL 17 (created empty on first boot) |
| Task broker | Valkey 8 (BSD-3-Clause), Celery broker and result backend |
| Metrics | OpenRelik metrics exporter 0.7.0 with Prometheus v3 |
| Front door | nginx on :80 routing / to the UI, /api/ and /auth/ to the backend |
| Evidence store | /opt/openrelik/data/artifacts |
| Per instance secrets | DB password, session secret and JWT key generated first boot into /opt/openrelik/config.env and /opt/openrelik/config/settings.toml |
| Admin account | per instance random password, seeded first boot into /root/openrelik-credentials.txt |
| Operating system | Ubuntu 24.04 LTS (patched at build) |
| License | Apache-2.0 (OpenRelik) |
Step 18: Managing the service
sudo systemctl status openrelik --no-pager | head -12
sudo docker compose --env-file /opt/openrelik/config.env -f /opt/openrelik/docker-compose.yml logs --tail 40 openrelik-server
Restart the whole stack with sudo systemctl restart openrelik, follow a worker live with ... logs -f openrelik-worker-plaso, and view configuration in /opt/openrelik/config.env, /opt/openrelik/config/settings.toml and /opt/openrelik/docker-compose.yml. After changing configuration, restart the service to apply it.
Step 19: Use your own domain and HTTPS (production)
The image serves the UI and API over plain HTTP on port 80, which is convenient behind a load balancer or on a private network. Because this platform carries evidence and credentials, terminate TLS in front of it for any real deployment:
- Front the VM with Azure Application Gateway, a load balancer with a managed certificate, or a CDN, and forward to nginx on port
80. - Or install your own certificate: add a TLS
serverblock to/etc/nginx/sites-available/openrelikreferencing your certificate and key, open443/tcpon the NSG, thensudo systemctl reload nginx. - Point a DNS name you control at the VM public IP. The UI and backend read their public address at first boot from the resolved public IP, so use a stable public IP, or update
OPENRELIK_SERVER_URLin/opt/openrelik/config.envandapi_server_url/ui_server_url/allowed_originsin/opt/openrelik/config/settings.tomlto your domain and restart.
Step 20: Security recommendations
- Restrict the NSG. Allow TCP 80 only from your analysts' networks and TCP 22 only from your management network. Evidence should never be reachable from the open internet.
- Terminate TLS in front of the app (Step 19) so credentials, evidence and results are encrypted in transit.
- Rotate the seeded administrator password after first sign in, and create a named account per analyst (Step 14) so actions are attributable.
- Keep single sign on closed unless configured deliberately, and never set
public_access = truewithout an allowlist or workspace domain. - Keep the internal services private. PostgreSQL, Valkey, Prometheus and the workers publish no host port; keep it that way and never expose the container ports directly.
- Put evidence on a dedicated encrypted disk for real casework, and back up
/opt/openrelik/dataalongside the PostgreSQL volume. - Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Step 21: Support and Licensing
OpenRelik and its workers are distributed under the Apache License 2.0. This cloudimg image bundles the unmodified official open source releases; cloudimg provides the packaging, the single nginx front door, the per instance secret and administrator generation, the listener isolation checks, the paired deploy guide, and 24/7 support with a guaranteed 24 hour response SLA. Valkey is used in place of Redis as the Celery broker so the image carries only permissively licensed components. OpenRelik is an independent open source project and this image is not affiliated with or endorsed by it.
Deploy on Azure
Launch OpenRelik on Ubuntu 24.04 LTS by cloudimg from the Azure Marketplace and follow this guide to a working digital forensics and incident response platform in minutes.