SSE broadcasts the authoritative state before the HTTP response returns, so local setState calls in handlers caused every entry to appear twice. Handlers now only call the API and show notifications; SSE drives all state. Added a useEffect to keep selectedBookingForDetails in sync with the SSE-updated bookings list.
GhostGrid
GhostGrid is an internal network lab and device inventory tool for managing hardware lab environments.
The application uses an Express backend and a Vite/React frontend running in a single Node.js process. Data is stored locally in a SQLite database using better-sqlite3.
GhostGrid is designed to run fully offline. Fonts are bundled locally through @fontsource, and the application does not load external code, assets, or CDN resources at runtime.
Features
-
Dashboard
Overview of active and upcoming reservations, plus a quick links widget for frequently used tools. -
Bookings
Reserve complete lab topologies or individual devices for a defined time period. Bookings include conflict detection and device status validation. -
Inventory
Manage lab devices, including emergency and rescue information. Live device status is retrieved from CheckMK. -
Topology
Visualize devices and connections for each lab environment. -
Quick Links
Shared link dashboard for internal tools such as CheckMK, Semaphore, documentation, or jump hosts. -
Team
Overview of all registered users. -
Logbook
Shared audit and maintenance journal for lab activity, operational notes, and troubleshooting history.
Device Status
Device reachability is monitored in CheckMK and imported through the CheckMK API.
Each device can be linked to CheckMK using the CheckMK Host URL field. If no CheckMK binding is configured, the device status is set to unknown.
Devices with an unknown status are not available for booking.
Local Development
Requirements
- Node.js 20 LTS
Setup
npm install
npm run dev
The application will be available at:
http://localhost:3000
The development server runs the Express backend with Vite middleware.
Available Scripts
npm run dev
Start the local development server.
npm run build
Build the frontend into dist/ and bundle the server as dist/server.cjs.
npm start
Start the built production server. This expects NODE_ENV=production.
npm run lint
Run the TypeScript type check using tsc --noEmit.
Configuration
Configuration is loaded from environment variables or a local .env file. See .env.example for reference.
| Variable | Description |
|---|---|
JWT_SECRET |
Secret used to sign JSON Web Tokens. This must be set explicitly in production. Without a value, the application falls back to an insecure default. |
PORT |
HTTP port used by the application. Defaults to 3000. |
Deployment
Production deployment is intended to run inside a Proxmox LXC container using systemd.
For detailed deployment instructions, see:
DEPLOY.md
The container runs both branches in parallel:
| Branch | Purpose | Port |
|---|---|---|
main |
Production | 3000 |
dev |
Staging | 3001 |
Each branch runs as a separate systemd service and uses its own database.