Install HotLoop IoT 4.18.10
HotLoop IoT first shipped in 4.18.10. The image is ghcr.io/hotloop-io/hotloop-iot:4.18.10, built for amd64, arm64 and arm/v7, and the chart is hotloop-iot in the same Helm repository as the rest of the lineup. Both pull with no login. There is no Docker or Compose path, on purpose, and a bare podman run from a shell that dies with the session isn’t an install.
Two ways in. A cluster gets Helm. A Pi, a NUC or a small industrial PC with no cluster gets Podman Quadlet. Either way the database is a choice you make once: PostgreSQL 16 (the default), or a SQLite file with no database container at all.
helm repo add hotloop https://hotloop.io/hotloophelm repo updatehelm install hotloop hotloop/hotloop-iot --version 4.18.10 \ --namespace hotloop --create-namespaceCall the release hotloop whichever product it is. The release name is what the database’s volume, the Secrets and the Service are named after, and keeping it is what lets a site move up a product later.
That deploys IoT plus PostgreSQL 16.15 beside it on a 10 Gi volume, keeping 30 days of history. The chart generates the database password, the MCP token and an admin password into the release Secret, and reuses them on every upgrade, so a helm upgrade never rotates a password out from under you.
For a SQLite file and no database pod, ask for it when you install:
helm install hotloop hotloop/hotloop-iot --version 4.18.10 \ --namespace hotloop --create-namespace \ --set database.type=sqliteSQLite is one writer on one local disk, so it is one replica, and the volume goes on local storage, never NFS. A site with years of history at one second wants PostgreSQL. The IoT chart takes postgresql or sqlite and nothing else: asking it for timescaledb fails the install. Moving between the two later is a backup and a restore, not a values change, because the new database starts empty. Backups has the restore.
Back up the key
Section titled “Back up the key”The chart also generates <release>-secret-key (hotloop-secret-key with the commands above). It holds the key that encrypts every password HotLoop keeps for a device. The key is never in the database and never in a backup, so it is part of your data: a backup restores credentials only where that key is mounted. The chart keeps the Secret through a helm uninstall. Back it up somewhere other than next to your backups, because a key sitting beside the backups it protects protects nothing. Install the Gateway has the whole story, and it is the same key.
Sign in
Section titled “Sign in”The user is admin. The install notes print the command that reads the password back:
kubectl -n hotloop get secret hotloop \ -o jsonpath='{.data.admin-password}' | base64 -dkubectl -n hotloop port-forward svc/hotloop 8080:8080Open http://localhost:8080. That admin account is a bootstrap, not a reset switch: once it exists, changing auth.admin.password and upgrading does nothing, so a password somebody set in the UI never gets clobbered by the next deploy.
Now add a device, discover its tags, and try to write to one. You can’t. Writes ship off, every tag is read-only until somebody arms it, and safety.allowWrites stays false until you decide this deployment gets to move machinery. The write gate has every check, in order.
What to set before a real plant sees it
Section titled “What to set before a real plant sees it”Put these in a values file and install with -f.
| Value | Default | Why you’d touch it |
|---|---|---|
plant.name, plant.siteId |
HotLoop, empty |
What the plant is called on screens, in pages, and to other sites. |
plant.latitude, plant.longitude |
empty | Where the plant is, in decimal degrees. The sun is worked out from them on the box. Both or neither. |
global.timezone |
America/New_York |
Schedules and shift changes run on it. It has to be a real zone name, because one that won’t load stops startup. |
publicUrl |
empty | The address a phone on the plant Wi-Fi reaches HotLoop at. Without it, notifications have no link back and ntfy gets no Acknowledge button. |
safety.allowWrites |
false |
The master switch. Off, nothing writes to a machine, from anywhere. |
safety.allowMcpWrites |
false |
Lets agents write through the same gate. It narrows the master switch and never goes around it. |
historian.retentionDays |
30 |
Days of history kept. The Gateway and Edge keep 90, because a Pi’s disk is small. |
logbook.retentionDays |
90 |
Days of entity state changes the logbook keeps. |
database.postgresql.persistence.size |
10Gi |
Your history lives here. Size it for your tag count and the retention above. |
secretKey.existingSecret |
empty | A Secret you manage holding the device password key. Set it if you render the chart with helm template, which can’t generate a stable key. |
opcuaClient.persistence.enabled |
false |
Turn it on before you add a secured OPC UA device, so the client’s certificates survive a restart. |
ingress |
off | Only if you want it reachable from outside the cluster by a name. |
Podman Quadlet
Section titled “Podman Quadlet”For a box that isn’t in a cluster. Quadlet turns the containers into real systemd services: they start on boot with nobody logged in, restart when they die, and log to the journal. It needs Podman 5.0 or newer. Raspberry Pi OS Bookworm ships 4.3, which has no Quadlet at all, so a Pi wants Trixie or newer. Put the database volume on a USB SSD and not the SD card, because history writes all day and SD cards die of exactly that.
The units are in the iot/ directory of the HotLoop repository, under deploy/quadlet/. Podman Quadlet explains what each file is. The short version for PostgreSQL:
sudo cp hotloop.network hotloop.container hotloop-db.container \ hotloop-db.volume hotloop-data.volume /etc/containers/systemd/
openssl rand -hex 24 | sudo podman secret create hotloop-db-password -sudo podman run --rm ghcr.io/hotloop-io/hotloop-iot:stable gen-secret-key \ | sudo podman secret create hotloop-secret-key -printf '%s' 'a long admin password' \ | sudo podman run --rm -i ghcr.io/hotloop-io/hotloop-iot:stable hash-password \ | sudo podman secret create hotloop-admin-password-hash -
sudo systemctl daemon-reloadsudo systemctl start hotloop.servicesudo systemctl status hotloop.service hotloop-db.servicecurl -s localhost:8080/api/statusThen open http://<this box>:8080 and log in as admin. The three secrets are the database password, the key that encrypts device passwords (lose it and every one has to be typed in again, so keep a copy somewhere that isn’t this box), and the bcrypt hash of the admin’s password, never the password itself.
For a SQLite file instead, use the files in iot/sqlite/ and nothing from the directory above. They have the same unit names, so it is one set or the other, never both. It is two files, hotloop.container and hotloop-data.volume, and two secrets, hotloop-secret-key and hotloop-admin-password-hash. The database is /data/hotloop.db on the hotloop-data volume.
The unit follows :stable, and Podman moves it once the timer is on:
sudo systemctl enable --now podman-auto-update.timerA new image migrates the database on its way up, and if it can’t start, Podman puts the previous one back. The database container does not follow :stable, on purpose. The :stable auto-update says what an update does, what a rollback cannot undo, and how to hold updates until you say. Take a backup before you turn updates on.
Moving up a product
Section titled “Moving up a product”IoT to Edge to the Gateway keeps every device, tag, entity, automation, alarm, user and hour of history, and the lineup has the how. The Quadlet move has been run on one set of volumes. The same move as a helm upgrade on a real cluster, and going back down a product, have not been run, so don’t take a box you care about down a product.
What has and hasn’t been run
Section titled “What has and hasn’t been run”IoT’s SQLite Quadlet unit was run under systemd, rootless, from the committed files. The PostgreSQL unit, and the Edge and Gateway units, are generated from the Gateway’s, which was run for real, and compared to it. A real Pi under systemd as root, and the 32-bit arm images on real hardware, haven’t been done yet. This page will say so when they are.
License
Section titled “License”HotLoop IoT is under HotLoop’s Business Source License 1.1. Home and lab use is free, and business use is free through EmberNET. See the License page and Using HotLoop in a business.