Deployment guide

Yuvomi

Overview

This guide covers the deployment and configuration of Yuvomi on Ubuntu 24.04 on Azure using SecureAnyCloud Azure Marketplace images. Yuvomi is an open-source, self-hosted family planner that brings a whole household's day-to-day organisation into one private web app. It combines shared tasks and chores, a family calendar, shopping and pantry lists, meal planning and recipes, budgets and contacts. Each family member has an account, so everyone sees what they need and jobs can be assigned and tracked.

Everything lives on your own server rather than a third-party cloud, so household routines, schedules and finances stay under your control.

The SecureAnyCloud image ships the free and open-source, MIT-licensed Yuvomi application. It runs the officially supported way, as a single container built from the pinned upstream source and backed by an embedded SQLite database. There is no external database to provision, and your instance starts in seconds.

Upstream Yuvomi lets the first visitor to a new instance run the setup wizard and become the admin, which is a real risk for a VM with a public IP. This image closes that window completely. On first boot, before the public port is ever opened, the instance generates a per-VM session signing secret and a per-VM database encryption key. It then claims the admin account itself with a per-VM random password, written to a root-only file. The database is encrypted at rest with a key unique to this VM.

Yuvomi is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by the Yuvomi project. It ships the free and open-source self-hosted software, unmodified.

What you get:

  • Yuvomi v1.87.0 (the MIT-licensed Node.js family planner), built from the pinned upstream source tag
  • Embedded SQLite database, created empty on first boot, encrypted at rest with a per-VM key and stored on a persistent path
  • Docker Engine running the application container, published to loopback only
  • Host nginx as the single public listener, terminating TLS on port 443 with a per-VM self-signed certificate and a redirect from port 80
  • yuvomi.service, yuvomi-firstboot.service and yuvomi-postboot.service as systemd units, enabled and active on boot
  • A per-VM session signing secret, a per-VM database encryption key and a per-VM admin account password, generated on first boot and never baked into the image
  • The admin account claimed during bootstrap while port 443 is still closed, so a passer-by can never run the setup wizard
  • No open self-registration: further members are added by invitation only, by the admin from Settings
  • No default login, no shipped secret, no bundled third-party API key and an empty database on first boot
  • Ubuntu 24.04 LTS base with the latest security patches applied at build time
  • Azure Linux Agent for cloud integration and SSH key injection
  • 24/7 SecureAnyCloud support with a guaranteed 24-hour response SLA

Prerequisites

  • An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
  • A subscription to the Yuvomi listing on Azure Marketplace
  • Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM). It is a comfortable starting point for a person, a household or a small family, and the application idles at around 150 MB of memory. For a large household or many concurrent users, use Standard_D2s_v5 or larger.
  • Network security group inbound rules that allow 22/tcp from your management network and 443/tcp for the web app from the networks that use it
1

Deploy from the Azure Portal

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Yuvomi 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 HTTPS (443).

Select Review + create, then Create.

2

Deploy from the Azure CLI

RG="yuvomi-prod"; LOCATION="eastus"; VM_NAME="yuvomi-01" IMAGE_URN="sac1647283583153:yuvomi:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name yuvomi-vnet --address-prefix 10.100.0.0/16 --subnet-name yuvomi-subnet --subnet-prefix 10.100.1.0/24 az network nsg create -g "$RG" --name yuvomi-nsg az network nsg rule create -g "$RG" --nsg-name yuvomi-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 yuvomi-nsg --name allow-https --priority 110 \
  --destination-port-ranges 443 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:yuvomi:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name yuvomi-vnet --subnet yuvomi-subnet --nsg yuvomi-nsg --public-ip-sku Standard

Replace <sub-id> and <version> with your subscription ID and the image version shown on the listing. Replace <your-mgmt-cidr> with the network you administer from.

3

First boot and per-instance credentials

On the first boot of each VM, Yuvomi generates its own per-instance secrets and claims its own admin account before the web port is opened. Nothing is baked into the image.

Give the instance a minute after first boot, then SSH in and read the credentials file. The file is 0600 root:root:

sudo cat /root/yuvomi-credentials.txt

The file contains everything unique to this instance:

  • YUVOMI_USERNAME and YUVOMI_PASSWORD are the admin login that you use in the web UI. The admin has full access, including member management.
  • YUVOMI_URL is the web address of this instance, resolved from its public IP on first boot.

The session signing secret and the database encryption key are held in /opt/yuvomi/.env (also 0600 root:root) and never leave the VM.

Confirm that the services and container are healthy:

sudo systemctl is-active docker yuvomi-firstboot yuvomi yuvomi-postboot nginx
active active active active active
sudo docker compose -f /opt/yuvomi/docker-compose.yml ps --format 'table {{.Service}}\t{{.Status}}\t{{.Ports}}'
SERVICE STATUS PORTS yuvomi Up 8 minutes (healthy) 127.0.0.1:3000->3000/tcp

The application container publishes to loopback only. Host nginx on port 443 is the single public entry point and terminates TLS.

4

Understand the security model

Upstream Yuvomi guides the first person who opens a new instance through the setup wizard that creates the admin account. On a VM with a public IP that is a real risk, so SecureAnyCloud removes it in two independent ways.

First, yuvomi-postboot.service claims the admin account itself, over the loopback port, with a password generated for this VM. Yuvomi's own setup endpoint then returns 404 forever in production once a user exists. The application's code enforces this, not a configuration flag.

Second, host nginx, the only public listener, does not start until the admin exists. It is gated on a bootstrap-ready marker that the post-boot service creates only after the admin exists. Port 443 is therefore closed for the whole bootstrap window.

The session signing secret and the database encryption key are also generated on first boot, before the stack can start. The upstream sample values (REPLACE_WITH_A_LONG_RANDOM_STRING, REPLACE_WITH_A_STRONG_ENCRYPTION_KEY) therefore never exist on your VM. A start-up guard refuses to launch the application if either secret is empty, too short or still a sample value. The database is encrypted at rest with the per-VM key.

Check the listening ports:

ss -tln | grep -E ':(443|3000) ' | awk '{print $1, $4}'
LISTEN 127.0.0.1:3000 LISTEN 0.0.0.0:443 LISTEN [::]:443

The setup wizard is closed, and authenticated data is not readable anonymously:

curl -sk -o /dev/null -w 'setup wizard (after admin claimed) -> %{http_code}\n' -X POST https://127.0.0.1/api/v1/auth/setup -H 'Content-Type: application/json' --data '{"username":"probe","display_name":"probe","password":"probe-should-never-work"}'
curl -sk -o /dev/null -w 'authenticated API (anonymous) -> %{http_code}\n' https://127.0.0.1/api/v1/auth/me
setup wizard (after admin claimed) -> 404 authenticated API (anonymous) -> 401

The on-disk database is encrypted at rest, so its header is not the plaintext SQLite marker. Check the header:

sudo head -c 16 /var/lib/yuvomi/data/yuvomi.db | grep -qa "SQLite format 3" && echo "plaintext" || echo "encrypted (no plaintext SQLite header)"
encrypted (no plaintext SQLite header)
5

Verify the end-to-end round trip

The image ships a prover that exercises the whole security model through the public front door. It confirms that the app answers, the setup wizard is closed, and a wrong password is rejected. It also confirms that the per-instance admin password logs in, issues a session, and creates and reads back a real task.

sudo /usr/local/sbin/yuvomi-roundtrip.sh
6

Sign in to the web app

Open https://<vm-ip>/ in your browser and sign in with the YUVOMI_USERNAME and YUVOMI_PASSWORD from the credentials file.

The image uses a per-VM self-signed certificate, so your browser shows a certificate warning the first time. Accept the warning, or install your own certificate at /etc/ssl/yuvomi/.

Once you are signed in, the dashboard is the home view. It gathers the household's day at a glance, with upcoming tasks and events, shopping lists, meals and more. The module navigation runs down the side, so you can open tasks, the calendar, shopping, meals, budget and contacts.

Choose Tasks to see and manage the household's shared to-do list. Each task can be assigned to a family member and given a due date, a priority and a category. Chores and jobs are then shared out and tracked rather than forgotten.

The Calendar brings the family's events together in one shared month view. Appointments, activities and reminders for everyone in the household are visible in one place.

Adding household members

There is no open self-registration on this image, so nobody can create an account on your instance.

To add a family member, sign in as the admin, open Settings, and invite them there. Each person gets their own login and sees the household's shared tasks, calendar and lists according to what is shared with them.

Using your own domain

On first boot the instance sets its own address, BASE_URL, to https://<vm-ip>, and generates a self-signed certificate for that address.

To reach the VM by a DNS name instead of its IP address, point a hostname at the VM. Then set BASE_URL in /opt/yuvomi/.env to that URL, for example https://yuvomi.example.com. Install a certificate for that name at /etc/ssl/yuvomi/yuvomi.crt and /etc/ssl/yuvomi/yuvomi.key, and restart the service:

sudo systemctl restart yuvomi

Repeat these steps if the VM's public IP changes, for example after a deallocate and start.

Managing the service

View the application logs and restart the stack:

# view recent application logs
sudo docker compose -f /opt/yuvomi/docker-compose.yml logs --tail 50 yuvomi
# restart the stack
sudo systemctl restart yuvomi

The upstream licence text for the shipped version is recorded on the VM at /usr/share/doc/yuvomi/, alongside a note on the pinned source that it was built from.

Support

SecureAnyCloud provides 24/7 support with a guaranteed 24-hour response SLA. For help with this image, email sales@secureanycloud.com.

Deploy on Azure

Launch Yuvomi 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