HIHome Inventory
GitHub
Installation

How you will run it.

Three supported paths, all rootless, all described by one service matrix. The commands below are placeholders for the shape of the thing — the real ones land with the first release.

Nothing to install today
No container image is published and no release exists. The third-party images in the service matrix are pinned to their digests; the five built from this repository carry none, because nothing has been published for a digest to name yet.

Choose a runtime

Podman ≥ 5 with Quadlet

The reference path. Quadlet turns container units into systemd units, so the instance starts with the machine, restarts under systemd's rules and runs entirely in your user session.

Planned — these commands do not work yet
# planned — not available yet
mkdir -p ~/.config/containers/systemd

curl -LO https://github.com/greluc/Home-Inventory/releases/latest/download/homeinv-quadlet.tar.gz
tar -xzf homeinv-quadlet.tar.gz -C ~/.config/containers/systemd

cp homeinv.env.example ~/.config/homeinv/homeinv.env   # set HOMEINV_*
systemctl --user daemon-reload
systemctl --user start homeinv-minimal.target

loginctl enable-linger "$USER"   # survive a logout
  • ·Generated from deploy/services.yaml — never hand-edited
  • ·Rootless by construction: no daemon, no root, no bind mounts
  • ·The migration service runs once per start, before the api unit

Docker with Compose v2, rootless

An equal path, not a fallback. Same images, same environment keys, same limits — Docker must be installed in rootless mode; the rootful daemon is unsupported.

Planned — these commands do not work yet
# planned — not available yet
curl -LO https://github.com/greluc/Home-Inventory/releases/latest/download/compose.yaml
curl -LO https://github.com/greluc/Home-Inventory/releases/latest/download/.env.example

cp .env.example .env   # set HOMEINV_*
docker compose up -d

docker compose logs -f homeinv-migration
  • ·Generated from the same service matrix; a hand-written deviation fails CI
  • ·Named volumes only — a bind mount would reintroduce host ownership
  • ·Published ports come from the web service alone; everything else is internal

Kubernetes with Helm

Hand-written rather than generated, and validated against the matrix: same services, same environment keys, same limits. Tested in CI against kind with the restricted PodSecurity profile and user namespaces.

Planned — these commands do not work yet
# planned — not available yet
helm repo add home-inv https://greluc.github.io/Home-Inventory/charts
helm repo update

helm show values home-inv/home-inv > values.yaml   # then edit
helm install home-inv home-inv/home-inv -f values.yaml -n home-inv --create-namespace
  • ·Arrives with stage 2 — the two container runtimes carry operation first
  • ·The chart disciplines statelessness: api and worker hold nothing on disk
  • ·PostgreSQL, OpenSearch and RabbitMQ are yours to provide or to run in-cluster

Rootless, without exception

No supported path runs a container daemon or a container as root on the host. That is not a hardening preference — it is why the application listens on 8080 and why there is not a single bind mount in the deployment directory.

One source, three renderings

deploy/services.yaml is edited; the Quadlet units and compose.yaml are generated from it, and a hand-written deviation fails the drift check. The Helm chart is too different in shape to generate, so it is validated against the same matrix instead.

Before you start

Prerequisites
WhatRequirement
Container runtimePodman ≥ 5 with Quadlet, or Docker with Compose v2 — rootless in both cases
KubernetesA cluster with the restricted PodSecurity profile and user namespaces
DatabasePostgreSQL 18 — row-level security, JSONB, uuidv7()
DistributionsDebian ≥ 13 · Ubuntu ≥ 26.04 LTS · Fedora ≥ 43 · RHEL, CentOS Stream, Rocky, Alma ≥ 9.5 resp. ≥ 10
NetworkOne hostname with TLS. The web service is the ingress and the only one that publishes a port
MediaA volume for the BlobStore. No bind mounts — anywhere
OutboundOnly the egress proxy may leave the deployment; in the smallest profile with exactly one allowlist entry, for the virus signatures

What you will be running

Ten services, not one container
Services in the deployment
ServiceRoleFrom stage
webThe ingress: serves the PWA and the CSP headers — the only published port0
apiThe REST and GraphQL surface, stateless0
migrationA one-shot service; no long-running process holds DDL rights0
postgresPostgreSQL 18 with row-level security0
blobstoreThe filesystem BlobStore as its own service, so api and worker stay stateless0
clamavThe mandatory malware scan, fail-closed0
egress-proxyThe only way out, with an allowlist per segment0
workerEvents, background runs, housekeeping1
rabbitmqQuorum queues for the transactional outbox1
opensearchThe derived read model for search and facets1

The stage column says when a service first appears. A stage-0 installation runs seven of them; OpenSearch and RabbitMQ arrive with stage 1, when there is something to index and something to queue.

Get told when it is installable

There is no mailing list and no newsletter. Watch the repository's releases — that is the same signal the author gets.