Skip to main content
Version: 3.0 (next)

Backup & Migration

Move configuration between MaestroHub organizations. You export what you have built into a single .mhub.json bundle, then import that bundle wherever you need it: a different organization on the same installation, or a different installation entirely. The usual reason is promoting work from a test system to a live one.

Open the page from Admin > Maintain > Backup & Migration in the sidebar. The older /system-management/export-import address still works, so existing bookmarks and links keep going to the right place.

Files exported by 2.x cannot be imported into 3.0.0

3.0.0 replaced the export format. A file produced by any earlier release (its schemaVersion is the text "1.0.0") is refused at upload with an explanation, and there is no converter.

To move data off a 2.x instance: upgrade that instance to 3.0.0 first, export again from it, then import the new file. Keep the old file until you have the new one. Nothing in 3.0.0 can read it.

What a bundle is​

A bundle is a template, not a copy of your database rows. It describes what to build in the destination rather than naming things that exist in the source.

It contains connections, functions, topics, pipelines and dashboards. It does not contain:

  • historical readings or any other time-series data
  • users, roles or permissions
  • instance settings such as email or licensing
  • App Studio apps (coming soon, not part of release 3.0), which have their own backup, described at the bottom of this page

Two properties follow from being a template, and both matter in practice:

No source identity travels. There are no internal record identifiers, no timestamps, and nothing naming the instance that produced the file. Exporting the same selection twice produces byte-identical files, so a bundle checked into version control only changes when the configuration does.

Every namespace path is written with a placeholder. Instead of mHv1.0/production/line-1/temperature, the file stores mHv1.0/<org>/line-1/temperature. The <org> part is filled in with the destination you pick at import time. This is what lets one bundle be imported into several organizations, each binding to its own namespace, with no editing between.

A path that names some other organization outright, rather than using the placeholder, is refused before anything is written. That case is almost always a hand-edited file, and binding it would silently produce a path that looks correct but points at the wrong place.

Permissions​

ActionPermission
Export a bundle, browse the entity listdependencies:export
Export a bundle with connection credentialsdependencies:export_credentials
Preview an import, commit an importdependencies:import

The page itself is gated on dependencies:export.

dependencies:export_credentials is deliberately separate. An export without credentials is a template, safe to hand around; an export with them is the passwords themselves in a file, and this is the only place in MaestroHub where a decrypted secret leaves over HTTP. Organization.Admin holds both, so an org administrator's access is unchanged — the split exists so a custom role can be given configuration export without being given the secrets. Without it, the Include connection credentials box is shown disabled with that reason, and the server refuses the request even if the box is bypassed.

Importing checks dependencies:import in the destination organization, not only in the one you are working in. Picking a destination you hold no grant in is refused before anything about that organization is read.

Exporting​

Click Start export. Everything happens in one dialog.

Choosing what to include​

Everything in this organization is the default and needs no further input.

Specific entities shows the organization's contents grouped by kind, with a filter box for finding things by name. Tick what you want.

References are not added for you. If you export a pipeline, the connection it uses is not pulled in automatically. Tick both. The dialog warns you when a selection references something you have not included, so an inconsistent bundle is visible before you download it rather than after someone tries to import it.

Credentials​

Passwords, API keys and private keys are left out by default and replaced with a placeholder. The bundle still records which fields were omitted, so the import can ask for them.

Ticking Include connection credentials writes the real secrets into the file as readable text. The dialog says so, in place, whenever the box is ticked. The box needs the dependencies:export_credentials permission; without it the box is disabled and says why.

warning

A bundle exported with credentials is as sensitive as the passwords inside it. Store and transfer it accordingly, and prefer leaving them out when the file will be emailed, shared, or committed anywhere.

Whether an export carried credentials is recorded in the audit trail, so the question "did that file have live passwords in it?" is answerable after the fact.

Description​

An optional free-text note stored in the bundle and shown to whoever imports it. Leave it empty if you want byte-identical exports, since the text is part of the file.

Download​

Download bundle produces <organization-name>.mhub.json. If the button is disabled it says why, usually that nothing has been ticked yet.

Importing​

Click Start import. Three steps: upload, preview, result.

Step 1. Upload​

Choose the .mhub.json file and the destination organization.

The destination is never assumed. It does not default to the organization you are currently viewing, because importing into the wrong one is tedious to unpick. You would have to delete each entity by hand. Nothing is read from the file until both are set, and the button explains which one is still missing.

Step 2. Preview​

The preview is a plan. Nothing has been written yet, and committing applies exactly the plan shown.

It gives you:

  • Bundle summary. The description, the total entity count, the format version, and the destination namespace every path will bind to.
  • Per-kind counts. How many connections, functions, topics, pipelines and dashboards will be created, replaced, or left alone.
  • Bound paths. Before-and-after pairs showing <org> resolved to the destination, so you can confirm the binding is what you expected before committing.
  • Blocking problems, if any, each with what to do about it.
  • Name collisions, each with a choice (see below).
  • Missing credentials, if the bundle was exported without them.

Anything that cannot be fixed from this screen blocks the import and says so. The Import button is disabled until every collision has an answer and you have confirmed the entity count, and it explains which of those is still outstanding.

Name collisions​

When something in the bundle shares a name with something already in the destination, the import stops and asks. It never overwrites silently, and the default when a question goes unanswered is to refuse the whole import rather than guess.

ChoiceEffect
ReplaceOverwrite the destination entity with the version from the bundle.
Keep existingLeave the destination untouched and drop that entity from the import. References to it still resolve to what is already there.

Dashboard names are display labels, not identities, so a destination can legitimately hold two dashboards with the same name. Replace cannot be offered there — nothing may pick one of them by chance — and the preview says so, naming how many share the name. Keep existing still works: leaving them alone is answerable without knowing which one was meant, so one ambiguous dashboard does not make the rest of the bundle unimportable.

Re-importing a bundle into an organization that already has it collides on everything, which can run to hundreds of entries. Apply to all sets every collision at once; individual choices remain available for the cases that differ.

Rename is not implemented

The design allows for importing under a new name so both versions coexist, but this release does not offer it. Replace and Keep existing both work for every entity kind.

Credentials​

If the bundle was exported without secrets, the preview lists each connection that needs them and offers a field per missing value.

Filling them in stores them with the connection. Leaving a field blank is a legitimate choice, not a skipped step: the connection is created without that value, and you add it later from the Connections page. What never happens is the placeholder being stored as though it were the password. A connection with a placeholder for a password cannot authenticate, and the failure would surface far from the import that caused it.

Step 3. Result​

On success: how many entities landed, where, and the same per-kind breakdown as the preview, now describing what happened rather than what was planned.

On failure: what went wrong, and, importantly, whether anything stayed behind. A failed commit rolls back, but a rollback is not always able to undo everything (an in-place update cannot be reversed, and a compensating delete can itself fail). When entities did stay, the result screen names them so you can reconcile by hand. When the rollback was clean it says nothing was written, and that statement is trustworthy.

After importing​

Imported pipelines are disabled. They do not start on their own, and nothing they would publish is published until you enable each one from the Pipelines page. This is deliberate: a freshly imported pipeline points at connections you may not have finished setting up.

Check connections first, then enable pipelines.

History and auditing​

This page has no history tables. Every export and every import writes an audit record instead: who did it, when, to which organization, how many entities, and whether the export carried credentials. Query those from the Audit Trail rather than from this page.

App Studio backup​

Coming soon

App Studio is coming soon: it is in development and testing and is not part of release 3.0. This section describes it as it is being built.

The App Studio backup card at the bottom of the page is a different thing from the bundle wizards above it, and the two are not interchangeable.

Where a bundle is a portable template, an App Studio backup is an exact copy of one organization's App Studio: every app, its versions, checkpoints and documents, plus each app's git history. The database and the git data are captured together in a single .tar.gz so they cannot drift apart. Open edit sessions are not included, so anyone mid-edit when the backup ran will find that unsaved work missing after a restore.

Restoring refuses by default if the organization already has apps, so you cannot overwrite by accident. Replace everything deletes every existing app and its history first. Download a backup before choosing it.

Both controls need the app:backup permission, and the card only appears when App Studio is licensed.

File format​

The bundle is a single readable .mhub.json document:

  • schemaVersion. An integer, currently 2. An older or newer value is refused rather than guessed at.
  • manifest. The format dialect (org-placeholder-v1) and your description.
  • connections, functions, topics, pipelines, dashboards. The entity definitions.

Everything inside refers to everything else by name within the organization, never by internal identifier, which is what makes the same file usable in more than one place. Namespace paths carry the <org> placeholder described above.