GroveMap

GroveMap

Docker app from BobbySmalls' Repository

Overview

Web-based disk usage analyzer with interactive treemap visualization. Mount your Unraid shares to see what's consuming your storage. Drill down into folders, filter by file name, extension, or date. Lightweight, read-only, no database required.

GroveMap icon

GroveMap

Disk usage analyzer with an interactive treemap web UI.
Built for Unraid but runs anywhere Docker does.

GroveMap treemap view GroveMap tree list view

Mount any directories into the container and GroveMap will scan them, cache the results, and present an interactive treemap you can drill into. Filter files by name, extension, or date to find what's eating your storage.

Quick Start

docker build -t grovemap .
docker run -d -p 8080:8080 -v /mnt/user:/data/user:ro --name grovemap grovemap

Open http://your-server:8080.

Features

  • Interactive treemap - proportional visualization of disk usage, click to drill down
  • Tree list view - sortable hierarchical breakdown with size bars and modified dates; toggle between treemap and tree from the header
  • Multiple volumes - mount as many directories as you need under /data/
  • Filtering - search by file name, extension, or modification date range
  • Background scanning - UI stays responsive while scans run
  • Auto-discovery - any directory under /data/ becomes a scannable root
  • Read-only - all mounts use :ro, GroveMap never modifies your files

Configuration

Environment Variable Default Description
SCAN_CACHE_TTL 300 Seconds to cache scan results before they expire
SCAN_ON_START true Automatically scan all roots when the container starts
DATA_ROOT /data Base path where mounted volumes are discovered
PORT 8080 Web UI port (change CMD in Dockerfile if needed)

Unraid Installation

Via Docker CLI

docker run -d \
  --name grovemap \
  -p 8080:8080 \
  -v /mnt/user/media:/data/media:ro \
  -v /mnt/user/documents:/data/documents:ro \
  -e SCAN_CACHE_TTL=300 \
  --restart unless-stopped \
  grovemap

Via Unraid Docker UI

  1. Go to Docker > Add Container
  2. Set Repository to grovemap (or your built image name)
  3. Add a Port mapping: host 8080 -> container 8080
  4. Add Path mappings for each directory to scan:
    • Host: /mnt/user/media -> Container: /data/media, Access: Read Only
  5. Set WebUI to http://[IP]:[PORT:8080]

An Unraid template XML is included in unraid-template.xml.

Development

Prerequisites

  • Python 3.12+
  • Node.js 20+
  • npm

Backend

cd backend
pip install -r requirements.txt
DATA_ROOT=./test-data STATIC_DIR=../frontend/dist uvicorn main:app --reload --port 8080

Frontend

cd frontend
npm install
npm run dev

The Vite dev server runs on port 5173 and proxies /api requests to the backend on port 8080.

Project Structure

grovemap/
├── Dockerfile              # Multi-stage build (node + python-alpine)
├── docker-compose.yml      # Local testing with Docker
├── unraid-template.xml     # Unraid Community Apps template
├── backend/
│   ├── requirements.txt    # fastapi, uvicorn
│   ├── main.py             # API routes + SPA serving
│   ├── scanner.py          # Recursive directory scanner (os.scandir)
│   └── cache.py            # In-memory TTL cache with background scanning
└── frontend/
    ├── package.json
    ├── vite.config.ts      # Dev proxy to backend
    └── src/
        ├── App.tsx         # Root selector / treemap view routing
        ├── api/client.ts   # React Query hooks
        ├── utils.ts        # formatSize, formatDate, color palette
        └── components/
            ├── RootSelector.tsx   # Volume cards with scan status
            ├── TreemapView.tsx    # Main view: shared header + view toggle
            ├── Treemap.tsx        # d3-hierarchy SVG treemap
            ├── TreeListView.tsx   # Sortable hierarchical list with size bars
            ├── ViewToggle.tsx     # Treemap / Tree segmented control
            ├── Breadcrumb.tsx     # Drill-down navigation
            ├── FilterPanel.tsx    # Name/extension/date filters
            ├── FileList.tsx       # Filtered file results table
            └── ScanStatus.tsx     # Scan progress indicator

API Endpoints

Method Endpoint Description
GET /api/roots List mounted volumes with scan status
GET /api/tree?root=...&depth=3&path=... Directory tree with sizes
GET /api/files?root=...&name=...&extension=... Filtered file listing
POST /api/scan?root=... Trigger a rescan
GET /api/status Scan status for all roots

Architecture Decisions

  • No database - scan results are cached in memory with a configurable TTL. For datasets under 500K files, a full scan completes in seconds and the memory footprint is manageable.
  • Depth-limited tree responses - the API returns trees truncated at a configurable depth. The frontend requests deeper levels on drill-down to avoid sending massive payloads.
  • Background scanning - scans run in a daemon thread. The API serves cached data while a rescan is in progress, and the frontend polls for completion.
  • Read-only mounts - volumes are mounted as :ro by default. The scanner only reads file metadata (os.scandir + stat), never modifies files.

License

MIT

Media gallery

Install GroveMap on Unraid in a few clicks.

Find GroveMap in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for GroveMap Review the template variables and paths Click Install

Related apps

Explore more like this

Explore all

Details

Repository
ghcr.io/robsmallridge/grovemap:latest
Last Updated2026-06-25
First Seen2026-06-01

Runtime arguments

Web UI
http://[IP]:[PORT:8080]
Network
bridge
Shell
sh
Privileged
false

Template configuration

WebUI PortPorttcp

Port for the web interface

Target
8080
Default
8080
Value
8080
Share 1Pathro

First directory to analyze

Target
/data/share1
Default
/mnt/user
Value
/mnt/user
Share 2Pathro

Second directory to analyze (optional)

Target
/data/share2
Share 3Pathro

Third directory to analyze (optional)

Target
/data/share3
Cache TTLVariable

Seconds to cache scan results

Target
SCAN_CACHE_TTL
Default
300
Value
300
Scan on StartVariable

Auto-scan when container starts

Target
SCAN_ON_START
Default
true
Value
true