BHIMA on Ubuntu 24.04 on Azure User Guide
Overview
BHIMA (Basic Hospital Information Management Application) is an open-source hospital information system built for health facilities in low-resource settings. It pairs a full double-entry accounting ledger with the daily operations of a clinic or hospital: patient registration and billing, debtors and cash management, medical stock and inventory across depots, employees and payroll, and the financial and operational reports a facility reports on. The cloudimg image installs BHIMA 1.39 from the official upstream release alongside Node.js 24 LTS, MySQL 8, and Redis, all reverse-proxied by nginx and wired together for predictable single-VM behaviour.
What is included:
- BHIMA 1.39.0 (the official upstream release build) at
/opt/bhima/bin, run by thebhimasystem user - Node.js 24 LTS from NodeSource
- MySQL 8 from Ubuntu 24.04 main, tuned with BHIMA's required
sql_mode(STRICT_ALL_TABLES,NO_UNSIGNED_SUBTRACTION) - Redis from Ubuntu 24.04 main as the express-session store
- nginx reverse-proxying TCP 80 to the app on
127.0.0.1:8080 bhima.service(Node app) andbhima-firstboot.service(one-shot per-VM credential rotation)- A populated demonstration dataset (Test Enterprise, chart of accounts, patients, and posted transactions) so every module has content on first boot
- Per-VM admin, database, and session secrets generated at first boot — the upstream
superuser/superuserdemo login is rejected - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key, a VNet + subnet, and a Network Security Group that exposes TCP 22 to your management CIDR and TCP 80 to your users (or to your CDN / Front Door / Application Gateway with TLS terminated upstream). Standard_B2s (2 vCPU, 4 GB RAM) is comfortable for a single-facility deployment. For busy multi-department hospitals, move to a D-series VM.
Step 1: Deploy from the cloudimg gallery
In the Azure Portal, create a new VM from cloudimgGallery/bhima-ubuntu-24-04, choose Standard_B2s, attach your SSH key, and place the VM in a subnet whose NSG allows inbound TCP 22 (SSH) and TCP 80 (HTTP). Wait for provisioning to finish, then copy the public IP from the VM Overview blade.
Step 2: SSH to the VM
ssh azureuser@<vm-ip>
Step 3: Confirm the stack is running
systemctl is-active bhima.service mysql.service redis-server.service nginx.service
node --version
ss -ltn | grep -E ':(80|8080|3306|6379) '
curl -sI http://127.0.0.1/ | head -4
Expected output:
active
active
active
active
v24.19.0
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
LISTEN 0 511 127.0.0.1:6379 0.0.0.0:*
LISTEN 0 511 *:8080 *:*
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Port 80 is nginx (public), 8080 is the BHIMA Node process, 3306 is MySQL and 6379 is Redis (both bound to localhost).

Step 4: Explore the demonstration dataset
The image ships a populated demonstration dataset so you can explore every module immediately rather than staring at an empty install. Confirm the row counts:
RP=$(sudo grep '^MYSQL_ROOT_PASSWORD=' /stage/scripts/bhima-credentials.log | cut -d= -f2-)
sudo mysql -uroot -p"$RP" bhima -N -e "SELECT 'enterprises', COUNT(*) FROM enterprise
UNION ALL SELECT 'projects', COUNT(*) FROM project
UNION ALL SELECT 'users', COUNT(*) FROM user
UNION ALL SELECT 'accounts', COUNT(*) FROM account
UNION ALL SELECT 'patients', COUNT(*) FROM patient
UNION ALL SELECT 'journal rows', COUNT(*) FROM posting_journal;"
Expected output:
enterprises 1
projects 3
users 4
accounts 307
patients 265
journal rows 52

Step 5: Read the per-VM credentials
Each VM generates its own admin, database, and session secrets at first boot and writes them to a root-only file:
sudo cat /stage/scripts/bhima-credentials.log
The file is mode 0600, root-owned. It contains BHIMA_ADMIN_USERNAME / BHIMA_ADMIN_PASSWORD (the application administrator), BHIMA_DB_PASSWORD, MYSQL_ROOT_PASSWORD, and the URL for this VM. Copy these into your secrets manager and keep the file off-VM.

Step 6: Verify the credential rotation
The image is hardened so no two VMs share a login: the per-VM superuser password authenticates, and the upstream superuser/superuser demo default is rejected.
AP=$(sudo grep '^BHIMA_ADMIN_PASSWORD=' /stage/scripts/bhima-credentials.log | cut -d= -f2-)
curl -s -o /dev/null -w 'per-VM password -> HTTP %{http_code}\n' -X POST \
-H 'Content-Type: application/json' \
--data "{\"username\":\"superuser\",\"password\":\"$AP\",\"project\":1}" http://127.0.0.1/auth/login
curl -s -o /dev/null -w 'upstream default -> HTTP %{http_code}\n' -X POST \
-H 'Content-Type: application/json' \
--data '{"username":"superuser","password":"superuser","project":1}' http://127.0.0.1/auth/login
Expected output:
per-VM password -> HTTP 200
upstream default -> HTTP 401

Step 7: Sign in
Browse to http://<vm-ip>/ from your laptop. BHIMA shows its sign-in form: enter the username superuser, the BHIMA_ADMIN_PASSWORD from Step 5, and choose the project Test Project A. (Use the language dropdown at the top of the form to switch between English and French.)

Step 8: The enterprise dashboard
After signing in, BHIMA lands you on the enterprise dashboard, showing the active project, the enterprise currency and exchange rates, and the current fiscal year.

Step 9: Chart of accounts
Open Finance → Account Management to see the full chart of accounts that ships with the demonstration dataset — a structured, multi-level account tree you can edit, extend, or replace with your own.

Step 10: The posting journal
Open Finance → Journal to see BHIMA's double-entry accounting in action: every transaction is recorded with matching debit and credit lines against real accounts, and the journal totals balance.

Step 11: Components
| Component | Path |
|---|---|
| BHIMA app | /opt/bhima/bin/ |
| App version file | /opt/bhima/package.json |
| Runtime config | /opt/bhima/bin/.env |
| Node.js 24 LTS | /usr/bin/node |
| systemd unit (app) | /etc/systemd/system/bhima.service |
| systemd unit (firstboot) | /etc/systemd/system/bhima-firstboot.service |
| Firstboot script | /usr/local/sbin/bhima-firstboot.sh |
| Firstboot sentinel | /var/lib/cloudimg/bhima-firstboot.done |
| MySQL config | /etc/mysql/mysql.conf.d/zz-bhima.cnf |
| MySQL data | /var/lib/mysql/ |
| nginx site | /etc/nginx/sites-enabled/bhima-cloudimg |
| Credentials | /stage/scripts/bhima-credentials.log (mode 0600 root:root) |
Step 12: Production hardening
- Front the VM with TLS: terminate HTTPS at Azure Application Gateway or Front Door, or run
certbot --nginxon the VM after pointing your DNS at the public IP. - The demonstration dataset: the shipped
Test Enterprisedata is for evaluation. When you are ready to run a real facility, create your own enterprise, fiscal year and chart of accounts inside BHIMA — see the upstream documentation at https://docs.bhi.ma for starting a clean production database. - Rotate or add users: sign in as
superuser, then create your own named administrator and staff accounts under Administration → Users and disable the demo accounts. - Back up MySQL: schedule
mysqldump bhimaand copy/opt/bhima/bin/client/uploadto Azure Blob Storage or AWS S3. - Restrict the NSG: lock TCP 22 to your management CIDR and front TCP 80/443 with your CDN only.
- Patch monthly:
sudo apt-get update && sudo apt-get -y upgrade && sudo reboot. Watch https://github.com/Third-Culture-Software/bhima/releases for BHIMA releases.
Licensing
BHIMA is licensed under the GNU General Public License v2.0 (GPL-2.0) — free to use. cloudimg provides commercial support separately. support@cloudimg.co.uk.