Maintenance, backups and restore
What to preserve
| State | Backup considerations |
|---|---|
| Selected stack/branch/image digests | Record a coherent release baseline alongside configuration |
hrsdk_configs and local modifications |
Include calibrated motor/assembly settings, saved node overrides, performances, character/world content and assets |
Operator .hrsdk state |
Environment, manifests, generated DDS profile and secret files; protect credentials separately |
| Console configuration/state | /etc/hr-system-console, /var/lib/hr-system-console, selected operator/service configuration |
| Runtime volumes | Identify actual Compose volumes for HR runtime, Redis and enabled databases |
| Face store and recordings | Preserve only according to the deployment's data-retention/access policy |
| Voice licenses/models | Retain installation/version metadata and required licensed artifacts |
Do not publish backups into the documentation webroot. Backups containing credentials or personal data need access control and appropriate encryption.
Inventory before changing anything
hr version
hr stack show CONFIGURED_STACK_VERSION
docker volume ls
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
systemctl cat hrsdk.service
df -h
Inspect bind mounts and volume names using the selected project/configuration. Avoid dumping full rendered Compose or environment into shared logs: interpolation can reveal secrets.
Consistent backup procedure
- Record release/configuration identifiers, date and operator.
- Finish or stop current performances/conversation sessions; stop state writers as appropriate.
- Back up configuration and saved overrides, preserving file ownership/mode.
- Use engine-consistent database backups for enabled MySQL/MongoDB/Redis state. Select the installed engine's approved backup method and credentials; a live raw volume copy is not automatically consistent.
- Back up runtime volumes after quiescing writers if using filesystem snapshots.
- Store checksums and a manifest of included paths/versions.
- Restore a sample to an isolated environment and verify it before relying on the backup.
Exact database commands depend on the installed image/version and credential arrangement. Discover those from the selected manifest/deployment; do not guess a root password from example configuration.
Restore
Prepare compatible host/runtime versions, stop writers, restore files and data to the intended locations, restore ownership/permissions, and reinstate the recorded stack/configuration. Validate database health and configuration loading before starting robot control. Test interfaces first, then deliberate hardware acceptance.
A restored Redis runtime can conflict with intentionally rebuilt bootstrap state. Determine whether the deployment expects a clean bootstrap or restored live state; preserve the source/saved configuration as the durable baseline. Do not merge arbitrary runtime snapshots across robot identities.
Disk and image management
Inspect image and volume usage before cleanup. Remove only confirmed unused images/releases after retaining rollback artifacts. Do not use volume-pruning or hr stop --volumes as generic disk cleanup. Check ASR archive retention, generated TTS files, model caches, container logs and Unity build caches separately.
ASR archives have application retention behavior; validate it before adding competing cleanup jobs. TensorRT engines can be regenerated for a platform but should retain model/platform metadata. Voice licenses may be irreplaceable without provider access.
Credentials and remote support
Update credentials through the designated console/setup/secret workflow and verify provider access. Preserve file modes and avoid logging values. Review RustDesk/remote tunnel configuration when transferring a robot to a new network or operator.
Evidence: current Compose mounts/volumes, console configuration/setup/tasks/services, CLI state constants, ASR recording code and configuration backend. Backup/restore procedures require deployment-specific engine verification before use on production data.
Concrete file and volume backup templates
Set absolute paths and identifiers after inspecting the actual deployment. The following templates create backups; they do not change robot configuration. Stop/quiesce the intended writers before a filesystem snapshot.
export BACKUP_DIR='/ABSOLUTE/PRIVATE/BACKUP_DIRECTORY'
export CONFIG_DIR='/ABSOLUTE/hrsdk_configs'
install -d -m 700 "$BACKUP_DIR"
tar --acls --xattrs -czf "$BACKUP_DIR/configuration.tar.gz" \
-C "$(dirname "$CONFIG_DIR")" "$(basename "$CONFIG_DIR")"
sha256sum "$BACKUP_DIR/configuration.tar.gz" > "$BACKUP_DIR/configuration.tar.gz.sha256"
This includes the selected configuration tree, including local files. Review its contents privately; it can include secrets/media. For a stopped named volume, use a trusted already-approved helper image with tar and mount the volume read-only:
export VOLUME_NAME='EXACT_EXISTING_VOLUME'
export BACKUP_IMAGE='APPROVED_IMAGE_WITH_TAR'
docker run --rm --network none \
--mount "type=volume,source=$VOLUME_NAME,target=/source,readonly" \
--mount "type=bind,source=$BACKUP_DIR,target=/backup" \
"$BACKUP_IMAGE" tar -czf /backup/runtime-volume.tar.gz -C /source .
Validate the volume exists before this command: a mistyped volume name can create an empty volume. Use unique filenames for multiple volumes. This snapshot is appropriate only after stopping their writers; it is not a live database consistency mechanism.
For an enabled MySQL container using the current image's environment conventions, an engine-level template is:
export MYSQL_CONTAINER='EXACT_RUNNING_MYSQL_CONTAINER'
docker exec "$MYSQL_CONTAINER" sh -c \
'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" exec mysqldump --user=root --single-transaction --routines --events "$MYSQL_DATABASE"' \
> "$BACKUP_DIR/conversations.sql"
Verify the selected image provides the tool and expected environment. --single-transaction does not make nontransactional tables consistent; quiesce their writers. Test restore into a separate compatible database and inspect exit status/output before accepting a backup. Do not log the environment or password.
Isolated restore template
For a new, explicitly selected restore volume, use the same trusted helper image and private backup mount to extract into /target. Confirm the destination is an isolated empty volume, not the running production volume:
export RESTORE_VOLUME='EXPLICIT_ISOLATED_RESTORE_VOLUME'
docker volume create "$RESTORE_VOLUME"
docker run --rm --network none \
--mount "type=volume,source=$RESTORE_VOLUME,target=/target" \
--mount "type=bind,source=$BACKUP_DIR,target=/backup,readonly" \
"$BACKUP_IMAGE" tar -xzf /backup/runtime-volume.tar.gz -C /target
Inspect restored ownership/content and start a compatible isolated service for validation. Switching production volumes is a separate, deliberate lifecycle change after validation; do not mount the same writable database data into two running instances.