Applications Azure

Baby Buddy on Ubuntu 24.04 on Azure User Guide

| Product: Baby Buddy on Ubuntu 24.04 LTS on Azure

Overview

Baby Buddy is a popular open source, self hosted web application that helps caregivers track a baby's daily activities and growth. It records feedings, sleep, diaper changes, tummy time, pumping, temperature and measurements, and presents them as an at a glance dashboard of cards, a chronological timeline and a set of reporting charts. The cloudimg image installs Baby Buddy as a Django 5.2 application in a dedicated Python virtual environment, served by gunicorn and reverse proxied behind nginx, then locks it down for a marketplace appliance. gunicorn is bound to loopback 127.0.0.1:8000 and never exposed directly; nginx on port 80 is the only way in, plus an unauthenticated /healthz endpoint for load balancer probes. Baby Buddy has its own built in authentication, so this image is secure by default in a Django specific way: the well known default admin/admin account is removed at build time, and on the first boot of every VM a fresh Django secret key is generated and the administrator account is created with a unique, randomly generated password written to a root only file. A populated demo child with several weeks of sample entries ships so the dashboard, timeline and charts are non empty out of the box; you delete it and add your own child whenever you are ready. Backed by 24/7 cloudimg support.

What is included:

  • Baby Buddy 2.9.2 installed in a dedicated Python virtual environment and running as the babybuddy gunicorn systemd service
  • The full Baby Buddy web application on :80, fronted by nginx with gunicorn bound to loopback only
  • Built in Django authentication with the default admin/admin account removed and a unique administrator password generated on first boot
  • A per VM Django secret key generated on first boot, never baked into the image
  • Host settings configured so sign in works on the public IP address or a custom domain, with no baked in hostname
  • A populated demo child with roughly a month of feedings, sleep, diaper changes, tummy time and pumping so the dashboard and charts are non empty
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • babybuddy.service (gunicorn) + nginx.service as systemd units, enabled and active
  • 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 comfortable starting point; Baby Buddy is light on resources. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web application, and 443/tcp if you add TLS. Baby Buddy serves plain HTTP on port 80; for production use, terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Baby Buddy 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 baby-buddy \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open port 80 to your network so you can reach the web application:

az vm open-port --resource-group <your-rg> --name baby-buddy --port 80

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active babybuddy.service nginx.service

Both report active. Baby Buddy runs under gunicorn on the loopback address 127.0.0.1:8000; nginx fronts it on port 80. The application is never bound to a public interface, so nginx is the only way in.

The babybuddy gunicorn service and nginx reporting active, gunicorn listening on loopback 127.0.0.1:8000, and nginx listening on port 80

Step 5 - Retrieve your admin password

Baby Buddy uses its own Django login. The username is admin and a unique password is generated on the first boot of your VM and written to a root only file:

sudo cat /root/babybuddy-credentials.txt

This file contains BABYBUDDY_USERNAME, BABYBUDDY_PASSWORD and the BABYBUDDY_URL to open in a browser. The file is mode 0600 root:root, and the default admin/admin account that Baby Buddy normally ships is removed at build time, so no shared or default credential exists in the image. Store the password somewhere safe and change it after first sign in (see Maintenance).

The per VM credentials file with the generated admin username, URL and a masked password, its 0600 root only permissions, and gunicorn bound to loopback

Step 6 - Confirm the health endpoint

nginx serves an unauthenticated health endpoint for load balancers and probes:

curl -s http://localhost/healthz

It returns ok. This endpoint never requires authentication, so it is safe for an Azure Load Balancer health probe.

Step 7 - Confirm authentication is required

Because Baby Buddy manages its own login, the dashboard cannot be reached without signing in. An unauthenticated request to the dashboard returns HTTP 302 and redirects to the sign in page, while the health endpoint stays open:

echo "health   : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/healthz)"
echo "dashboard: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/dashboard/)"

It prints health : 200 and dashboard : 302. The dashboard, timeline and every tracking view require the per VM admin password; only the health endpoint is open. gunicorn is bound to loopback and nginx is the only way in.

The health endpoint returning 200 unauthenticated, the dashboard returning 302 to the sign in page without a session, and the full per VM login round trip proof passing

Step 8 - Confirm the installed version and components

Baby Buddy runs on Django in a dedicated virtual environment. Confirm the framework version and that the core components are in place:

/opt/babybuddy/venv/bin/python -c "import django; print('Django', django.get_version())"
sudo ls /opt/babybuddy/venv/bin/gunicorn /opt/babybuddy/app/data/db.sqlite3 /etc/systemd/system/babybuddy.service

It reports Django 5.2 and lists the gunicorn binary, the SQLite database on the OS disk and the systemd unit. The image ships Baby Buddy 2.9.2 with a populated demo child so the dashboard is non empty on first boot.

The Django and Baby Buddy versions, the demo data counts of children, feedings, sleep, diaper changes and tummy time, and the Baby Buddy components installed by this image

Step 9 - Sign in

Browse to http://<vm-public-ip>/. Baby Buddy shows its sign in page. Enter admin and the password from Step 5.

The Baby Buddy sign in page with the username and password fields

After signing in you land on the dashboard for the demo child. It is a grid of at a glance cards - last feeding, last sleep, last diaper change, last pumping, recent activity counts and rolling statistics - all populated from the sample entries that ship with the image.

The Baby Buddy dashboard for the demo child showing populated cards for last feeding, last sleep, last diaper change, last pumping and rolling statistics

Step 10 - Explore the timeline

Open a child from the Children menu, or Timeline from the top navigation, to see the chronological record of everything that has been tracked - feedings, sleep, diaper changes, tummy time and notes - with timestamps and quick edit links. This is where you review and correct individual entries.

The Baby Buddy timeline for the demo child listing tracked activities and notes with timestamps and edit links

Step 11 - View the reporting charts

Open a child and choose Reports to reach the charting views. Baby Buddy renders interactive charts for feeding amounts and types, sleep patterns, diaper change frequency, tummy time and growth (weight, height and head circumference). The Feeding Amounts report, for example, breaks daily intake down by type across the tracked period.

The Baby Buddy Feeding Amounts report showing an interactive stacked bar chart of daily feeding amounts by type for the demo child

Step 12 - Add your own child and remove the demo data

The image ships a populated demo child so the dashboard is not empty. When you are ready, add your own child from the Children menu (Children -> Add Child), then start tracking from the Activities and Measurements menus or with the quick add buttons on the dashboard. To remove the demo child once you have your own, open it from the Children list and choose Delete - this removes the demo child and all of its sample entries.

Maintenance

  • Password: the administrator password is generated on first boot and stored in /root/babybuddy-credentials.txt (mode 0600 root:root). Change it from the web interface under the admin user menu -> Settings, or by resetting it from the command line: cd /opt/babybuddy/app && sudo runuser -u babybuddy -- env DJANGO_SETTINGS_MODULE=babybuddy.settings.production SECRET_KEY=$(grep '^SECRET_KEY=' /opt/babybuddy/babybuddy.env | cut -d= -f2-) /opt/babybuddy/venv/bin/python manage.py changepassword admin.
  • Add users: invite additional caregivers from Users in the top navigation, or create one on the command line with Baby Buddy's createuser management command.
  • Restrict access: Baby Buddy serves plain HTTP on port 80. For production, restrict access to trusted IP ranges in your Network Security Group, and front it with TLS (for example certbot with your own domain) terminating on :443. Add your domain to CSRF_TRUSTED_ORIGINS and ALLOWED_HOSTS in /opt/babybuddy/babybuddy.env and sudo systemctl restart babybuddy if you use a custom hostname.
  • Loopback binding: gunicorn is bound to 127.0.0.1:8000 in /etc/systemd/system/babybuddy.service, so nginx is the only path in. Keep it that way - do not change the bind address to a public interface.
  • Database: the SQLite database lives at /opt/babybuddy/app/data/db.sqlite3 (owned babybuddy:babybuddy). Back it up by copying the file while the service is stopped, or use Baby Buddy's built in Import / Export under the Database menu.
  • Upgrades: Baby Buddy is installed from a pinned release into its virtual environment. To upgrade, replace the source under /opt/babybuddy/app, reinstall requirements with /opt/babybuddy/venv/bin/pip, run manage.py migrate and manage.py collectstatic, then sudo systemctl restart babybuddy.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.