Manage without HSI
HSI is a control panel over standard Linux tools, not a replacement for them. For
every area below, the underlying files and commands are the same ones you’d use if
HSI weren’t installed, so a stopped hsi service, a broken update, or a full
uninstall never leaves the server itself unmanageable.
This page intentionally doesn’t cover the file manager or the App Store: browsing
files is just the filesystem (ls, cp, standard permissions), and every app the
App Store installs is a normal container, covered under Docker below.
Docker
Section titled “Docker”Containers created through the App Store or the Containers app are ordinary Docker
containers under their configured name; nothing about them depends on HSI staying
up. Each app managed by HSI is a Docker Compose project under
/opt/containers/<name>/compose.yaml: the file is the source of truth, usable
without HSI:
docker ps -a # list containers, including stopped onesdocker logs -f <name>docker start|stop|restart <name>docker inspect <name> # ports, mounts, env, labels, everything HSI showed you
# Compose project (the file HSI generates/edits):docker compose -f /opt/containers/<name>/compose.yaml psdocker compose -f /opt/containers/<name>/compose.yaml up -ddocker compose -f /opt/containers/<name>/compose.yaml logs -fdocker compose -f /opt/containers/<name>/compose.yaml downx-hsi: keys in the compose file are HSI metadata (pinned URL, UI hints), safe
to ignore or delete.
Directories under /opt/containers whose names HSI cannot represent (spaces,
leading dot) are ignored by the app list; manage them with plain docker compose.
Samba (SMB shares)
Section titled “Samba (SMB shares)”HSI owns its own config file, /etc/nasui/samba/smb.conf, and points smbd at it
through a systemd drop-in (/etc/systemd/system/smbd.service.d/nasui.conf). The
Samba package’s own /etc/samba/smb.conf is never touched, so apt upgrade never
conflicts with it.
testparm -s /etc/nasui/samba/smb.conf # validate the config HSI generatedsmbstatus # who's connected, to which sharesystemctl restart smbd # apply a config change by handSamba’s user database is managed the normal way (smbpasswd); HSI keeps it in
sync when you change a password through the UI, but doesn’t replace it with its own
store.
pdbedit -L # list Samba accountssmbpasswd -x <username> # remove one, e.g. after disabling "Samba identity" # for a user in HSI, which stops syncing it but never # deletes it for youUsers (Linux/Samba identity)
Section titled “Users (Linux/Samba identity)”Every HSI user maps 1:1 to a Linux account by username (/sbin/nologin shell, no
shell/SSH access, it only exists to own files and back Samba). A Samba account is
provisioned for it too, unless “Samba identity” is turned off for that user
(Settings → Users → a user → Identity). HSI never invents its own separate
user/permission store for either: id <username>, getent passwd <username>, and
pdbedit -L are always the ground truth, and HSI’s Identity panel is a read-only
view over exactly those facts, not a cache that can drift from them.
id <username> # Linux uid/gid/groupsgetent passwd <username> # full Linux account recordRAID (mdadm)
Section titled “RAID (mdadm)”Arrays HSI creates are plain mdadm arrays. Their assembly config is written to
the standard location so they still auto-assemble on boot without HSI running.
cat /proc/mdstat # live array statemdadm --detail /dev/md0 # full detail on one arraycat /etc/mdadm/mdadm.conf # HSI adds one marked ARRAY line per array it createsEach volume HSI manages is also described in /etc/hsi/storage/, with its disks by
serial number: see Storage descriptions
to reassemble and mount it from that file.
Importing existing arrays and volume groups
Section titled “Importing existing arrays and volume groups”After a reinstall, or with disks moved from another machine, Storage > RAID lists arrays found in the disks’ superblocks that are not running, and Storage > LVM lists volume groups with no active volume. Importing never formats anything. By hand:
mdadm --examine --scan --verbose # arrays recorded on the disksmdadm --assemble /dev/md1 --uuid=<UUID> --scan # add --run to start it degradedlvs -o vg_name,lv_name,lv_active # inactive volumes have an empty lv_activevgchange -ay <vg>The filesystems they hold then appear in Storage > Mounts. Mounting one that already holds data never changes its ownership or permissions.
Replacing a failed disk
Section titled “Replacing a failed disk”Storage > RAID shows each member as Active, Failed or Spare, with the disk model and serial number to find it physically. The same steps by hand:
cat /proc/mdstat # (F) marks a failed membermdadm --detail /dev/md0 # state of every membermdadm --manage /dev/md0 --fail /dev/sdb # if the kernel has not marked it yetmdadm --manage /dev/md0 --remove /dev/sdb # or --remove detached if the disk is gonemdadm --manage /dev/md0 --add /dev/sdf # at least as large as the smallest memberwatch cat /proc/mdstat # recovery = NN.N% while it rebuildsSupported levels: RAID 0 (no redundancy, nothing to replace), RAID 1, RAID 5 and RAID 10. Until the rebuild finishes the array has no redundancy left (RAID 5, RAID 10 pair, two-disk RAID 1): avoid heavy writes and keep a backup.
Mounts
Section titled “Mounts”Mounts HSI persists go through /etc/fstab, the same file mount -a and every
distro tool already reads.
findmnt # current mountscat /etc/fstab # persisted entriesmount -a # (re)apply fstab by handThe fstab line of each volume HSI manages is also in its storage description.
Before changing storage, HSI shows the exact commands and file diffs it will apply; the same plan is kept in the audit log, so every change can be redone or undone by hand.
HSI’s entries carry nofail, and their mount point directories are made
immutable while unmounted so nothing writes to the system disk in their place.
To reuse such a directory by hand, clear the flag first:
umount /mnt/data && chattr -i /mnt/datasystemd services
Section titled “systemd services”HSI itself is three ordinary systemd units grouped under hsi.target; see
systemd services for the full list and log
commands.
systemctl status hsi-server hsi-worker hsi-natssystemctl stop hsi.target # stop HSI entirely, e.g. before manual workVersions and rollback
Section titled “Versions and rollback”Each release lives in /opt/hsi/releases/<version>/ and /opt/hsi/current is a
symbolic link to the active one (the two previous versions are kept).
/usr/local/bin/hsi-worker points into it. Before each update the database and
configuration are copied to /var/lib/hsi/update/<from>-<to>/, and the result of
the last update is in /var/lib/hsi/update/last.json (the last 20 results in
results.jsonl). After an update, a rollback or a reinstall, the two newest
previous versions and the snapshots they need are kept; a version that failed and
was rolled back is removed.
ls -l /opt/hsi/current /opt/hsi/releasescat /var/lib/hsi/update/last.jsonsudo hsi-worker update statussudo hsi-worker update rollback # previous version, with the data of its snapshotThe rollback loses everything changed in the database since that snapshot. See Updates.
Backup plans
Section titled “Backup plans”Each plan is a systemd timer, hsi-backup@<id>.timer, and each versioned repository
has a check timer, hsi-backup-check@<id>.timer. They run without the HSI server.
systemctl list-timers 'hsi-backup*'sudo hsi-worker backup run <id> [--manual] # --manual runs a paused plan toosudo hsi-worker backup check <id> [--full]The configuration is in /etc/hsi/backup.json, the secrets of each repository in
/etc/hsi/backup/<id>.json (readable by root only) and the run logs in
/var/lib/hsi/backup/.
For a versioned plan you can also use restic directly, with the binary HSI installed. Pass the repository and its secrets as environment variables, never on the command line, where other users could read them:
sudo -iexport RESTIC_REPOSITORY=/mnt/backups/repo # from the repository settingsexport RESTIC_PASSWORD='...' # "password" in /etc/hsi/backup/<id>.json/usr/local/lib/hsi/restic snapshots/usr/local/lib/hsi/restic restore latest --target /mnt/restoredS3 repositories also need AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, REST
repositories RESTIC_REST_USERNAME and RESTIC_REST_PASSWORD. The repository
address is s3:https://<endpoint>/<bucket>/<path> (s3:http://... for an endpoint
written with http://), rest:<url> or sftp://<user>@<host>:<port>/<path>. For
SFTP, add the options HSI uses to the restic command:
-o sftp.args='-i <key> -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes'HSI takes its snapshots with the host name hsi: add --host hsi to a manual
backup so it finds the previous snapshot.
The old rsync plans, now sync plans, run the same rsync command you could type by
hand from the plan’s source, destination and options.
What this doesn’t cover yet
Section titled “What this doesn’t cover yet”Users/groups and LVM are also implemented as standard Linux mechanisms (Linux
accounts, lvm2) rather than HSI-private state, but don’t have a documented
manual-recovery workflow yet.
If you need a manual-recovery workflow that isn’t written here yet, the relevant
root-worker source (apps/root-worker/) is the authoritative reference for exactly
what commands HSI runs.