Developer Tools Azure

REI3 on Ubuntu 24.04 LTS on Azure

| Product: REI3 on Ubuntu 24.04 LTS

Overview

REI3 is an open low code business application platform. You build and run multi user, database backed business applications entirely from a browser: forms, relations, roles, workflows and reports, authored in a graphical Builder and backed by real PostgreSQL tables. An application store of ready made modules means you can also start from a working set of business applications instead of a blank page. It is the self hosted, MIT licensed peer of the well known low code builders, with no seat metering and no vendor hosting in the middle.

The cloudimg image runs REI3 3.12.7 as its official, unmodified Linux server binary alongside PostgreSQL 16 on the same VM, on a hardened, fully patched Ubuntu 24.04 LTS base. The database is a same box dependency rather than a separate service to provision, so the VM boots and serves on its own with nothing else to stand up.

REI3 documents a default login of admin / admin, and its own initialiser seeds exactly that account the first time it meets an empty database. This image never ships it. The image is deliberately shipped unprovisioned — no REI3 database, no configuration file, no TLS key and therefore no accounts at all. On the first boot of every VM a one shot service creates this VM's database and its own random passwords, creates a single administrator with a random password, and deletes the seeded admin account before REI3 is ever reachable. Nothing is bound to a network port until that finishes, and no secret is ever shared between customers. Backed by 24/7 cloudimg support.

What is included:

  • REI3 3.12.7 (MIT licensed) as the official upstream Linux server binary, managed by systemd
  • The REI3 web interface on :443 over HTTPS, served by REI3 itself, with :80 redirecting to it
  • PostgreSQL 16 on the same VM, reachable only over loopback
  • A per VM database password and administrator password generated on first boot and recorded in a root only file
  • REI3's documented default admin / admin login deleted during first boot, and proven absent
  • A TLS certificate generated on first boot for this VM's own addresses, so no private key ships in the image
  • Nothing bound to :443 or :80 until first boot has provisioned and secured the instance
  • A default drop nftables firewall so only 22, 80 and 443 are reachable from the network
  • ImageMagick and Ghostscript for REI3's file and PDF thumbnails, and the PostgreSQL client tools for its integrated backups
  • postgresql.service, rei3.service, nginx.service and nftables.service as enabled units so the stack returns after a reboot
  • 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; size up for many concurrent users or large applications. NSG inbound: allow 22/tcp from your management network and 443/tcp so your browser can reach REI3, plus 80/tcp if you want the automatic redirect from http:// to work.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for REI3 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), HTTPS (443) and HTTP (80). Then Review + create and Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name rei3 \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open the web ports so your browser can reach REI3:

az vm open-port --resource-group <your-rg> --name rei3 --port 443 --priority 1001
az vm open-port --resource-group <your-rg> --name rei3 --port 80  --priority 1002

Step 3 - Confirm the services are running

SSH in as azureuser. First boot creates this VM's PostgreSQL role and database, builds the REI3 schema, creates your administrator, deletes REI3's seeded default account and generates this VM's TLS certificate. It completes in well under a minute, after which REI3 is listening on :443.

systemctl is-active postgresql rei3 nginx nftables
systemctl show -p Result -p ActiveState --value rei3-firstboot.service

REI3 serves HTTPS itself on :443; nginx exists only to redirect :80 to it. PostgreSQL is bound to loopback and is never exposed to the network.

ss -tlnH | awk '{print $4}' | sort -u

The postgresql, rei3, nginx and nftables systemd units reporting active, the first boot service reporting success, and the listening sockets showing REI3 on 443, nginx on 80 and PostgreSQL bound to loopback only

Step 4 - Confirm no default credential shipped

This is the check worth doing on any appliance that has a documented default login. REI3's initialiser seeds an admin / admin account whenever it meets an empty database; first boot deletes it, so exactly one account exists on your VM and it is yours.

sudo -u postgres psql -tAc "SELECT count(*) FROM instance.login" rei3
sudo -u postgres psql -tAc "SELECT count(*) FROM instance.login WHERE name='admin'" rei3

The second command must print 0. You can also confirm it against the live login endpoint — the published default is refused:

curl -ks -o /dev/null -w 'admin/admin -> HTTP %{http_code}\n' -X POST \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}' https://127.0.0.1/api/auth

One login total, zero logins named admin, the single account being the per VM administrator, and REI3's published default admin slash admin refused with HTTP 401 by the live login endpoint

Step 5 - Review the host firewall

A default drop nftables ruleset ships with the image, so PostgreSQL stays a same box dependency no matter how the network security group is later widened.

sudo nft list ruleset | sed -n '/chain input/,/}/p'

Step 6 - Retrieve this VM's administrator credentials

First boot writes them to a root only file. It records the sign in URL, your administrator login and password, and the PostgreSQL credentials REI3 uses.

sudo stat -c '%n  mode %a  owner %U:%G' /root/rei3-credentials.txt
sudo grep -E '^(REI3_URL|rei3\.admin\.login)=' /root/rei3-credentials.txt

Read the whole file, including the password, with:

sudo cat /root/rei3-credentials.txt

Confirm the password actually authenticates. This posts to REI3's own login endpoint and checks the response body, not just the status line:

CODE=$(curl -ks -o /tmp/rei3-auth.json -w '%{http_code}' -X POST \
  -H 'Content-Type: application/json' \
  -d '{"username":"<REI3_ADMIN_LOGIN>","password":"<REI3_ADMIN_PASSWORD>"}' \
  https://127.0.0.1/api/auth)
echo "per-VM administrator -> HTTP ${CODE}"
test "${CODE}" = "200" || { echo "ERROR: the per-VM administrator did not authenticate"; exit 1; }
grep -q '"token"' /tmp/rei3-auth.json || { echo "ERROR: no session token in the response"; exit 1; }
echo "OK: authenticated and received a session token"
rm -f /tmp/rei3-auth.json

A wrong password is refused:

curl -ks -o /dev/null -w 'wrong password -> HTTP %{http_code}\n' -X POST \
  -H 'Content-Type: application/json' \
  -d '{"username":"<REI3_ADMIN_LOGIN>","password":"DefinitelyNotThePassword123"}' \
  https://127.0.0.1/api/auth

The per VM administrator authenticating with HTTP 200 and receiving a session token, a wrong password refused with HTTP 401, and the same correct password refused after the account is deactivated directly in PostgreSQL then accepted again once reactivated

Step 7 - Sign in to REI3

Browse to https://<your-vm-public-ip>/ and sign in with the login and password from Step 6. REI3 serves HTTPS with a certificate generated on this VM's first boot for this VM's own addresses. Because it is self signed, your browser will warn the first time; that is expected for a freshly deployed appliance, and Step 11 shows how to install your own certificate.

A new instance starts in maintenance mode, which is REI3's normal state for a system that has not been set up yet: administrators can sign in and use the Builder, and everyone else is held out until you are ready. Step 10 switches it to production mode.

The REI3 sign in page showing the maintenance mode notice and the username and password fields, protected by the administrator account generated on this VM's first boot

Step 8 - Install your first applications

A new instance has no applications yet, so REI3 offers you three ways to get started: install the ready made Core Company set, install individual modules from the repository, or import an application from a file.

Core Company is the fastest way to see the platform doing real work. It installs a connected set of business applications — absence management, time tracking, projects and tasks, ticketing, a password safe, IT asset management and an organisation directory. Choose Install Core Company and give it a minute or so to download and build its schema.

Once installed, the home page lists your applications grouped by area. The platform version is shown in the corner.

The REI3 applications home listing the installed Asset, Company, Operations and Shared application groups as cards, with the platform version 3.12.7 shown in the corner

Step 9 - Give your account access, then use an application

REI3 separates installing an application from being allowed to use it, so a freshly installed module is not visible to anyone until roles are assigned. Go to Administration (the icon by your user name) then Memberships, pick a role from the list at the top, add your user to it, and choose Save. Repeat for each application you want access to.

Back on the home page the applications are now open to you. Choosing Tasks and then New opens a real form — a title, a rich text description, deadline, priority, progress, state, owner and file attachments — and saving it writes a row to PostgreSQL that immediately appears in the list.

The REI3 Tasks application showing a My tasks list with four saved task records, each with its state, progress, priority, last changed timestamp and owner

Every record you create here is an ordinary row in an ordinary PostgreSQL table on this VM, which you can confirm directly:

sudo -u postgres psql -tAc \
  "SELECT count(*) FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema')" rei3

Step 10 - Administration and production mode

Administration shows the platform version, the update state, this VM's public hostname (set to your VM's address on first boot, so the links REI3 generates point at the right place), the password policy, session lifetime, email accounts, backups, logs and the scheduler.

When you have finished setting the system up, turn Maintenance mode off to put the instance into production mode so your users can sign in. Add those users under Users, and grant them application access under Memberships exactly as in Step 9.

The REI3 administration System configuration page showing platform version 3.12.7, version state Current, this VM's public hostname, the maintenance and builder mode switches, and the password policy

You can confirm the public hostname was pointed at this VM rather than left as a placeholder:

sudo -u postgres psql -tAc \
  "SELECT value FROM instance.config WHERE name='publicHostName'" rei3

Step 11 - Install your own TLS certificate

REI3 reads its certificate and key from /opt/rei3/data/certificates/. The shipped pair is generated on first boot for this VM and is self signed. To use your own certificate, copy the PEM encoded certificate and key over cert.crt and cert.key, keep them owned by the rei3 user, and restart the service:

sudo install -o rei3 -g rei3 -m 0644 /path/to/fullchain.pem /opt/rei3/data/certificates/cert.crt
sudo install -o rei3 -g rei3 -m 0640 /path/to/privkey.pem   /opt/rei3/data/certificates/cert.key
sudo systemctl restart rei3

Confirm the certificate the running server is presenting:

sudo openssl x509 -in /opt/rei3/data/certificates/cert.crt -noout -subject -ext subjectAltName

The nftables input chain with a drop policy accepting only loopback, established traffic and TCP ports 22, 80 and 443, the TLS certificate issued to cloudimg naming this VM's own addresses, and the credentials file at mode 600 owned by root

Step 12 - Check persistence and hardening

The stack is enabled to return after a reboot, the credentials file is root only, and no swap is baked into the OS disk (an Azure image requirement). Unattended security upgrades keep the base operating system patched.

systemctl is-enabled postgresql rei3 nginx nftables rei3-firstboot
swapon --show | wc -l
apt-mark showhold | wc -l

Both counts must be 0: no swap devices, and no packages held back from security updates.

Step 13 - Back up and maintain your VM

REI3 has its own integrated backup feature under Administration then Backups, which uses the PostgreSQL client tools shipped in this image; set a target directory and a schedule there. For VM level protection, take Azure snapshots or use Azure Backup on the OS disk, which captures the database, your applications and their data together.

To back up the database by hand:

sudo -u postgres pg_dump -Fc rei3 > /var/backups/rei3-$(date +%F).dump

The base operating system applies security updates automatically through unattended upgrades. To move to a newer REI3 release, follow the upstream upgrade notes at rei3.de and take a database backup first.

Security notes

  • No default credential ever exists on your VM. REI3's documented admin / admin account is created by its own initialiser against an empty database and is deleted during first boot, before the service is reachable. Step 4 proves it is gone.
  • Every secret is unique to your VM. The administrator password, the PostgreSQL role password, REI3's internal token signing secret and the TLS private key are all generated on your VM's first boot. Nothing is baked into the image.
  • The instance is not reachable until it is secured. rei3.service will not start until first boot has written its bootstrap marker, so an unprovisioned REI3 can never come up and seed a default account ahead of it.
  • PostgreSQL is not on the network. It listens on loopback and the default drop firewall does not open 5432.
  • Restrict 22/tcp to your management network, and put your own certificate in front of REI3 (Step 11) before exposing it to the internet.
  • Change the administrator password from the user menu after your first sign in, and set your password policy under Administration.
  • Keep Builder mode off in production; it is a design time tool.

Architecture summary

Component Detail
REI3 3.12.7, official upstream Linux server binary, MIT licensed
Web interface HTTPS on :443, served by REI3 itself
Port 80 nginx, 301 redirect to HTTPS, proxies nothing
Database PostgreSQL 16 on the same VM, loopback only
Application data Ordinary PostgreSQL tables in the rei3 database
Files and thumbnails /opt/rei3/data/, with ImageMagick and Ghostscript
TLS Self signed, generated on first boot for this VM's addresses
First boot rei3-firstboot.service — database, administrator, TLS, and deletion of the seeded default account
Credentials /root/rei3-credentials.txt, mode 0600, owner root
Firewall nftables, default drop, allowing 22, 80, 443
Base image Ubuntu 24.04 LTS, fully patched, unattended security upgrades enabled

Support

cloudimg provides 24/7 support for this image. Email support@cloudimg.co.uk with your VM's region and size, the output of Step 3, and what you were doing when the problem appeared. REI3 product documentation is at rei3.de.