Applications Azure

GNU Health on Ubuntu 24.04 on Azure User Guide

| Product: GNU Health on Ubuntu 24.04 LTS on Azure

Overview

GNU Health is a free and libre Hospital and Health Information System (HIS/HMIS) and an official GNU project. It provides electronic medical records, patient and health-professional management, health institutions, appointments and clinical evaluations, built on the mature Tryton application framework. The cloudimg image ships the GNU Health HIS 5.0 core installed in a dedicated Python virtual environment on Tryton 7.0 LTS, served by gunicorn and reverse proxied behind nginx, with a PostgreSQL database and the Tryton sao web client ready in the browser, 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, serving the web client's static assets directly and proxying the application's remote-procedure calls, plus an unauthenticated /healthz endpoint for load balancer probes. The image is secure by default: no database and no default login ship in the image at all. On the first boot of every VM a fresh, empty GNU Health database is initialised, the health information system modules are activated, and the administrator account is created with a unique, randomly generated password written to a root only file. Backed by 24/7 cloudimg support.

What is included:

  • GNU Health HIS 5.0 core (the health Tryton module) on Tryton 7.0 LTS, installed in a dedicated Python virtual environment and running as the gnu-health gunicorn systemd service
  • The Tryton sao web client on :80, fronted by nginx with the application server bound to loopback only
  • A PostgreSQL 16 database holding the health information system, created fresh on first boot with a per VM database
  • No default login and no shipped patient data: a fresh database is initialised on first boot and the administrator is created with a unique random password, never baked into the image
  • The application is gated on a first-boot bootstrap marker so it never starts before the fresh database and per-VM credential exist
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • A 4 GiB swap file so the system runs comfortably on a small instance
  • postgresql.service, gnu-health.service (gunicorn/trytond) and 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. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web client, and 443/tcp if you add TLS. GNU Health 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 GNU Health 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 gnu-health \
  --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 client:

az vm open-port --resource-group <your-rg> --name gnu-health --port 80

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active postgresql gnu-health nginx

All three report active. GNU Health runs under gunicorn on the loopback address 127.0.0.1:8000; nginx fronts it on port 80 and PostgreSQL is bound to loopback. The application is never bound to a public interface, so nginx is the only way in.

The postgresql, gnu-health gunicorn and nginx services reporting active, with trytond listening on loopback 127.0.0.1:8000 and nginx listening on port 80

Step 5 - Retrieve your admin password

GNU Health signs in with a Tryton user. 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/gnu-health-credentials.txt

This file contains GNUHEALTH_ADMIN_USER, GNUHEALTH_ADMIN_PASSWORD, the GNUHEALTH_DB database name to select at sign-in, and the GNUHEALTH_URL to open in a browser. The file is mode 0600 root:root, and no default account is ever created in the image, so no shared or default credential exists. Store the password somewhere safe and change it after first sign in (see Maintenance).

The first-boot init service enabled, the application gated on a bootstrap marker until the fresh database and per-VM admin password are created, and trytond bound to loopback only

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 the web client and the end-to-end round-trip

The Tryton web client is served on port 80, and the application server answers remote-procedure calls behind it. A helper on the image proves the full round-trip end to end - that the web client answers, that the per-VM admin password authenticates through the running server, that the GNU Health module is active, and that a health record can be created and read back:

echo "web client: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
sudo bash /usr/local/sbin/gnu-health-verify-login.sh

The web client returns 200 and the proof prints OK: the sao client loads, the per-VM admin password authenticates, the GNU Health health module is active, and a demonstration party record is created, read back and removed.

The web client returning 200, the health endpoint returning 200 unauthenticated, and the full per-VM login and GNU Health round-trip proof passing

Step 8 - Confirm the installed version and the GNU Health module

GNU Health runs on the Tryton framework in a dedicated virtual environment. Confirm the framework and GNU Health versions and that the health module is activated in the database:

/opt/gnuhealth/his-50/venv/bin/python -c "import trytond; print('trytond', trytond.__version__)"
/opt/gnuhealth/his-50/venv/bin/pip show gnuhealth | grep -E '^Name|^Version'

It reports trytond 7.0.x and GNU Health 5.0.x, confirming the GNU Health HIS core is installed and activated, so the health information system is ready on first boot.

The trytond and GNU Health versions, the health module active in the database, and the GNU Health components installed by this image

Step 9 - Sign in to the web client

Browse to http://<vm-public-ip>/. The Tryton web client loads; click the sign-in icon, enter the database name (ghealth), the user name admin and the password from Step 5. This is the browser interface to your health information system.

The GNU Health / Tryton web client sign-in dialog with the database and user name fields

Step 10 - The GNU Health desktop

After signing in you land on the GNU Health desktop, signed in as the Administrator. From here you reach the health information system menus - parties and patients, health professionals, institutions, appointments and evaluations, financial and administration - using the action search at the top left to open any view.

The logged-in GNU Health desktop with the Administrator session and the action search for opening any menu

Step 11 - Work with parties and patients

Open Parties from the action search. Parties are the people and organisations GNU Health manages - patients, health professionals, insurers and institutions all build on the party record. Open a party to see its demographics, and mark a person as a patient to create their clinical record.

The GNU Health Parties list, the records the health information system builds patients and health professionals on

Step 12 - Administration and users

Open Users from the action search under Administration to manage the accounts that can sign in to your health information system, assign roles and groups, and add the clinicians and staff for your institution.

The GNU Health administration Users list for managing accounts, roles and access to the health information system

Step 13 - Build your health information system

The image ships a fresh, empty GNU Health database, so you start from a clean installation with no demonstration patient data. Add your institution under the Health configuration, create health professionals and patients as parties, and activate the optional GNU Health packages you need (laboratory, imaging, inpatient, nursing, pediatrics and many more) with the GNU Health tooling. See the GNU Health documentation for configuring and extending your deployment.

Maintenance

  • Password: the administrator password is generated on first boot and stored in /root/gnu-health-credentials.txt (mode 0600 root:root). Change it from the web client under the admin user's preferences, or reset it from the command line by re-running trytond-admin against the ghealth database with a password file.
  • Custom domain / reverse proxy: GNU Health is reached directly on the public IP out of the box. If you front it with your own domain or an external reverse proxy, add that origin to the cors setting under [web] in /opt/gnuhealth/his-50/etc/trytond.conf and sudo systemctl restart gnu-health, so the web client's browser requests from that origin are accepted.
  • Restrict access and add TLS: GNU Health 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.
  • Loopback binding: gunicorn is bound to 127.0.0.1:8000 in /etc/systemd/system/gnu-health.service, so nginx is the only path in. Keep it that way - do not change the bind address to a public interface.
  • Database: the health information system lives in the ghealth PostgreSQL database on loopback. Back it up with sudo -u gnuhealth pg_dump ghealth > ghealth.sql. The gnuhealth role connects over the local socket with peer authentication, so no database password is stored on disk.
  • GNU Health packages and updates: additional GNU Health modules install into the virtual environment with pip and activate with the Tryton trytond-admin tooling against the ghealth database; restart with sudo systemctl restart gnu-health after changes.
  • 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.