A collection of practical advice for running the CloudSOE OpenMRS image in production, on either cloud.

Back up the database volume

The patient database lives in a Docker named volume. Dump it with the rotated credentials from /opt/openmrs/.env:

cd /opt/openmrs
DB_PASS=$(sudo grep '^OMRS_DB_PASSWORD=' .env | cut -d= -f2)
sudo docker compose exec db mysqldump -uopenmrs -p"$DB_PASS" openmrs \
  | gzip > /home/$(whoami)/openmrs-db-$(date +%F).sql.gz

Ship the dump off the instance — encrypted, and to storage that meets your regulatory requirements; this is patient data. Cloud-level disk snapshots capture the Docker volumes too and are a good complement, but SQL dumps restore faster and across instance types.

Keep things updated

  • OS security updates come from Ubuntu’s repositories: sudo apt update && sudo apt upgrade on your own schedule.
  • The stack is pinned to the OpenMRS release that shipped in the image (the TAG line in /opt/openmrs/.env). Upgrading OpenMRS in place means changing that tag and letting the backend migrate the database — take a full backup first and follow the OpenMRS release notes.
  • New CloudSOE image versions are published to the marketplaces — for major moves, launch a fresh instance and restore your backup rather than upgrading in place.

Resource sizing

Four containers (gateway, frontend, backend, MySQL) want real memory: 8 GB RAM is the sensible floor (t3.large on AWS, Standard_D2as_v4 on Azure). If the backend restarts under load or htop shows swapping, step up a size. Keep an eye on the 100 GB disk with df -h — container images and database growth both land on it.

Security hardening

The image rotates every baked credential — MySQL openmrs and root passwords, and the OpenMRS admin password — on first boot. On top of that:

  • Change the rotated admin password after first login, and create named per-user accounts in the legacy admin UI (/openmrs) — don’t share admin.
  • Put TLS in front before real use — see the configuration guide; port 80 is plain HTTP.
  • Restrict port 80 in your security group / NSG to your clinic’s network, VPN or load balancer where practical.
  • The demo content baked into the reference application is sample data — clear out demo patients before entering real ones.

Troubleshooting first boot

The progress meter (openmrs-bootstrap-status, shown automatically at login) reads a status file written by the first-boot service. If it stalls or reports a failure:

systemctl status openmrs-firstboot
journalctl -u openmrs-firstboot --no-pager
cd /opt/openmrs && sudo docker compose ps

The script is safe to re-run: it retries on the next boot if its completion marker (/var/lib/openmrs-firstboot.done) was never written, and generated secrets are reused rather than regenerated. A manual retry is just:

sudo systemctl restart openmrs-firstboot

If the admin password rotation failed

The credentials file tells the truth: if the automatic reset failed, it records the default Admin123 with a warning. Change it immediately in the UI (log in at /openmrs, then My Profile → Change Login Info) and never leave the default on an internet-facing instance.

The login pages 404 or refuse connections

First boot takes about five minutes — the gateway answers before the backend is ready, so early requests can 502/504. Wait for the meter to reach 100%, then check from your own machine (an Azure VM often cannot reach its own public IP from inside):

curl -sI http://<public-ip>/openmrs/ws/rest/v1/session

The MOTD shows the wrong IP

The login banner captures the public IP at first boot. If you later attach a new Elastic IP / public IP, the banner will be stale (the system itself is unaffected). Edit /etc/motd to update it.