LaunchPad
Ein moderner, minimalistischer Homelab-Launcher – inspiriert von Raycast, Spotlight, Arc und Linear. Tippe wenige Buchstaben, finde sofort den gewünschten Dienst, drücke Enter.
Kein überladenes Dashboard. Keine Kacheln. Im Mittelpunkt steht eine extrem schnelle Suche.
Quickstart (Docker)
git clone <repo-url> LaunchPad
cd LaunchPad
cp .env.example .env # optional anpassen, siehe unten
docker compose up -d --build
- Frontend: http://localhost:8080
- Backend / Health-API: http://localhost:3001/api/health
Quickstart (lokale Entwicklung)
Voraussetzungen: Node.js ≥ 20, pnpm ≥ 9.
pnpm install
pnpm dev:backend # startet Fastify auf :3001
pnpm dev:frontend # startet Vite auf :5173 (proxyt /api zum Backend)
Projektstruktur
LaunchPad
│
├── apps
│ ├── frontend React + Vite + TypeScript + TailwindCSS
│ └── backend Fastify + TypeScript + Drizzle ORM + SQLite
│
├── packages
│ ├── shared gemeinsame Typen (Device, Service) + Such-Ranking-Logik
│ └── ui gemeinsame UI-Komponenten (SearchInput, StatusBadge)
│
├── docker zusätzliche Docker-Hilfsdateien
├── docs Projektdokumentation
├── pnpm-workspace.yaml
├── docker-compose.yml
└── tsconfig.base.json
Stand dieses Commits
Dieser erste Commit liefert ein lauffähiges Grundgerüst:
- ✅ pnpm-Monorepo mit
apps/*undpackages/* - ✅ Fastify-Backend mit
/api/health-Endpunkt - ✅ SQLite-Datenbank (better-sqlite3) inkl. Schema für
devices,services,categories(Drizzle ORM), automatisch angelegt beim Start - ✅ React-Startseite mit Suchfeld, Dark-/Light-Mode und Live-Statusanzeige des Backends
- ✅ Tastaturkürzel
/undStrg+Kzum Fokussieren der Suche - ✅ Docker-Compose-Setup:
docker compose up -d --buildstartet Frontend + Backend - ✅ Persistentes Docker-Volume für die SQLite-Datenbank
- ✅ REST-API für Geräte & Dienste (
/api/devices,/api/services), Zod-validiert, mit Repository-Layer über Drizzle (sieheapps/backend/src/db/repositories) - ✅ Suche im Frontend gegen echte Backend-Daten (TanStack Query), inkl. Ranking-Logik
aus
packages/sharedund Tastatur-Navigation (Pfeiltasten, Enter, Escape) - ✅ Kategorien-API (
/api/categories), inkl. Umbenennen, Löschen (Dienste behalten ihre Zuordnung nicht, werden aber nicht gelöscht) und Bulk-Reorder für Drag & Drop - ✅ Favoriten-Toggle direkt in der Trefferliste (Stern anklicken)
- ✅ Scanner-Engine + API (
POST /api/scan/devices/:id,POST /api/scan/fritzbox): DNS-Kandidaten (hostname/.home/.local), Portscan (80, 443 + typische Ports), Titel-/Favicon-Auslesen, Softwareerkennung, FritzBox-Geräteliste per TR-064 (HTTP-Digest-Auth). Läuft ausschließlich manuell per API-Aufruf – nie automatisch. Benutzeränderungen an Diensten (Name, Kategorie, Favorit, Alias, Icon, Reihenfolge) bleiben bei erneuten Scans garantiert erhalten.
Noch nicht enthalten (folgt in den nächsten Commits):
- Adminbereich mit "Jetzt scannen"-Button und Kategorien-Verwaltungsoberfläche — beide Backend-APIs existieren bereits vollständig
- TanStack Router, Plugin-System, PWA-Manifest, shadcn/ui, RHF
Umgebungsvariablen (.env)
Alle Umgebungsvariablen sind in .env.example dokumentiert. Für die lokale
Entwicklung und für Docker Compose:
cp .env.example .env
# .env anpassen (v. a. FRITZBOX_* für den FritzBox-Scan)
.env ist in .gitignore und wird nie committet. Auf dem Server
(/opt/LaunchPad) muss sie nach dem ersten git pull einmalig manuell
angelegt werden, da git-ignorierte Dateien nicht mitgepullt werden:
cd /opt/LaunchPad
cp .env.example .env
nano .env # FRITZBOX_* eintragen
docker compose up -d --build
Fehlt .env komplett, startet alles trotzdem mit den in docker-compose.yml
hinterlegten Defaults – der FritzBox-Scan liefert dann kontrolliert HTTP 400
statt abzustürzen. Für pnpm dev:backend (ohne Docker) wird .env automatisch
über dotenv geladen (apps/backend/src/env.ts, wird als allererstes importiert).
Siehe docs/ROADMAP.md für die geplante Reihenfolge.
API-Endpunkte (Stand Commit 2)
GET /api/health
GET /api/devices Liste aller Geräte inkl. ihrer Dienste
GET /api/devices/:id
POST /api/devices
PATCH /api/devices/:id
DELETE /api/devices/:id (löscht zugehörige Dienste per Cascade)
GET /api/services optional ?deviceId=&category=&favorite=true
GET /api/services/:id
POST /api/services erfordert existierende deviceId
PATCH /api/services/:id
DELETE /api/services/:id
GET /api/categories
POST /api/categories
PATCH /api/categories/reorder Body: [{ id, order }, ...]
PATCH /api/categories/:id Umbenennen
DELETE /api/categories/:id Dienste behalten ihre category nicht mehr (null),
werden aber nicht gelöscht
POST /api/scan/devices/:id Netzwerk-Scan für ein Gerät (DNS, Ports, Titel,
Favicon, Softwareerkennung); legt/aktualisiert Dienste
POST /api/scan/fritzbox Liest Geräteliste der FritzBox per TR-064
(erfordert FRITZBOX_HOST/USERNAME/PASSWORD)
Deployment auf dem Server (xlc-launchpad)
cd /opt/LaunchPad
git pull
docker compose up -d --build
Branching
Entwicklung erfolgt ausschließlich auf dev. main bleibt der stabile Branch.