Skip to content

Repository files navigation

CableMap

Physical network documentation for home labs and small offices. Map your devices, ports, cable runs, patch panels, and racks — then keep a visual, searchable record of what's plugged into what, backed up with real photos of your gear.

CableMap is a self-hosted web app (Node + SQLite) with a dark, keyboard-friendly UI. It's built for the person who has traced one cable too many and wants to write it down once. As of v0.8.0 it also imports from your UniFi controller and DNS/DHCP servers, tracks device uptime, alerts you when something changes, and can print a PDF documentation pack.

License: MIT Node Status


Screenshots

Dashboard Racks
Dashboard Rack elevation
At-a-glance counts, quick search, and recent activity. Front-of-rack "U" elevation with per-rack photos.
VLAN Manager
VLAN manager
Manage VLANs and see the connections assigned to each.

Why

Home labs grow organically. You add a switch, a NAS, an AP, a UPS — and six months later you can't remember whether port 14 on the core switch goes to the office wall jack or the garage. CableMap is a focused record-keeping tool for exactly that:

  • Write down the trace — port A → patch panel → port B, with cable type, color, length, and VLAN.
  • Prove it with a photo — attach pictures of the actual cable run, the device, or the whole rack.
  • See it two ways — a fast searchable table for daily lookups, and a visual canvas + rack elevation for planning and documentation.

Features

  • Devices, ports & connections — full CRUD with a port-conflict-aware connection model (a port can only hold one active connection at a time).
  • Bulk patching — patch a whole range of ports between two devices at once (switch 1–24 → panel 1–24), with a row-by-row preview and per-row conflict validation.
  • Patch panel support — front/back port pairs are modeled as linked ports, so a cable trace follows through the panel automatically.
  • Port trace algorithmGET /api/ports/:id/trace walks the physical path hop-by-hop (including patch-panel pass-through and cycle detection).
  • Rack elevation view — a real "U" diagram driven by each device's rack position, with real front/rear device images (via the NetBox import), drag-to-reposition, and PNG export. Passive occupants (UPS, shelves, blank panels) take up space too.
  • Connection-aware rack view — click a device in the elevation to see its cable runs drawn as arcs along the rack rail, color-coded by cable type, with runs that leave the rack tagged. The rack view answers "follow that cable" in physical space.
  • NetBox devicetype-library import — search 5,000+ community device definitions (CC0) and import any model as an editable template with accurate ports, power outlets, and front/rear elevation images. Devicetype YAML flows both ways: upload a local .yaml, or export any template back to the library format. Half-U gear and pass-through patch panels import correctly.
  • Rack layout import — bootstrap racks from a NetBox devices JSON export or a Rackula layout file: racks + placed devices (half-U supported), with template matching for types and images.
  • LLDP/CDP link discovery — poll a managed switch over SNMP to learn what's plugged into what, and confirm the proposed links into real connections (optional net-snmp dependency; managed gear only).
  • IPAM-lite — subnets (VLAN-linked) with live usage bars, per-address assignments, next-free suggestions, and one-click import of device management IPs.
  • Cable schedule — a registry of every physical run (cable ID, from/to device+port+location, type, connector, color, length, VLAN) with CSV export; plus scannable device QR codes for field lookup.
  • Asset & lifecycle — serial/asset tag/supplier/cost and purchase/warranty/EOL dates per device, with an Assets dashboard rolling up out-of-warranty, EOL-soon, and estimated fleet value.
  • Multi-user & API tokens — admin/editor/viewer accounts (viewers read-only) and hashed API tokens for scripted access (Authorization: Bearer / X-API-Key), on top of the env-configured bootstrap admin.

Live & Connected (v0.8.0)

CableMap Live & Connected — sources (UniFi, DNS/DHCP, firewalls, LLDP) feed an import-and-reconcile core that produces IPAM, devices, links, uptime history, notifications, and PDF docs

  • UniFi controller import — pull UniFi devices & switch ports into your inventory and queue client uplinks as proposed links (reviewed in the same confirm-before-write queue as LLDP). Works with UniFi OS (UDM/UDR/Cloud Key Gen2+) and legacy software controllers.
  • DNS/DHCP → IPAM import — a multi-source adapter for AdGuard Home, Pi-hole, Technitium, OPNsense, pfSense, MikroTik, UniFi, Firewalla, plus generic dnsmasq / ISC dhcpd / Kea CSV / hosts / CSV files. Preview a diff, then apply into IPAM. Pull from a live API or paste/upload the data.
  • Uptime & latency history — the reachability monitor now records a time-series; device pages show a 24h uptime bar and latency sparkline, and the dashboard shows overall availability.
  • Notifications & webhooks — opt-in alerts on device down/up, warranty/EOL approaching, or health regressions via ntfy, generic webhook, Discord, Slack, or email (SMTP), deduped so you're not spammed.
  • PDF documentation pack — one-click branded PDF (device inventory, rack elevations, cable schedule, IPAM, power) for handoff, compliance, or an MSP deliverable.
  • Canvas view — a React Flow topology map with device nodes, color-coded cable edges, draggable layout, VLAN/location filtering, live-status overlay, themes, uplink-aware auto-layout, and PNG/SVG export.
  • Reachability monitoring — opt in per device (ping / HTTP / HTTPS / TCP) with live online/offline status in the list, on device detail, on the canvas, and on the dashboard, plus uptime history and optional notifications. A lightweight documentation aid, not a full NOC. Configurable sweep interval; set MONITOR_INTERVAL_SECONDS=0 to disable.
  • Network discovery — sweep a subnet (/24/30) to find live hosts (IP, MAC + vendor, hostname) and approve them into your inventory from a pending queue. Pings only; no port scanning.
  • Read-only share links — revocable, no-login "live view" links for a wall display or a colleague (structure + status + connections; no photos, no editing).
  • Interop — JSON topology export (and a tokenized public feed) for other tools, plus an optional MCP server so an AI assistant can query the physical record.
  • Power mapping & load budgeting — model UPS/PDU outlets and which device each one feeds (with receptacle types and estimated draw), give a power source its rated capacity, and watch a live load bar with overload warnings. Device detail shows an outlet map for power sources and a "powered by" panel for everything else.
  • Health check — audits your documentation for inconsistencies: double-booked ports, rack-U overlaps, overloaded power sources, unmapped power, devices with no ports, and stale planned connections.
  • Change history — an append-only timeline of every device, connection, and power change, with a global History page and a per-device view.
  • Photos & documents — attach images (cable traces, device shots, rack photos) with auto-generated thumbnails, plus PDF spec sheets and Visio stencils. There's also a free-form photo gallery.
  • Full backup & restore — one-click ZIP of all data + uploaded files, and a guarded restore.
  • 344 built-in device templates across 25+ vendors — pick a model and the device form auto-fills make, type, rack height, ports, and (for UPS/PDU) outlets.
  • Custom templates — create your own gear (manufacturer, model, OS/firmware, form factor, ports, photo, spec sheet, product URLs). Built-ins are read-only; your custom ones are fully editable down to individual ports.
  • VLAN manager, full-text search, CSV import/export, and PDF port-map export.
  • Role-based multi-user auth (admin / editor / viewer) with API tokens, dark-mode-only UI, mobile-friendly list/search views.

Built-in template library

344 templates spanning networking, security, NAS, and power gear, including:

  • Ubiquiti — the UniFi lineup (gateways, switches, access points, aggregation)
  • Firewalls / NGFW — Fortinet (FortiGate/FortiSwitch/FortiAP, D/E/F gens), Palo Alto Networks (PA-200 → PA-5400), Cisco (ASA, Firepower, Secure Firewall), Cisco Meraki MX, Netgate/pfSense, OPNsense, Sophos XGS, SonicWall TZ, Protectli
  • Switches / APs — Cisco Catalyst (1200/1300, 2960-X, 3850, 9200/9300) & Meraki MS/MR, TP-Link Omada, MikroTik, Netgear, Aruba Instant On
  • NAS — Synology, QNAP, TrueNAS/iXsystems, Asustor, UGREEN, Drobo, plus custom DIY builds
  • UPS / power — APC, CyberPower, Eaton, Tripp Lite, Vertiv (rackmount + tower/desktop), plus rack PDUs — all with outlet definitions
  • Generic — patch panels, rackmount servers, UPS, shelves/drawers, blank rackspace, DIY

⚠️ Template port layouts are best-effort reference data to save you typing — not a guaranteed spec sheet. Every value is editable after you add a device, and you can create your own custom templates. Corrections via PR are welcome.

Need something not in the built-in library? Use Import from NetBox on the Templates page to pull any of 5,000+ community device definitions (ports, outlets, and rack images included).


Tech stack

Layer Technology
Frontend React + Tailwind CSS, bundled with Vite
Canvas React Flow (reactflow)
Charts Inline SVG (no chart library)
Backend Node.js 22 + Express
Database SQLite via better-sqlite3
Auth express-session + bcrypt; multi-user roles + hashed API tokens
Images sharp (server-side thumbnails)
Export CSV + PDF (pdfkit) + QR (qrcode)
Optional net-snmp (LLDP), nodemailer (email alerts), @modelcontextprotocol/sdk (MCP)

Quick start (local)

Prerequisites: Node.js 22 LTS and npm. (It still runs on Node 20+, but Node 20 reached end-of-life in April 2026 — use 22.)

git clone https://github.com/breed007/CableMap.git
cd CableMap

# Install root, client, and server dependencies
npm run install:all

# Configure environment (change the secrets!)
cp .env.example .env
#   edit .env → set SESSION_SECRET and ADMIN_PASSWORD

# Initialize the database (creates tables, seeds locations, VLANs, templates)
npm run db:init

# Run client (Vite) + server (Express) together
npm run dev

Log in with the ADMIN_USERNAME / ADMIN_PASSWORD from your .env.

Production build

npm run build     # builds the React app into server/public/
npm start         # serves the app + API from Express on PORT (default 3000)

Docker

cp .env.example .env   # edit secrets
docker compose up -d

The app runs on port 3000 and stores everything (database, sessions, uploaded photos) in a named volume mounted at /data. See docs/deployment-docker.md for update, backup, and reset instructions.


Proxmox VE (one-command LXC)

Running Proxmox? Create a ready-to-go container in one line — run this on the Proxmox host as root:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/breed007/CableMap/main/scripts/proxmox-lxc-install.sh)"

It spins up a Debian 13 LXC (defaults: 2 vCPU · 2048 MiB · 8 GiB, unprivileged), installs CableMap as a systemd service, and prints the URL plus a generated admin password. Pick Advanced at the prompt to change resources, hostname, or set a static IP. Update later by re-running pct exec <CTID> -- bash /root/lxc-setup.sh. Full details in scripts/README.md.


Configuration

All configuration is via environment variables (see .env.example):

Variable Default Description
PORT 3000 HTTP port
SESSION_SECRET changeme Session signing secret — change this
ADMIN_USERNAME admin Login username
ADMIN_PASSWORD changeme Login password (plaintext, or a bcrypt hash) — change this
DATA_DIR ./data Directory for the DB, sessions, and uploads
DB_PATH ./data/cablemap.db SQLite database path
MONITOR_INTERVAL_SECONDS 60 Reachability sweep interval; 0 disables the background checker
COOKIE_SECURE false Set true when behind an HTTPS reverse proxy (marks the session cookie Secure)
HISTORY_RETENTION 5000 Max history rows kept; older rows are pruned hourly (0 disables)
UPTIME_RETENTION_DAYS 30 Days of reachability samples kept for the uptime charts
NOTIFY_COOLDOWN_MINUTES 15 Minimum gap between repeat notifications for the same event
PUBLIC_BASE_URL (request host) Base URL embedded in device QR codes (set when behind a proxy)

To use a hashed admin password instead of plaintext:

node -e "require('bcrypt').hash('your-password', 10).then(h => console.log(h))"
# paste the $2b$... output as ADMIN_PASSWORD

Deployment


Project structure

CableMap/
├── client/          React + Vite frontend
│   └── src/
│       ├── pages/        Dashboard, Devices, Connections, Canvas, Racks, Templates, …
│       ├── components/   Sidebar, Modal, PhotoUploader, DocumentUploader, icons
│       └── utils/        API client, color/label maps
├── server/          Express backend
│   ├── db/               schema, seeds (templates), init/migrations
│   ├── routes/           devices, ports, connections, vlans, attachments, templates, …
│   └── utils/            tracePath (port-trace algorithm)
├── docs/            Deployment guides
└── data/            SQLite DB + uploads (gitignored)

API overview

All routes are under /api/ and require an authenticated session.

GET|POST        /api/locations              GET /api/locations/:id   (rack elevation)
GET|POST        /api/devices                PUT /api/devices/:id/position
POST            /api/devices/:id/ports/bulk-create
GET|PUT|DELETE  /api/ports/:id              GET /api/ports/:id/trace
GET|POST        /api/connections            POST /api/connections/bulk   (bulk patch)
GET|POST        /api/vlans
GET|POST|PUT|DELETE /api/device-templates   (custom templates editable; built-ins read-only)
GET|POST|PUT|DELETE /api/attachments        (images + PDF/Visio docs)
GET|POST|PUT|DELETE /api/power/outlets      POST /api/power/outlets/bulk-create
GET|POST|PUT|DELETE /api/power/connections  (outlet → device power mapping)
GET             /api/history                GET /api/history/device/:id
GET             /api/health                 (consistency / completeness checks)
POST            /api/devices/:id/check      POST /api/monitor/check-all  (reachability)
POST            /api/discovery/scan         GET /api/discovery   POST /api/discovery/:id/import
GET             /api/netbox/search?q=       POST /api/netbox/import  (devicetype-library)
POST            /api/netbox/import-yaml     GET /api/device-templates/:id/netbox.yaml
POST            /api/import/rack            (NetBox / Rackula rack layouts)
GET             /api/elevations/:file       POST /api/elevations/upload
GET|POST|PUT|DELETE /api/ipam/subnets       /api/ipam/addresses  (IPAM)
POST            /api/lldp/poll              GET /api/lldp  POST /api/lldp/:id/import  (link discovery)
GET             /api/cable-schedule         GET /api/cable-schedule/export.csv
GET             /api/qr/device/:id.svg      GET /api/assets/lifecycle
GET             /api/monitor/history/:id    GET /api/monitor/uptime  (uptime + latency)
GET|POST|PUT|DELETE /api/notifications/channels  /api/notifications/rules  (admin only)
POST            /api/imports/preview        POST /api/imports/apply  POST /api/imports/sources/:id/run  (DNS/DHCP)
POST            /api/unifi/test             POST /api/unifi/preview  POST /api/unifi/import
GET             /api/export/documentation.pdf  (documentation pack)
GET|POST|PUT|DELETE /api/users              /api/tokens  (admin only)
GET|POST|DELETE /api/share                  (read-only share links)
GET             /api/public/:token/snapshot GET /api/public/:token/topology.json  (no auth)
GET             /api/export/topology.json   (interop)
GET             /api/backup/export          POST /api/backup/import
GET             /api/search?q=              GET /api/summary
POST            /api/import/connections     GET /api/export/connections
GET             /api/export/device/:id/pdf

AI / MCP server (optional)

CableMap ships an experimental MCP server that exposes the physical record as read-only tools (list_devices, get_device, list_connections, search, topology) so an AI assistant can answer questions like "what's plugged into the core switch?".

cd server
npm install @modelcontextprotocol/sdk   # optional dependency
DB_PATH=../data/cablemap.db npm run mcp  # stdio MCP server

It reads the SQLite database directly (via Node's built-in driver) and doesn't require the web server to be running.


Tests

The server has a test suite built on Node's built-in test runner and node:sqlite — no external dependencies to install. Requires Node 22+ for testing (which is also the recommended runtime; the app still runs on Node 20+).

cd server && npm test

CI (GitHub Actions) runs the server tests and a client build on every push/PR.


Contributing

Contributions are welcome — especially device template corrections and additions. To add or fix templates, edit server/db/seeds.js (the seedTemplates array) and open a PR. Each template lists its make, model, SKU, device type, rack height, and a default_ports array.

  1. Fork and create a branch.
  2. Make your change; run npm run build to confirm the client compiles.
  3. For schema changes, keep server/db/init.js migrations additive and idempotent.
  4. Open a pull request.

License

MIT © 2026 breed007


CableMap was designed for documenting your own network. It supports multiple accounts (admin/editor/viewer) and API tokens, but is still intended to run on a trusted LAN or behind a reverse proxy with HTTPS — not exposed directly to the public internet. Set COOKIE_SECURE=true behind HTTPS, and change ADMIN_PASSWORD / SESSION_SECRET from their defaults.

About

Self-hosted physical network documentation for home labs and small offices — devices, ports, cable runs, patch panels, racks, and photos.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages