Applications Azure

Spliit on Ubuntu 24.04 on Azure User Guide

| Product: Spliit on Ubuntu 24.04 LTS on Azure

Overview

This image runs Spliit 1.19.1, the self hosted, open source expense sharing application for splitting bills within a group, on Ubuntu 24.04 LTS. Spliit is built and run from /opt/spliit on the Node.js 22 LTS runtime by an unprivileged spliit system account under a systemd service that starts it on boot and restarts it on failure. A local PostgreSQL 16 database stores every group, participant and expense.

Spliit listens on the loopback address 127.0.0.1:3000 by design and is never exposed directly. nginx is installed as a reverse proxy on port 80 that forwards every request to Spliit. Visitors reach the application on the standard HTTP port.

Access model, read this first. Spliit has no user accounts and no login screen. You create a group, and Spliit gives that group a unique, unguessable URL. Anyone who has a group's URL can view and edit that group, and that is exactly how you invite people, by sharing the URL. Treat group URLs like secrets, and front the VM with HTTPS before sharing links over the internet.

The only secret in the image is the PostgreSQL role password, used locally by the application. This image is secure by default: on the first boot of every deployed VM a one shot service generates a fresh per VM database password, rewrites the application's connection strings, and writes the password and the access URL to /root/spliit-credentials.txt (mode 0600, readable only by root). No default database password is baked into the image, and two VMs deployed from the same image never share one.

What is included:

  • Spliit 1.19.1 built from source at /opt/spliit, run with next start on loopback 127.0.0.1:3000
  • nginx reverse proxy on :80 in front of the application
  • PostgreSQL 16 holding all group and expense data, bound to localhost only
  • A per VM PostgreSQL password generated at first boot, in a root only file, with no default baked in
  • spliit.service, nginx.service and postgresql.service as systemd units, enabled and active
  • A fully security patched Ubuntu 24.04 LTS base (phased updates included) at image build time
  • 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 good starting point; scale up for larger groups and higher traffic. NSG inbound: allow 22/tcp from your management network and 80/tcp from your users (front port 80 with TLS for public exposure, see Enabling HTTPS).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Spliit 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 -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name spliit \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name spliit --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

The application is three systemd services, the Spliit Next.js server (loopback 127.0.0.1:3000), the nginx reverse proxy on port 80, and the PostgreSQL database:

systemctl is-active spliit.service nginx.service postgresql.service
curl -s -o /dev/null -w 'home page HTTP %{http_code}\n' http://127.0.0.1/

All three services report active and the home page returns 200. The Spliit server is bound to loopback 127.0.0.1:3000 only, reachable exclusively through the nginx proxy on port 80.

Spliit services active and the loopback and proxy listeners

Step 5 - Retrieve your access URL and database password

On the first boot, a one shot service generated a unique PostgreSQL password for this VM and recorded the access URL. Read the credentials file (root only):

sudo cat /root/spliit-credentials.txt

You will see the SPLIIT_URL for this VM and the per VM POSTGRES_PASSWORD. Keep this file safe. The database password is only used locally by the application; Spliit itself has no login.

Per VM access URL and database password generated on first boot

Step 6 - Open Spliit and create a group

Open http://<vm-public-ip>/ in your browser. You land on the Spliit welcome page. Choose Go to groups, then create your first group: give it a name, pick a currency, and add the participants (the people sharing expenses).

The Spliit welcome page on a fresh VM

When you create a group, Spliit assigns it a unique URL such as http://<vm-public-ip>/groups/<group-id>/expenses. Share that URL with the people in the group, that URL is the access. Anyone with it can add expenses and see balances; there is nothing to sign up for.

Step 7 - Add expenses

Open the group and use the + button to add an expense. For each expense you set a title, an amount, who paid it, and who it was paid for (the split). By default the cost is split evenly between the selected participants, and you can switch to uneven shares, percentages or exact amounts.

The add expense form with the split options

Every expense appears in the group's Expenses tab, showing who paid and who shared it:

The group's expenses list

Step 8 - Read the balances and settle up

Open the Balances tab. Spliit shows how much each participant has paid or is owed, then computes the suggested reimbursements, the smallest set of payments that settles the group. When someone pays back, use Mark as paid to record it.

Balances and the suggested reimbursements that settle the group

This is the heart of Spliit: add what everyone spent, and it works out who owes what.

Where everything lives

Configuration is in /etc/spliit/spliit.env (the PostgreSQL connection strings). The application is in /opt/spliit and runs with next start. All data is in the local PostgreSQL spliit database:

ss -tln | grep -E ':80 |:3000 |:5432 '
node -v
psql --version

Spliit is bound to loopback 127.0.0.1:3000 only; PostgreSQL listens on 127.0.0.1:5432 only; the nginx proxy on :80 is the sole HTTP entry point.

Runtime versions and the health of the application

The Prisma managed schema (groups, participants, expenses and categories) lives in the spliit database:

sudo -u postgres psql spliit -c '\dt'

The Prisma managed schema in the local PostgreSQL database

Security baseline

The image is captured from a fully security patched Ubuntu 24.04 LTS base, including Ubuntu's phased updates, which standard upgrades can silently hold back, and unattended security updates remain enabled on your VM. Confirm the state at any time:

apt-mark showhold
cat /etc/apt/apt.conf.d/20auto-upgrades

No packages are held, and APT::Periodic::Unattended-Upgrade "1" keeps security patches flowing on the running VM. Because group URLs are the access control, enabling HTTPS before you share links is strongly recommended.

Enabling HTTPS

This image serves HTTP on port 80. For production, terminate TLS in front of Spliit. Two common options:

  • Azure managed TLS: put the VM behind an Azure Application Gateway or Azure Front Door with a managed certificate, and forward to the VM on port 80.
  • On VM TLS with Let's Encrypt: point a DNS record at the VM's public IP, open port 443 in the NSG, then install certbot and obtain a certificate:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

certbot edits the nginx site and sets up automatic renewal. After enabling HTTPS, share your group URLs with https://.

Service management

Restart Spliit after a configuration change with sudo systemctl restart spliit. Inspect a service with sudo systemctl status spliit (or nginx, postgresql). A 200 on the home page means the application and database are healthy:

curl -s -o /dev/null -w 'home page HTTP %{http_code}\n' http://127.0.0.1/

Backup and maintenance

  • Database backup: all Spliit data is in PostgreSQL. Back it up with pg_dump:

text sudo -u postgres pg_dump spliit | gzip > spliit-backup-$(date +%F).sql.gz

Restore with psql spliit < spliit-backup.sql (after gunzip). For point in time durability, also snapshot the OS disk in Azure. - OS updates: unattended security updates are enabled; apply everything else with sudo apt-get update followed by sudo apt-get upgrade. Reboot if a new kernel is installed. - Upgrading Spliit: back up the database first, then follow the upstream notes at https://spliit.app. Restart the spliit service afterwards.

Support

This image is backed by 24/7 cloudimg technical support by email and chat, covering deployment, creating groups, adding and splitting expenses, reading balances, database backup and scaling, and TLS termination. Spliit is open source software (MIT licensed); cloudimg provides the packaging and support and is not affiliated with or endorsed by the Spliit project.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.