Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 22.09.2026 · 12 min Lesezeit

Homebox mit Docker Compose: Inventarverwaltung für IT-Assets und Geräte

Homebox erfasst Geräte, Seriennummern, Belege und Garantieablauf mit sehr geringem Ressourcenbedarf. Die Anleitung zeigt den Compose-Stack mit PostgreSQL, Erstkonfiguration, QR-Etiketten, Reverse Proxy sowie Backup mit geprüfter Wiederherstellung.

Geprüft am 18.10.2026 · für Homebox 0.27.0

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Regal mit vier gestapelten Laptops mit Farbpunkten, Mini PC und Kabeln mit farbigen Klettbändern in Körben

In kleinen Unternehmen steht die Seriennummer oft in einer Tabelle, der Kaufbeleg im Mailpostfach, und das Garantiedatum kennt niemand. Homebox ist ein schlankes, selbst gehostetes Inventarsystem für Geräte, Belege und Garantien, ohne dass Sie ein ausgewachsenes ITSM-Produkt betreiben müssen. Diese Anleitung zeigt die Installation mit Docker Compose und PostgreSQL, die Erstkonfiguration, Etiketten, Absicherung, Backup mit geprüfter Wiederherstellung und typische Fehler.

Voraussetzungen

Sie brauchen einen Linux-Host mit Docker Engine und Compose-Plugin (Version 2). Die offizielle Compose-Datei baut Images für linux/amd64, linux/arm64 und linux/arm, der Test lief auf amd64.

RessourceEmpfehlungIm Test beobachtet
CPU1 vCPU reicht für kleine Bestände0,41 Prozent im Leerlauf
Arbeitsspeicher512 MB für beide Container plus Puffer14,14 MiB App, 45,48 MiB Datenbank
Speicherplatz2 GB plus Platz für Fotos und BelegeImage 198 MB laut docker images
PortsEin freier Host-Port, im Container immer 7745Test lief auf 127.0.0.1:37450
EckdatenWert
Imageghcr.io/sysadminsmedia/homebox:0.27.0: Datenbank postgres:17-alpine
Port7745 im Container, auf dem Host an 127.0.0.1 gebunden
Volumeshomebox-data nach /data (Anhänge), homebox-db nach /var/lib/postgresql/data
Pflicht-EnvHBOX_AUTH_API_KEY_PEPPER (mindestens 32 Byte), POSTGRES_PASSWORD

Neben dem Standardimage gibt es latest-rootless (läuft als UID 65532, Bind-Mounts vorher mit chown 65532:65532 -R anpassen) und latest-hardened (distroless, ohne Shell). Homebox ist laut README für Heimanwender gebaut und keine CMDB: keine automatische Geräteerkennung, keine Abhängigkeiten zwischen Objekten, kein Lizenzmanagement mit Platzzählung, kein Ticketsystem, Rechte nur auf Gruppenebene. Für Ausgabe an Mitarbeitende mit Audit-Trail passt Snipe-IT, für Helpdesk mit Agenten-Inventarisierung GLPI.

Schritt 1: Geheimnisse erzeugen

Der Pepper fließt serverseitig in die Hashes der API-Schlüssel ein. Er ist Pflicht, ohne ihn startet der Dienst nicht. Ein späterer Wechsel entwertet alle ausgegebenen API-Schlüssel.

# Verzeichnis fuer den Stack anlegen
sudo mkdir -p /opt/homebox
cd /opt/homebox
# Datenbankpasswort und API-Key-Pepper erzeugen
{
  echo "POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=' | head -c 24)"
  echo "HBOX_AUTH_API_KEY_PEPPER=$(openssl rand -base64 48 | tr -d '\n')"
} > .env
# Datei nur fuer den Eigentuemer lesbar machen
chmod 600 .env

Die .env sieht danach strukturell so aus. Übernehmen Sie niemals Beispielwerte:

# Beispielwerte, NICHT uebernehmen
POSTGRES_PASSWORD=bitte-hier-eigenes-passwort-einsetzen
HBOX_AUTH_API_KEY_PEPPER=bitte-hier-eigenen-48-byte-wert-einsetzen

Verifizieren: ls -l .env zeigt -rw-------, grep -c = .env liefert 2.

Schritt 2: compose.yaml anlegen

Die Datei entspricht dem Stack aus dem Test, ergänzt um einen Healthcheck für PostgreSQL und eine Startreihenfolge. Der Port ist bewusst nur an 127.0.0.1 gebunden, der Zugriff von außen gehört hinter einen Reverse Proxy.

name: homebox

services:
  homebox-db:
    image: postgres:17-alpine
    container_name: homebox-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: homebox
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: homebox
    volumes:
      - homebox-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U homebox -d homebox"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 20s

  homebox:
    image: ghcr.io/sysadminsmedia/homebox:0.27.0
    container_name: homebox
    restart: unless-stopped
    depends_on:
      homebox-db:
        condition: service_healthy
    environment:
      HBOX_MODE: production
      HBOX_LOG_LEVEL: info
      HBOX_LOG_FORMAT: text
      HBOX_WEB_MAX_UPLOAD_SIZE: 25
      HBOX_OPTIONS_ALLOW_ANALYTICS: "false"
      HBOX_OPTIONS_GITHUB_RELEASE_CHECK: "false"
      HBOX_OPTIONS_ALLOW_REGISTRATION: "true"
      HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID: "true"
      HBOX_AUTH_API_KEY_PEPPER: ${HBOX_AUTH_API_KEY_PEPPER}
      HBOX_DATABASE_DRIVER: postgres
      HBOX_DATABASE_HOST: homebox-db
      HBOX_DATABASE_PORT: 5432
      HBOX_DATABASE_USERNAME: homebox
      HBOX_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
      HBOX_DATABASE_DATABASE: homebox
      HBOX_DATABASE_SSL_MODE: disable
      TZ: Europe/Berlin
    volumes:
      - homebox-data:/data
    ports:
      - "127.0.0.1:7745:7745"

volumes:
  homebox-db:
  homebox-data:
VariableStandardWarum gesetzt
HBOX_MODEdevelopmentFür den Betrieb auf production
HBOX_WEB_MAX_UPLOAD_SIZE10MB, für Handyfotos von Typenschildern auf 25 erhöht
HBOX_DATABASE_SSL_MODErequireIm internen Compose-Netz disable, bei externer Datenbank require lassen
HBOX_OPTIONS_ALLOW_REGISTRATIONtrueFür die Ersteinrichtung nötig, danach abschalten
HBOX_OPTIONS_AUTO_INCREMENT_ASSET_IDtrueFortlaufende Inventarnummern wie 000-001
HBOX_OPTIONS_GITHUB_RELEASE_CHECKtrueAbgeschaltet, sonst Verbindungsfehler im Log bei Hosts ohne Internet

Den Container-Port 7745 ändern Sie laut Dokumentation unter Docker nicht, nur die linke Seite im ports-Eintrag.

Verifizieren: docker compose config -q gibt nichts aus. ss -tlnp | grep 7745 bleibt leer, der Port ist also frei.

Schritt 3: Stack starten

# Stack im Hintergrund starten
docker compose up -d
# Startphase mit Migrationen ansehen
docker compose logs homebox --tail 50

Der erste Start legt das Datenbankschema an. Im Test endete die Migration nach wenigen Sekunden mit diesen Logzeilen:

2026/09/22 00:11:51 OK   20260512130001_add_exports.sql (57.42ms)
2026/09/22 00:11:51 goose: successfully migrated database to version: 20260512130001
12:11AM INF ../go/src/app/app/api/handlers/v1/v1_ctrl_auth.go:100 > registering auth provider name=local
12:11AM INF ../go/src/app/app/api/main.go:275 > Server is running on :7745

Das Image bringt einen eigenen Healthcheck mit, der per wget den Endpunkt /api/v1/status abfragt. Denselben Endpunkt nutzen Sie für eine externe Überwachung, er braucht keine Anmeldung und liefert keine sensiblen Daten:

# Startseite pruefen
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:7745/
# Statusendpunkt abfragen
curl -s http://127.0.0.1:7745/api/v1/status

Antwort im Test, gekürzt:

200
{"health":true,"title":"Homebox",
"build":{"version":"v0.26.2","commit":"e01dd737238a3fa7e1a6454b37de6c6fc88c86e4"},
"demo":false,"allowRegistration":true,"oidc":{"enabled":false},
"telemetry":{"enabled":false}}

Verifizieren: docker compose ps zeigt beide Container als (healthy), die Startseite liefert 200 und der Status "health":true.

Schritt 4: Erstes Konto und Struktur anlegen

Rufen Sie die Oberfläche im Browser auf (über einen SSH-Tunnel oder den Reverse Proxy aus Schritt 6) und legen Sie das erste Konto an. Weitere Kollegen holen Sie über einen Einladungslink aus dem Profilbereich in Ihre Gruppe. Ohne diesen Link sieht ein neu registrierter Benutzer laut Dokumentation nur eigene Objekte. Schließen Sie danach die Selbstregistrierung:

      HBOX_OPTIONS_ALLOW_REGISTRATION: "false"

und erstellen Sie den Container mit docker compose up -d neu.

Ab Version 0.26 sind Objekte und Standorte beides Entitäten, unterschieden durch einen Entitätstyp. Im Test war nach der Installation nur der Typ Location vorhanden, ein eigener Typ für Geräte ließ sich anlegen und verwenden. Zusätzlich legt Homebox beim ersten Konto Beispiel-Lagerorte (englisch benannt, etwa Garage oder Office) und sechs Beispiel-Tags an, die Sie umbenennen oder löschen. Die Währung stand im Test auf US-Dollar und ließ sich in den Gruppeneinstellungen auf Euro umstellen. Eine sinnvolle Struktur für eine kleine IT:

  • Standorte als Baum: Firmensitz, Büros, Serverraum mit Racks als Unterstandorten, Lager.
  • Entitätstypen: IT-Asset, Lizenz, Verbrauchsmaterial.
  • Tags und eigene Felder: Abteilung, Leasing oder Eigentum, Kostenstelle, Inventarnummer der Buchhaltung.

Füllen Sie je Gerät Name, Hersteller, Modell- und Seriennummer, Kaufdatum, Händler, Preis und Garantieablauf aus. Im Test wurden diese Felder an einem Beispielgerät gesetzt und wieder ausgelesen, die Inventarnummer 000-002 vergab Homebox selbst:

{'assetId': '000-002', 'serialNumber': 'PF-3XK91A',
 'manufacturer': 'Lenovo', 'warrantyExpires': '2029-02-10',
 'purchasePrice': 1249}

Belege und Fotos hängen Sie direkt ans Gerät. Im Volume liegen sie unter Hash-Namen, die Zuordnung steht nur in der Datenbank. Ein Backup des Volumes ohne Datenbank ist deshalb wertlos.

Homebox-Startseite mit Statistiken, zuletzt hinzugefügtem ThinkPad, Lagerorten und Tags
Startseite nach dem ersten Gerät: Gesamtwert, Lagerorte und Tags auf einen Blick.
Homebox-Detailansicht eines ThinkPad mit Seriennummer, Modellnummer, Hersteller und Asset-ID 000-002
Detailansicht des Beispielgeräts mit Seriennummer und automatisch vergebener Asset-ID.

Verifizieren: Ein neuer Registrierungsversuch scheitert (im Test HTTP 403 mit user registration disabled), /api/v1/status meldet "allowRegistration":false, und die Suche nach dem angelegten Gerätenamen liefert genau einen Treffer.

Schritt 5: Etiketten und CSV-Export

Den Alltagsnutzen bringen Etiketten: Homebox erzeugt je Objekt ein PNG mit QR-Code, das beim Scannen direkt auf den Datensatz führt. Im Test lieferte der Etikettenendpunkt:

label HTTP 200 type=image/png size=11283
label.png: PNG image data, 526 x 242, 8-bit/color RGB, non-interlaced

Breite und Höhe steuern HBOX_LABEL_MAKER_WIDTH (526) und HBOX_LABEL_MAKER_HEIGHT (200). Bei längeren Texten wächst die Höhe, weil HBOX_LABEL_MAKER_DYNAMIC_LENGTH standardmäßig aktiv ist. HBOX_LABEL_MAKER_ADDITIONAL_INFORMATION druckt eine feste Zusatzzeile wie den Firmennamen. Direktdruck aus der Anwendung ist laut Dokumentation nur mit HBOX_LABEL_MAKER_PRINT_COMMAND aktiv, sonst meldet der Status "labelPrinting":false.

Ablaufende Garantien behalten Sie über Notifier oder den CSV-Export im Blick. Der Export lieferte im Test diese Kopfzeile, derselbe Spaltensatz dient dem Import aus einer bestehenden Tabelle:

HB.import_ref,HB.parent_import_ref,HB.location,HB.tags,HB.asset_id,
HB.archived,HB.url,HB.name,HB.quantity,HB.description,HB.insured,
HB.notes,HB.purchase_price,HB.purchase_from,HB.purchase_date,
HB.manufacturer,HB.model_number,HB.serial_number,HB.lifetime_warranty,
HB.warranty_expires,HB.warranty_details,HB.sold_to,HB.sold_price,
HB.sold_date,HB.sold_notes

HB.import_ref und HB.parent_import_ref bilden die Hierarchie ab. Notifier sprechen laut Dokumentation allgemeine Endpunkte an. Cloud-Metadaten-Adressen und Bogon-Netze sind standardmäßig blockiert, einschränkbar über HBOX_NOTIFIER_ALLOW_NETS und HBOX_NOTIFIER_BLOCK_NETS. Seit 0.27.0 sperrt Homebox laut Dokumentation zusätzlich Ziele auf localhost (HBOX_NOTIFIER_BLOCK_LOCALHOST: Standard true). Läuft ntfy oder Gotify auf demselben Host, tragen Sie im Notifier die LAN-Adresse des Hosts ein oder setzen den Schalter auf false. Private Netze nach RFC 1918 sperrt erst HBOX_NOTIFIER_BLOCK_LOCAL_NETS: "true", das empfiehlt sich bei offener Registrierung oder öffentlich erreichbarer Instanz.

Verifizieren: Das Etikett eines Geräts öffnet sich als PNG, der QR-Code führt beim Scannen auf den Datensatz, und der Export enthält die Kopfzeile oben.

Schritt 6: Reverse Proxy und Absicherung

Hinter einem Reverse Proxy muss HBOX_OPTIONS_TRUST_PROXY: "true" gesetzt sein. Ohne diesen Schalter wertet Homebox laut Dokumentation X-Forwarded-Proto nicht aus, erkennt HTTPS nicht, und Etiketten arbeiten nicht korrekt. Für Live-Aktualisierungen nutzt Homebox den WebSocket-Endpunkt /api/v1/ws/events, im Test antwortete er ohne Anmeldung mit HTTP 401. Nginx braucht dafür Upgrade-Header, Traefik und Caddy erledigen das selbst. Die offizielle Nginx-Konfiguration:

server {
    listen 443 ssl http2;
    server_name inventar.example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:7745;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
    }
}

Mit Traefik setzen Sie Labels am Dienst, entscheidend ist der interne Port 7745 (Einrichtung: Traefik als Reverse Proxy):

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.homebox.rule=Host(`inventar.example.com`)"
      - "traefik.http.routers.homebox.entrypoints=websecure"
      - "traefik.http.routers.homebox.tls.certresolver=letsencrypt"
      - "traefik.http.services.homebox.loadbalancer.server.port=7745"

Lassen Sie die Anmelde-Drosselung aktiv (Standard: fünf Fehlversuche pro Minute, Backoff bis fünf Minuten) und HBOX_DEBUG_ENABLED auf false, denn der Debug-Listener gibt pprof- und expvar-Daten preis.

Verifizieren: curl -sI https://inventar.example.com/ liefert 200 mit gültigem Zertifikat, und die Browser-Entwicklerwerkzeuge zeigen für /api/v1/ws/events den Status 101 Switching Protocols.

Schritt 7: Backup und Wiederherstellung

Ein vollständiges Backup besteht aus dem PostgreSQL-Dump und dem Datenvolume. Beide Befehle liefen im Test, der Dump umfasste 47856 Byte, das Archiv mit einem Testanhang 468 Byte:

# Datenbank im eigenen Format sichern
docker compose exec -T homebox-db pg_dump -U homebox -d homebox -Fc > homebox.dump
# Anhaenge aus dem Volume sichern
docker run --rm -v homebox_homebox-data:/data:ro -v "$PWD":/backup alpine \
  tar czf /backup/homebox-data.tar.gz -C /data .

Die Wiederherstellung wurde im Test vollständig durchgespielt. Stoppen Sie zuerst die Anwendung, sonst blockieren offene Verbindungen das Löschen der Datenbank:

# Anwendung stoppen, Datenbank laeuft weiter
docker compose stop homebox
# Datenbank verwerfen und leer neu anlegen
docker compose exec -T homebox-db psql -U homebox -d postgres \
  -c "DROP DATABASE homebox;" -c "CREATE DATABASE homebox OWNER homebox;"
# Dump einspielen, bei jedem Fehler abbrechen
docker compose exec -T homebox-db pg_restore -U homebox -d homebox --exit-on-error < homebox.dump
# Gegenprobe direkt in der Datenbank
docker compose exec -T homebox-db psql -U homebox -d homebox -Atc \
  "SELECT name, serial_number, warranty_expires FROM entities WHERE name='ThinkPad T14 Gen 4';"
# Anwendung wieder starten
docker compose start homebox

Legen Sie Dump und Archiv auf ein Medium außerhalb des Hosts und prüfen Sie die Wiederherstellung regelmäßig auf einem Testsystem. Dump-Formate und Rollen vertieft die Anleitung zu pg_dump und pg_restore.

Verifizieren: Die Gegenprobe liefert den vorher angelegten Datensatz, im Test ThinkPad T14 Gen 4|PF-3XK91A|2029-02-10 00:00:00+00, und die Oberfläche antwortet nach dem Start wieder mit 200.

Schritt 8: Updates und Rollback

Ändern Sie für ein Update den Image-Tag in der compose.yaml. Container-Tags schreibt die Registry ohne führendes v, auch wenn das GitHub-Release so heißt.

# Zuerst sichern
docker compose exec -T homebox-db pg_dump -U homebox -d homebox -Fc > homebox-vor-update.dump
# Neue Images holen
docker compose pull
# Stack mit neuen Images neu erzeugen
docker compose up -d
# Logs auf Migrationsfehler pruefen
docker compose logs homebox --tail 50

Homebox spielt beim Start alle ausstehenden Migrationen per goose ein. Ein älteres Image findet danach ein neueres Schema vor. Ein Rollback heißt deshalb: altes Image starten und den Dump von vor dem Update einspielen. Seit 0.26 sind /v1/items/* und /v1/locations/* laut Migrationsanleitung durch /v1/entities/* ersetzt. Eigene Skripte gegen die API müssen Sie vor einem Update aus älteren Versionen anpassen.

Verifizieren: Die Logs enden mit Server is running on :7745, und /api/v1/status zeigt die neue Version.

Update von 0.26.2 auf 0.27.0

Im Test genügte der neue Tag 0.27.0 in der compose.yaml. Beim Start spielte goose die neuen Migrationen ein (successfully migrated database to version: 20260821000000), der Statusendpunkt meldete v0.27.0. Konto, Tags und ein vorher angelegtes Gerät waren erhalten, ein falsches Passwort wurde mit 401 abgewiesen, der WebSocket-Endpunkt ohne Anmeldung ebenfalls mit 401. Dump und Wiederherstellung wie in Schritt 7 funktionierten unter 0.27.0 unverändert.

0.27.0 schließt laut Release Notes 15 Sicherheitslücken, ein zeitnahes Update ist deshalb ratsam. Neu ist außerdem eine überarbeitete Suche: Standard bleibt die Datenbanksuche (HBOX_SEARCH_DRIVER), optional lässt sich Meilisearch anbinden. Für Suchen ohne Rücksicht auf Akzente nutzt Homebox auf PostgreSQL die Erweiterung unaccent und legt sie beim Start selbst an, im Test war sie danach in der Datenbank vorhanden. Fehlt dem Datenbankbenutzer das Recht dazu, legen Sie sie einmalig als Superuser mit CREATE EXTENSION IF NOT EXISTS unaccent; an.

Typische Fehler

Die folgenden Meldungen traten im Test auf oder wurden gezielt provoziert:

FehlerbildUrsacheLösung
failed to resolve reference "ghcr.io/...homebox:v0.27.0": not foundContainer-Tag mit führendem vTag 0.27.0 ohne v verwenden
panic: auth.api_key_pepper must be set to at least 32 bytesHBOX_AUTH_API_KEY_PEPPER fehlt oder ist zu kurzWert mit openssl rand -base64 48 erzeugen
Bind for 127.0.0.1:7745 failed: port is already allocatedHost-Port belegtLinks im ports-Eintrag einen freien Port wählen, rechts bleibt 7745
dial tcp 127.0.0.1:5432: connect: connection refused, danach panicHBOX_DATABASE_HOST steht auf localhostDienstnamen homebox-db eintragen
Leere assetId nach einem PUTVollständiges Update ohne assetId im RumpfInventarnummer bei API-Schreibzugriffen mitsenden
404 page not found bei /api/v1/locationsEndpunkt durch Entitäts-API ersetzt/api/v1/entities?isLocation=true
Falsches Protokoll, Etiketten scheitern hinter ProxyHBOX_OPTIONS_TRUST_PROXY fehltAuf true setzen, Proxy sendet X-Forwarded-Proto
failed to get latest github release im LogHost ohne InternetzugangHarmlos, HBOX_OPTIONS_GITHUB_RELEASE_CHECK: "false"

Häufige Fragen

Reicht SQLite statt PostgreSQL?

Für sehr kleine Bestände ja, SQLite ist der Standard (HBOX_DATABASE_DRIVER: sqlite3: Datei unter /data/.data/homebox.db). PostgreSQL erlaubt Dumps mit pg_dump im laufenden Betrieb, wie in Schritt 7 getestet.

Wie entfernen Sie Homebox vollständig?

docker compose down -v --remove-orphans löscht Container, Netzwerk und beide Volumes mit allen Daten unwiderruflich, im Test blieb danach kein Volume übrig. Ziehen Sie vorher ein Backup. Das Verzeichnis /opt/homebox löschen Sie anschließend selbst.

Können Sie Anhänge in S3 ablegen?

Laut Dokumentation ja, über HBOX_STORAGE_CONN_STRING mit einem S3-kompatiblen Ziel oder Google Cloud Storage. Unter Docker empfiehlt das Projekt den Standardwert file:///./ im Volume.

Fazit

Homebox ist keine CMDB, aber in einer Viertelstunde installiert, sparsam und so einfach, dass auch Kollegen ohne IT-Hintergrund es pflegen. Starten Sie mit PostgreSQL und festem Versionstag, schließen Sie die Selbstregistrierung, veröffentlichen Sie den Dienst nur über einen Reverse Proxy mit TLS und spielen Sie die Wiederherstellung einmal durch, bevor echte Daten darin liegen. Wächst der Bedarf, führt der CSV-Export in ein größeres System.

Weiterführende Anleitungen und Quellen

HomeboxDocker ComposeInventarverwaltungIT-Asset-ManagementPostgreSQLSelfhostingKleinunternehmen