Self-hosted HomeLab-Management— Devices, Docker, Proxmox, Pi-hole, Monitoring, all-in-one-App.
3.6K
Eine Sicht. Dein gesamtes HomeLab.
Self-hosted HomeLab-Verwaltung mit 28 Modulen und über 45 Dashboard-Widgets in einer App: Netzwerk-Discovery, Container, VMs, Backups, Mediaserver, IPAM, Notifications, PKI, Reverse-Proxy, SSO, Mesh-VPN, Adblocker, K8s, Audit-Trail, Notes/ToDos — alles untereinander verknüpft über Devices, IPs, MAC-Adressen, Hostnamen, Compose-Stacks und Container-IDs. Kein weiterer Single-Tool-Wrapper, sondern echte Cross-Tool-Sicht.
DeviceId-Link, Conflict-Detection gegen Pi-hole-/AdGuard-/Technitium-DHCP-Leases, „nächste freie IP".smartctl --json, Disk-Health-Aging, Scheduled-Scans.cost.electricityPriceEurPerKwh + cost.region).MinRoleId pro Widget / Tab.exec-Pfad als Alternative.Dieses Repo enthält beide Komponenten (Backend-API + Frontend-Web) und unterscheidet sie über das Tag-Prefix:
api-Image: .NET 10 ASP.NET Core Web API, hört auf Port 5099.
web-Image: nginx + statisches React-Bundle, hört auf Port 8080.
| Tag | Bedeutung |
|---|---|
api-latest / web-latest | Production-Stand. Wer ohne expliziten Tag pullt, bekommt freigegebenen Code — niemals dev. |
api-production / web-production | Identisch mit latest. Stabil, manuell promotet aus staging. |
api-staging / web-staging | UAT-Promotion aus dev. Snapshot für Integrationstests vor Production. |
api-dev / web-dev | Aktueller Entwicklungsstand. Pinning empfohlen, wenn du immer das Neueste willst (statt versehentlich auf production zu hängen). |
api-<MAJOR.MINOR.BUILD.REV> / web-… | Versions-Snapshots (Rollback-Historie). Bleiben dauerhaft in der Registry. Beispiel: api-0.46.330.624. |
Promotion-Pfad: dev → staging → production (+ latest-Tag mit-aktualisiert).
Promotions sind bewusste Operator-Entscheidungen, keine Automation. Versions-Tags
laufen niemals rückwärts — Rollback geht über das passende <rev>-Tag.
api-latest / web-latest (= production).<rev>-Tag pinnen.api-dev / web-dev.Linux-Host mit Docker + Docker Compose. Vier Schritte.
Der Vault verschlüsselt alle Secrets (API-Tokens, SSH-Keys, App-Passwörter) mit AES-256-GCM.
openssl rand -base64 32
Die Logs-Ansicht der App liest Container-Logs aus Loki — Vector liefert die Streams.
Lege zwei Config-Dateien neben deine docker-compose.yml:
config/loki-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9095
log_level: info
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore: { store: inmemory }
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index: { prefix: index_, period: 24h }
limits_config:
retention_period: 336h # 14 Tage
reject_old_samples: true
reject_old_samples_max_age: 168h
allow_structured_metadata: true
volume_enabled: true
compactor:
working_directory: /loki/compactor
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
delete_request_store: filesystem
analytics:
reporting_enabled: false
config/vector.yaml
data_dir: /var/lib/vector
api:
enabled: false
sources:
docker:
type: docker_logs
exclude_containers:
- imphomelab-vector
- imphomelab-loki
journald:
type: journald
journal_directory: /var/log/journal
include_units: []
transforms:
enrich_docker:
type: remap
inputs: [docker]
source: |
.source = "docker"
.compose_project = .label."com.docker.compose.project" || "(none)"
.compose_service = .label."com.docker.compose.service" || "(none)"
enrich_journald:
type: remap
inputs: [journald]
source: |
.source = "journald"
.container_name = "(host)"
sinks:
loki:
type: loki
inputs: [enrich_docker, enrich_journald]
endpoint: ${LOKI_ENDPOINT:-http://localhost:3100}
encoding: { codec: text }
labels:
source: "{{ source }}"
container: "{{ container_name }}"
image: "{{ image }}"
compose_project: "{{ compose_project }}"
compose_service: "{{ compose_service }}"
unit: "{{ _SYSTEMD_UNIT }}"
out_of_order_action: accept
remove_label_fields: true
batch:
max_bytes: 1048576
timeout_secs: 5
💡 Brauchst du nur Discovery + Dashboard + Monitoring ohne Logs-Ansicht? Dann diesen Schritt überspringen und die
loki/vector-Services unten weglassen.
docker-compose.yml anlegenservices:
api:
image: hawk18x/imphomelab-manager:api-latest
container_name: imphomelab-api
restart: unless-stopped
network_mode: host # Discovery braucht LAN-Zugriff (ICMP, ARP, mDNS, SSDP)
cap_add: [NET_RAW] # ICMP ohne Root
environment:
- ASPNETCORE_URLS=http://+:5099
- ConnectionStrings__Default=Data Source=/app/data/imphomelab.db
- IMPHOMELAB_MASTER_KEY=<OUTPUT_VON_SCHRITT_1>
volumes:
- ./data/api:/app/data
- ./data/logs:/app/logs
depends_on: [loki]
web:
image: hawk18x/imphomelab-manager:web-latest
container_name: imphomelab-web
restart: unless-stopped
network_mode: host # API ist via http://localhost:5099 erreichbar
depends_on: [api]
loki:
image: grafana/loki:3.0.0
container_name: imphomelab-loki
restart: unless-stopped
network_mode: host
command: ["-config.file=/etc/loki/local-config.yaml"]
volumes:
- ./data/loki:/loki
- ./config/loki-config.yaml:/etc/loki/local-config.yaml:ro
vector:
image: timberio/vector:0.40.0-debian
container_name: imphomelab-vector
restart: unless-stopped
network_mode: host
environment:
- LOKI_ENDPOINT=http://localhost:3100
volumes:
- ./data/vector:/var/lib/vector
- ./config/vector.yaml:/etc/vector/vector.yaml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/log/journal:/var/log/journal:ro
depends_on: [loki]
💡 Bridge-Network statt Host-Networking? Dann
network_mode: host+cap_addbei allen Services entfernen, ein gemeinsamesnetworks:-Feld definieren,ports: ["5099:5099"]+["8080:8080"]bei api/web ergänzen und invectorLOKI_ENDPOINT=http://loki:3100setzen. Discovery (mDNS, ARP, ICMP-Sweep) fällt dann aus — der Rest funktioniert.
docker compose up -d
# Healthcheck:
curl http://localhost:5099/healthz # {"status":"Healthy"}
# Loki ready?
curl http://localhost:3100/ready # ready
# UI im Browser:
# http://<host>:8080
Beim ersten Start legt die App die SQLite-DB an, führt EF-Migrationen aus und seedet die Default-Scheduled-Tasks (Discovery alle 15 min, Uptime 60 s, Cert-Check 12 h). Anschließend ist alles im UI konfigurierbar — Subnetze, Integrationen, Tags, Widgets, Benutzer.
Logs aktivieren: einmalig in Einstellungen → Logs die Loki-URL eintragen:
http://localhost:3100. Sobald gesetzt, listet die Logs-Section die Container-Streams live.
api-latest / web-latest zeigen immer auf den aktuellen Production-Stand
(neu seit RC1: war früher dev — siehe Tag-Schema oben). Für reproduzierbare
Deployments einen Versions-Tag pinnen, z. B. api-0.46.330.624 / web-0.46.329.1106.
docker compose pull
docker compose up -d
Wer das absolut Neueste haben will (auch nicht-promotete Builds), pinned auf api-dev / web-dev.
| Env-Variable | Pflicht | Default | Zweck |
|---|---|---|---|
IMPHOMELAB_MASTER_KEY | ja | — | 32-byte base64 oder Freitext (→ SHA-256). Vault-Master-Key. |
ConnectionStrings__Default | nein | Data Source=/app/data/imphomelab.db | SQLite-Pfad. Bind-Mount auf persistenten Storage empfohlen. |
ASPNETCORE_URLS | nein | http://+:5099 | API-Listen-Adresse. |
Alle weiteren Settings (Discovery-Intervalle, Polling-Raten, Integrationen,
Theme/Branding, Logs-Loki-URL, Modul-Toggles, Notification-Provider, Smart-Plugs,
Strompreis …) sind im UI unter Einstellungen persistiert. Module lassen sich
einzeln deaktivieren (module.<name>.enabled in AppSettings) — deaktivierte
Module blenden Tabs, Widgets und Hilfe-Topics aus.
/metrics, Healthcheck unter /healthz| Port | Container | Zweck |
|---|---|---|
8080 | web | UI (HTTP) |
5099 | api | REST + SignalR-Hubs (/hubs/events, /hubs/terminal) |
3100 | loki | Loki HTTP-API (intern) |
Auf manchen Hosts ist Port 8080 belegt — dann z. B. auf 8090 mappen.
Die Auto-Discovery (mDNS, SSDP, ARP-Cache-Read, ICMP-Sweep) funktioniert
nur mit network_mode: host auf Linux. Auf Docker Desktop (Windows/macOS)
greift sie nicht — der Container läuft dort in einer WSL2-VM, das LAN ist nicht
direkt sichtbar. Der Rest der App (Docker/Proxmox/Pi-hole/… über deren APIs,
Dashboard, Logs) funktioniert auch im Bridge-Mode.
cap_add: [NET_RAW] erlaubt ICMP-Pings ohne Root im Container.
Content type
Image
Digest
sha256:b063991db…
Size
27 MB
Last updated
8 days ago
docker pull hawk18x/imphomelab-manager:web-latest