Deployment guide

Spliit

Overview

Spliit is a self-hosted, open-source application for sharing expenses and splitting bills within a group. This image runs Spliit 1.19.1 on Ubuntu 24.04 LTS, with a local PostgreSQL 16 database that stores every group, participant and expense.

Spliit is built and run from /opt/spliit on the Node.js 22 LTS runtime by an unprivileged spliit system account. A systemd service starts it on boot and restarts it on failure. Spliit listens on the loopback address 127.0.0.1:3000 and is never exposed directly. nginx runs as a reverse proxy on port 80 and forwards every request to Spliit.

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

The only secret in the image is the PostgreSQL role password, which the application uses locally. The image is secure by default: on the first boot of every VM, a one-shot service generates a fresh per-VM database password and rewrites the application's connection strings. It 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 you get:

  • Spliit 1.19.1 built from source at /opt/spliit and run with next start on loopback 127.0.0.1:3000
  • An 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 and stored in a root-only file, with no default baked in
  • spliit.service, nginx.service and postgresql.service as enabled, active systemd units
  • A fully security-patched Ubuntu 24.04 LTS base at image build time, phased updates included
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size. Scale up for larger groups and higher traffic.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp from your users. For public exposure, put TLS in front of port 80 (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 SecureAnyCloud, and select Create.

On the Basics tab, 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).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:spliit-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name spliit \
  --image sac1647283583153:spliit-ubuntu-24-04:default:latest \
  --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

Connect over SSH as azureuser:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

The application runs as 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. Check them and the home page:

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, so it is reachable solely through the nginx proxy on port 80.

Step 5 - Retrieve your access URL and database password

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

sudo cat /root/spliit-credentials.txt

The file lists the SPLIIT_URL for this VM and the per-VM POSTGRES_PASSWORD. Keep a copy somewhere safe. The application uses the database password locally, and Spliit itself has no login.

Step 6 - Open Spliit and create a group

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

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

Step 7 - Add expenses

Open the group and select the + button to add an expense. Set a title and an amount, then choose who paid and who it was paid for (the split).

By default, Spliit splits the cost evenly between the selected participants. You can switch to uneven shares, percentages or exact amounts.

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

Step 8 - Read the balances and settle up

Open the Balances tab. Spliit shows how much each participant has paid or is owed. It then computes the suggested reimbursements, the smallest set of payments that settles the group.

When someone pays back, select Mark as paid to record it. You add what everyone spent, and Spliit works out who owes what.

Where everything lives

Configuration is in /etc/spliit/spliit.env, which holds the PostgreSQL connection strings. The application is in /opt/spliit and runs with next start. All data is in the local PostgreSQL spliit database. Check the listening ports and runtime versions:

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.

The Prisma-managed schema (groups, participants, expenses and categories) lives in the spliit database. List its tables:

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

Security baseline

The image is captured from a fully security-patched Ubuntu 24.04 LTS base. That includes Ubuntu's phased updates, which standard upgrades can silently hold back. 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. Group URLs are the access control, so enable HTTPS before you share links.

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 you enable 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. The command is 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, and 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 SecureAnyCloud technical support by email and chat. Support covers deployment, creating groups, adding and splitting expenses, reading balances, database backup and scaling, and TLS termination.

Spliit is open-source software (MIT licensed). SecureAnyCloud 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.

Deploy on Azure

Launch Spliit on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure