HomeBox is a self-hosted inventory management system that I’ve just installed into my homelab. This is a log of how I did it.

ArchitectureHomeBox can run entirely independently using a SQLite database, the local file system for storage, and its own user system for authentication. However it can also use PostgreSQL, S3-compatible storage, and OIDC for auth. Since I have all of those things already running that’s how I set it up.## InstallThe docs contain an example Docker compose file so I started with that. I use Ansible to configure my virtual machines and have one dedicated to Docker Compose stacks, so in my code I created a new directory for HomeBox and added the example Docker Compose file.If I was using the default setup I could have stopped there but I’m using the extra things I mentioned above and each one of them needs a secret. Instead of writing the secrets as plain-text I used Ansible vault to encrypt a template file in my repo and then write that as .env to the same directory as the compose file. Docker Compose will automatically read it and use its values when referenced in the docker-compose.yaml file.## DatabaseI have a virtual machine dedicated to running Postgres and use the geerlingguy/docker-role-postgresql role to configure it. In my group_vars/postgres/main.yaml file I added lines for a new homebox database and user to postgresql_databases, postgresql_users and postgresql_hba_entries. The new postgresql_user uses a password of "{{ vault_homebox_database_password }}" so I created a new password and entered it into my group_vars/postgres/vault.yaml file which is also encrypted with Ansible vault.To use it I added:yaml- HBOX_DATABASE_DRIVER=postgres- HBOX_DATABASE_HOST=postgres.infra.home.arpa- HBOX_DATABASE_PORT=5432- HBOX_DATABASE_USERNAME=homebox- HBOX_DATABASE_PASSWORD=${HBOX_DATABASE_PASSWORD}- HBOX_DATABASE_DATABASE=homeboxto the environment part of the docker-compose.yaml. The role that sets up the Docker Compose stacks doesn’t read the values I set for the Postgres role, so I had to copy the password I used for the database into the encrypted file that creates the .env for HomeBox. I now have that same password written twice, once for the database and once for HomeBox to use it.## StorageI’m currently running MinIO on my TrueNAS Scale machine and I can use that for S3-compatible storage. I set it up before they changed their license and now migrating to an alternative is yet another thing on my TODO list.I created a new bucket by using the mc CLI client to run:shmc mb lab/homeboxTo use it I added:yaml- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}- HBOX_STORAGE_CONN_STRING=s3://homebox?awssdk=v2&endpoint=http://<NAS_IP>:9000&disable_https=true&s3ForcePathStyle=trueto the environment part of my docker-compose.yaml.The “AWS” (Minio) values are also secrets added to the template that writes out the .env file.The HBOX_STORAGE_CONN_STRING value comes from the HomeBox docs.Note to self: I should also set up nas.infra.home.arpa like I did for Postgres.## OIDCI have Kanidm set up as an IdP and it can do OIDC for HomeBox to use for authentication.To create the client in Kanidm I ran:shkanidm system oauth2 create homebox HomeBox "https://homebox.cloud.paultibbetts.uk"kanidm group create homebox_userskanidm group add-members homebox_users paulkanidm system oauth2 update-scope-map homebox homebox_users openid profile emailand to set the logo for it I ran:shcurl -o homebox.svg https://raw.githubusercontent.com/sysadminsmedia/homebox/refs/heads/main/docs/public/lilbox.svgkanidm system oauth2 set-image homebox homebox.svg svgrm homebox.svgThe docker compose environment values to use Kanidm for OIDC are:yaml- HBOX_OPTIONS_HOSTNAME=homebox.cloud.paultibbetts.uk- HBOX_OIDC_ENABLED=true- HBOX_OIDC_ISSUER_URL=https://<kanidm_domain>/oauth2/openid/homebox- HBOX_OIDC_CLIENT_ID=homebox- HBOX_OIDC_CLIENT_SECRET=${HBOX_OIDC_CLIENT_SECRET}- HBOX_OPTIONS_TRUST_PROXY=truewhere HBOX_OIDCD_CLIENT_SECRET is another secret added to the .env template.## DNSI use Pi-hole for ad-blocking and custom DNS records in my homelab.I don’t yet have an automated way to configure it, so I did it using the web UI, and wrote another reminder to automate this process.I have an A record for the reverse proxy I use so I created a CNAME for HomeBox that points homebox.cloud.paultibbetts.uk to the reverse proxy.I could set up an A record for HomeBox but that would mean writing out the IP of the reverse proxy, whereas using a CNAME means I can enter its domain, which is easier to remember than numbers. It also means I could move the reverse proxy to another server and I would only need to update the A record for it and all the things pointing to it with CNAMEs would still work.## Reverse proxyI use Caddy as a reverse proxy. This is configured by an Ansible role. Well it should be, I left all the tasks in the playbook but I only use it once in this one playbook so it doesn’t need to be.The Caddyfile that configures all my virtual hosts is a template that Ansible writes out. I use Cloudflare’s DNS challenge when Caddy requests TLS certificates from Lets Encrypt and that needs a token for Cloudflare so I use an Ansible template file so I can encrypt the token using Ansible vault. I use the DNS challenge because my homelab isn’t on the internet so it’s not accessible to Lets Encrypt when it tries to do the regular HTTP challenge.For HomeBox I added:https://homebox.cloud.paultibbetts.uk { reverse_proxy apps.infra.home.arpa:3100}where apps.infra.home.arpa is an A record for the VM with Docker Compose running HomeBox. The 3100 port was defined earlier in the Docker Compose yaml file:yamlports: - 3100:7745## DeployTo deploy I ran the apps.yaml playbook to write the docker-compose.yaml file and the .env file that contains all the secrets. This also runs docker compose up -d so the stack is up and running by the end of it.To add the virtual host to Caddy I ran my ingress.yaml playbook that configures Caddy.Because this is my writeup I can pretend it all worked perfectly the first time and I definitely didn’t have a typo in my domain.## Initial testI registered a user account using my email and set a password, just in case. I then logged out and tried again using OIDC and it logged me into the same account - this is because my email in Kanidm is the same one I used when registering. Some apps make separate accounts when logging in using a password or with OIDC but I like this approach more.HomeBox doesn’t have a super user, it uses a multi-tenant setup where everyone gets their own inventory and you have to invite others to access yours. I haven’t tried this yet. I might not ever need it - I don’t want anyone else seeing how many unused cables I refuse to throw away.Creating my account proved the database worked ✅, and logging in with Kanidm proved OIDC worked ✅, so I created an item in HomeBox and uploaded a photo and that proved the storage with MinIO worked ✅.