GNU Health on Ubuntu 24.04 on Azure User Guide
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
healthTryton module) on Tryton 7.0 LTS, installed in a dedicated Python virtual environment and running as thegnu-healthgunicorn systemd service - The Tryton
saoweb 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
/healthzendpoint 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) andnginx.serviceas 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.

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).

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.

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.

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.

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.

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.

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.

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(mode0600 root:root). Change it from the web client under theadminuser's preferences, or reset it from the command line by re-running trytond-admin against theghealthdatabase 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
corssetting under[web]in/opt/gnuhealth/his-50/etc/trytond.confandsudo 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:8000in/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
ghealthPostgreSQL database on loopback. Back it up withsudo -u gnuhealth pg_dump ghealth > ghealth.sql. Thegnuhealthrole 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-admintooling against theghealthdatabase; restart withsudo systemctl restart gnu-healthafter 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.