Returning to the original state
This page resets a FerroEHR instance to the state its release shipped in: the configuration the release ships, and an empty database carrying the schema that release’s migrations create. Nothing else survives a reset. EHRs, compositions, templates, parties, the party-to-EHR map, the audit trail and the instance id the usage report sends are all gone, and the next boot starts as a fresh install.
Before you reset
Warning
A reset deletes the access log along with the records it describes. If the instance has ever held real personal data, the audit trail is subject to the retention floor of every jurisdiction you operate in (three years in every EU Member State, five in the Netherlands, one in Switzerland; see Audit), and your duty to keep it does not end when the instance does. Take a backup of every domain first, the audit trail included (Backup and point-in-time recovery), and keep it for that horizon.
A reset does not reach anything outside the instance. Your logical dumps, WAL archives, volume snapshots, log collector and any external Audit Record Repository still hold what they held. Deleting those is a separate decision with the same retention duties. To take the instance out of service for good instead of starting it again, follow Decommissioning.
The reset has two halves, and you need both:
- Configuration: the server reads its built-in defaults, then a
ferroehr.toml, thenFERROEHR__…environment variables, then--set(Configuration reference). The original state is the release’s own file and no overrides. - Database: drop the database and let the release’s migrations build it again. Drop the whole database, never single schemas (Recovering a partially wiped database explains why).
The deployment_profile the release ships is sandbox, so a reset instance
says on its boot banner and on GET /ferroehr/rest/status that it must not
hold real patient data. Set deployment_profile = "production" again before
it does.
Docker Compose
The quickstart keeps the database in the named volume ferroehr-pgdata (and,
with the s3 profile, multimedia in ferroehr-seaweedfs), and its server
configuration inline in docker-compose.yml.
-
Stop the stack and delete its volumes:
docker compose down --volumes--volumesremoves the named volumes the file declares (docker compose down). Run it with the same-foverlay files and--profileflags you started the stack with, so it finds every service. -
Restore the configuration. Replace
docker-compose.ymlwith the copy attached to your release on GitHub Releases, and remove everyFERROEHR__…,DATABASE_URLandRUST_LOGvariable you set, from your shell and from any.envfile next to the compose file:env | grep -E '^(FERROEHR__|DATABASE_URL=|RUST_LOG=)' # expect no output -
Start it again:
docker compose up -d --waitThe database image provisions the domain roles on the empty volume, and the server applies its migrations at boot.
-
Read the result back. The effective configuration should be the file’s and nothing else:
docker compose exec ferroehr /usr/local/bin/ferroehr config check
Kubernetes and Helm
The chart deploys no database, so the two halves are separate operations.
-
Remove the release, so no pod holds a connection:
helm uninstall ferroehr --namespace ferroehrThis keeps the Secrets and PersistentVolumeClaims you created yourself, such as the DSN Secret and the backup claims.
-
Drop and recreate the database, as a role that may (the bootstrap superuser or the database owner), connected to a different database:
DROP DATABASE ferroehr WITH (FORCE); CREATE DATABASE ferroehr OWNER ferroehr;WITH (FORCE)terminates the sessions still connected (DROP DATABASE). Use the owner your deployment provisioned the database with. If[storage.party],[storage.linkage]or[storage.audit]name databases of their own, drop and recreate each of those too. The domain roles are cluster-wide objects, so they survive the drop, and the migrations reuse them. -
Install the chart again with only the values every deployment must supply (the DSN Secret and an authentication mechanism), and none of your other overrides:
helm install ferroehr oci://ghcr.io/ferrohealth/charts/ferroehr \ --version <your chart version> \ --namespace ferroehr \ -f minimal-values.yamlThe schema is applied at boot (
config.db.migrate: apply, the chart default), or by the migration Job when you enabled it.
The Kubernetes deployment probes run these three steps against a real cluster: the release is removed and the DSN Secret survives, the database is dropped and recreated by the bootstrap superuser, and the reinstalled release migrates the empty database and no longer finds an EHR written before the reset.
A single binary
- Stop the server.
- Drop and recreate the database as in step 2 of the Kubernetes procedure.
- Restore the configuration: replace your
ferroehr.tomlwithferroehr config default > ferroehr.toml(or delete it, which leaves the built-in defaults), and unset everyFERROEHR__…,DATABASE_URLandRUST_LOGvariable except the database DSN. - Prepare the schema with
ferroehr db migrate, or start the server with the defaultdb.migrate = "apply". - Check the effective configuration with
ferroehr config check.
How the procedure is tested
The deployment probe harness (scripts/deploy-probe.sh, its original_state
family) runs the Docker Compose procedure above. It writes an EHR, resets the
stack as steps 1 to 3 describe, and checks that the volume was deleted, that
the EHR is gone, and that the server reports the shipped configuration. The
Kubernetes and single-binary procedures are not exercised by any probe.