Homebox 0.26.2 on AWS User Guide
Overview
This guide covers launching and using the Homebox 0.26.2 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Helpdesk, ITSM and Project Management listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Homebox is a self hosted inventory and organisation system for homes, home labs and small teams. You record what you own, where it is kept (nested locations such as rooms, shelves and boxes), tags, quantities, serial and model numbers, purchase and warranty details, maintenance logs and photos or documents, then find anything with search or by scanning a printed QR label. It is a single Go program with an embedded SQLite database, so there is no separate database server to run.
The cloudimg image adds:
- HTTPS from the first boot. nginx serves Homebox on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
- An administrator account unique to your instance, and no open sign-up. Upstream Homebox lets the first person who opens the site register and become the owner. This image instead creates the administrator itself on first boot, with a password generated on your instance and written to
/root/homebox-credentials.txt, and keeps public registration closed. You add people with single use invites. - Fail closed. No account, password or key is baked into the image. Homebox refuses to start until first boot has written its per instance secrets, and nginx refuses to start until first boot has finished.
- Loopback only. Homebox listens on
127.0.0.1:7745behind nginx. The only open ports are 22, 80 and 443. - Hardened defaults. Homebox runs as its own unprivileged user in a systemd sandbox. Homebox and nginx are blocked from the instance metadata service; the AMI requires IMDSv2; requests for a host name the instance does not serve are dropped; cross site requests that change data are refused; and the client address Homebox sees (it rate limits sign-in attempts per client) comes from the connection, never from a header a client can forge.
- Your data on its own volume. The database and every uploaded photo and document live on a separate 20 GiB EBS volume mounted at
/data, which you can resize and snapshot on its own. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: Homebox 0.26.2 (/usr/local/bin/homebox, the official release binary, checksum verified), nginx, sqlite3, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH), TCP 443 (the web app and API) and TCP 80 (redirects to HTTPS) from your own networks only.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Homebox 0.26.2 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (Homebox is light; a smaller type works for a single household), your key pair and a security group as above. Keep the second EBS volume: it is where your inventory, photos and documents are stored.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=homebox}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Homebox 0.26.2 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
First boot takes a few seconds. Then the three units are active:
systemctl is-active homebox nginx homebox-firstboot
active
active
active
Homebox listens on loopback only; nginx serves ports 80 and 443:
sudo ss -tlnp | awk 'NR==1 || /homebox|nginx|sshd/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer
LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN 0.0.0.0:22 users:(("sshd"),("systemd"))
LISTEN 127.0.0.1:7745 users:(("homebox"))
LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:22 users:(("sshd"),("systemd"))
Step 4: Get your URL and administrator password
sudo cat /root/homebox-credentials.txt
The file holds the address Homebox is served as (your instance's public IP address by default), the administrator's email address and the password generated on this instance:
HOMEBOX_URL=https://<public-ip>/
HOMEBOX_ADMIN_EMAIL=admin@homebox.local
HOMEBOX_ADMIN_PASSWORD=<24 letters and digits>
Homebox reports itself healthy, on version 0.26.2, with registration closed:
H=$(sudo sed -nE 's#^HOMEBOX_URL=https://([^/]+)/.*#\1#p' /root/homebox-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/api/v1/status" | jq '{health, allowRegistration, version: .build.version}'
{
"health": true,
"allowRegistration": false,
"version": "0.26.2"
}
Step 5: Sign in from your browser
Open HOMEBOX_URL in your browser. The certificate is self signed (generated on your instance), so accept the browser warning once, or install your own certificate (Step 9). The sign-in page shows Registration Disabled: nobody can create an account from the internet.

Sign in with the email address and password from Step 4. Then open Profile and use Change Password to set your own password. The home page shows quick statistics, recently added items, your storage locations and tags. A new collection starts with eight example locations (Attic, Basement, Bathroom, Bedroom, Garage, Kitchen, Living Room, Office) and a few tags, which you can rename or delete:

Step 6: Track your things
Use Create to add an item or a location. Open a location to see everything stored in it; locations can contain other locations (a shelf in the garage, a box on the shelf):

Each item has details (quantity, serial and model numbers, manufacturer, insurance and purchase or warranty information, notes and an asset ID), a maintenance log, and photo or document attachments. Labels prints asset labels with QR codes; scanning one opens the item:

Step 7: Add people with invites
Public registration stays closed. To give someone access to your collection, open Collection, then Invites, and press + to create an invite. Each invite has a number of uses and an expiry date; send the invite link to the person, and they register with it into your collection. An invite token that does not exist is refused, so closed registration cannot be bypassed by guessing one.

The image keeps public registration closed, and a start check (/usr/local/sbin/homebox-start-guard) refuses to run Homebox if HBOX_OPTIONS_ALLOW_REGISTRATION is set to anything but false. If you deliberately want open sign-up (for example on an isolated private network), set it to true in /etc/homebox/homebox.env, clear the check with a systemd override, and restart. Anyone who can reach the site can then create an account, so we recommend invites instead:
sudo systemctl edit homebox # add the two lines: [Service] and ExecStartPre=
sudo systemctl restart homebox
Step 8: Use the REST API
Everything in the web app is available from the REST API under /api/v1. Sign in with POST /api/v1/users/login to get a token, then send it in the Authorization header. On the instance (the password is read from the credentials file and sent to curl on stdin, so it never appears on a command line):
H=$(sudo sed -nE 's#^HOMEBOX_URL=https://([^/]+)/.*#\1#p' /root/homebox-credentials.txt)
login() { sudo python3 -c 'import json
c=dict(l.strip().split("=",1) for l in open("/root/homebox-credentials.txt") if l.startswith("HOMEBOX_ADMIN_"))
print(json.dumps({"username":c["HOMEBOX_ADMIN_EMAIL"],"password":c["HOMEBOX_ADMIN_PASSWORD"],"stayLoggedIn":False}))' \
| curl -sk --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" -H 'Content-Type: application/json' \
--data-binary @- "https://$H/api/v1/users/login" | jq -r .token; }
TOKEN=$(login)
api() { printf 'header = "Authorization: %s"\n' "$TOKEN" | curl -sk -K - --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" "$@"; }
api "https://$H/api/v1/users/self" | jq -r '.item | "\(.name) <\(.email)>"'
api "https://$H/api/v1/groups/statistics" | jq -c '{totalUsers, totalItems, totalLocations, totalTags}'
Administrator <admin@homebox.local>
{"totalUsers":1,"totalItems":0,"totalLocations":8,"totalTags":6}
Items and locations are both "entities" in Homebox 0.26. This creates an item in the Office location and finds it again with a search:
H=$(sudo sed -nE 's#^HOMEBOX_URL=https://([^/]+)/.*#\1#p' /root/homebox-credentials.txt)
TOKEN=$(sudo python3 -c 'import json
c=dict(l.strip().split("=",1) for l in open("/root/homebox-credentials.txt") if l.startswith("HOMEBOX_ADMIN_"))
print(json.dumps({"username":c["HOMEBOX_ADMIN_EMAIL"],"password":c["HOMEBOX_ADMIN_PASSWORD"],"stayLoggedIn":False}))' \
| curl -sk --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" -H 'Content-Type: application/json' \
--data-binary @- "https://$H/api/v1/users/login" | jq -r .token)
api() { printf 'header = "Authorization: %s"\n' "$TOKEN" | curl -sk -K - --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" -H 'Content-Type: application/json' "$@"; }
OFFICE=$(api "https://$H/api/v1/entities/tree" | jq -r '.[] | select(.name=="Office") | .id')
api -X POST "https://$H/api/v1/entities" -d "{\"name\":\"Label printer\",\"quantity\":1,\"parentId\":\"$OFFICE\"}" | jq -r '"created: \(.name)"'
api "https://$H/api/v1/entities?q=printer" | jq -r '.items[] | "\(.name) in \(.parent.name)"'
created: Label printer
Label printer in Office
From your own computer, use https://<your-dns-name>/api/v1/... the same way. For scripts, use Profile > Create API Key instead of signing in with the password (an API key has the same permissions as your account). The interactive API reference is linked as API at the bottom of every page.
Step 9: Your own DNS name and certificate
Point a DNS record at the instance, then set the name Homebox is served as. This mints a new self signed certificate for the name, updates nginx, Homebox's own base URL (used in password reset links) and the URL in /root/homebox-credentials.txt, and keeps the name across reboots:
sudo homebox-set-hostname <your-domain>
To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx (running homebox-set-hostname again replaces it with a self signed one):
sudo install -m 0644 <your-domain>.crt /etc/ssl/homebox/homebox.crt
sudo install -m 0600 <your-domain>.key /etc/ssl/homebox/homebox.key
sudo nginx -t && sudo systemctl reload nginx
Step 10: Security checks
Without a token the API refuses you, public registration is refused, a sign-in posted from another web site is refused, and a request for a host name the instance does not serve gets no answer:
H=$(sudo sed -nE 's#^HOMEBOX_URL=https://([^/]+)/.*#\1#p' /root/homebox-credentials.txt)
curl -sk -o /dev/null -w 'unauthenticated API call: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/api/v1/users/self"
curl -sk -w ' (HTTP %{http_code})\n' --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" -H 'Content-Type: application/json' \
-d '{"name":"someone","email":"someone@example.com","password":"Someone-123456789"}' "https://$H/api/v1/users/register"
curl -sk -o /dev/null -w 'cross-site sign-in attempt: %{http_code}\n' --resolve "$H:443:127.0.0.1" -H 'Origin: https://evil.example' \
-H 'Content-Type: application/json' -d '{"username":"x","password":"y"}' "https://$H/api/v1/users/login"
curl -s -o /dev/null -w 'unknown host name: %{http_code}\n' -H 'Host: evil.example' http://127.0.0.1/ || true
unauthenticated API call: 401
{"error":"user registration disabled"} (HTTP 403)
cross-site sign-in attempt: 403
unknown host name: 000
The configuration keeps Homebox on loopback with registration closed, and the secrets files are readable by root (and, for the configuration, the homebox service) only:
sudo grep -E '^HBOX_(WEB_HOST|OPTIONS_ALLOW_REGISTRATION|OPTIONS_TRUST_PROXY|OPTIONS_HOSTNAME)=' /etc/homebox/homebox.env
sudo stat -c '%a %U:%G %n' /etc/homebox/homebox.env /root/homebox-credentials.txt /etc/ssl/homebox/homebox.key
HBOX_WEB_HOST=127.0.0.1
HBOX_OPTIONS_ALLOW_REGISTRATION=false
HBOX_OPTIONS_TRUST_PROXY=true
HBOX_OPTIONS_HOSTNAME=https://<public-ip>
640 root:homebox /etc/homebox/homebox.env
600 root:root /root/homebox-credentials.txt
600 root:root /etc/ssl/homebox/homebox.key
Homebox runs unprivileged in a sandbox, neither Homebox nor nginx can reach the instance metadata service, and nginx passes Homebox the real client address from the connection (Homebox trusts these headers only because nginx on the same machine is the only thing that can reach it):
systemctl show homebox -p User -p ProtectSystem -p NoNewPrivileges -p IPAddressDeny
systemctl show nginx -p IPAddressDeny
grep -E 'proxy_set_header (X-Forwarded-For|X-Real-IP|X-Forwarded-Host)' /etc/nginx/sites-available/cloudimg-homebox
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32
User=homebox
ProtectSystem=full
NoNewPrivileges=yes
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host "";
The certificate was generated on this instance and names its own addresses:
H=$(sudo sed -nE 's#^HOMEBOX_URL=https://([^/]+)/.*#\1#p' /root/homebox-credentials.txt)
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
subject=CN = <public-ip>, O = cloudimg
X509v3 Subject Alternative Name:
IP Address:<public-ip>, DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost
Step 11: Data, backups and configuration
The database (homebox.db) and the uploaded photos and documents (data/) live on the separate EBS volume, bind mounted at /var/lib/homebox:
findmnt -no SOURCE,TARGET /data
findmnt -no SOURCE,TARGET /var/lib/homebox
sudo ls /var/lib/homebox
/dev/nvme1n1 /data
/dev/nvme1n1[/homebox] /var/lib/homebox
data
homebox.db
homebox.db-shm
homebox.db-wal
To back up, snapshot the /data volume. Collection > Tools in the web app also exports your inventory to CSV (Import/Export) and generates a bill of materials or printable asset ID labels. To grow the volume, resize it in EC2, then run sudo resize2fs on its device.
Homebox reads /etc/homebox/homebox.env; the image sets:
| Setting | Meaning | Image default |
|---|---|---|
HBOX_WEB_HOST / HBOX_WEB_PORT |
Bind address and port | 127.0.0.1 / 7745 (nginx fronts it) |
HBOX_OPTIONS_ALLOW_REGISTRATION |
Public sign-up | false (invites still work) |
HBOX_OPTIONS_HOSTNAME |
Base URL used in password reset links | https://<your host> from first boot |
HBOX_OPTIONS_TRUST_PROXY |
Take the client address from nginx | true |
HBOX_OPTIONS_GITHUB_RELEASE_CHECK |
Ask GitHub for newer releases | false |
HBOX_AUTH_API_KEY_PEPPER |
Secret mixed into stored API key hashes | generated on first boot; do not change it, or existing API keys stop working |
After changing a setting, run sudo systemctl restart homebox. To send password reset emails, add the SMTP settings from the Homebox documentation (HBOX_MAILER_*).
To upgrade Homebox, download the release from the Homebox project, check its checksum, replace /usr/local/bin/homebox and restart the service. Snapshot the data volume before you do; Homebox migrates the database on start.
Step 12: Server components
| Component | Path |
|---|---|
| Homebox binary | /usr/local/bin/homebox |
| Database and uploads | /var/lib/homebox (on the /data volume) |
| Configuration | /etc/homebox/homebox.env (root:homebox, 0640) |
| Service unit | /etc/systemd/system/homebox.service |
| nginx site | /etc/nginx/sites-available/cloudimg-homebox |
| Certificate and key | /etc/ssl/homebox/ |
| First boot script | /usr/local/sbin/homebox-firstboot.sh |
| Host name helper | /usr/local/sbin/homebox-set-hostname |
| Credentials | /root/homebox-credentials.txt (mode 0600) |
| Licence | /usr/share/doc/homebox/LICENSE |
Step 13: Security recommendations
- Allow ports 22, 80 and 443 in the security group from your own networks only.
- Change the administrator password after your first sign-in, and keep
/root/homebox-credentials.txtsecret (delete it once you have changed the password, if you prefer). - Keep public registration closed and add people with single use invites that expire.
- Use your own DNS name and a certificate your clients trust (Step 9).
- Keep the operating system patched; unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else. - Snapshot the
/datavolume regularly to back up your inventory.
Support and licensing
Homebox is open source under the GNU Affero General Public License v3.0 (a copy is at /usr/share/doc/homebox/LICENSE); there is no per user or per CPU licence fee. The AMI price covers cloudimg's hardening, first boot setup and support.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA