# inventree A small, self-contained IT asset inventory system. The heart of inventree is a nested folder tree — like a file manager — for organizing physical and virtual IT assets (servers, switches, laptops, printers, etc.). - Single compiled Go binary, embedded HTML templates and static assets - SQLite storage (WAL mode, foreign keys, migrations) - Bootstrap 5 UI, minimal vanilla JavaScript (no Node/React/build step) - Session-based auth with two roles: Admin and User - Custom, admin-defined asset types with custom fields - CSV import/export, full-text-ish search with breadcrumbs ## Quick start ```sh go build -o inventree ./cmd/inventree ./inventree serve ``` Then open http://localhost:8080 and log in with: ``` Username: admin Password: admin ``` (This default account is created intentionally on first run. Change or disable it via the Users admin page once you're up and running.) The database file is created automatically at `data/inventree.db` on first run, with migrations applied and seed data (default statuses, item types, and the admin account) inserted. ## CLI ```sh inventree # same as `inventree serve` inventree serve # start the web server inventree version # print the version inventree database migrate # apply pending migrations and exit inventree database backup [path] # write a consistent VACUUM INTO snapshot ``` `serve` flags: | Flag | Default | Description | |---------------------|------------------------|--------------------------------------------| | `-addr` | `:8080` | Listen address | | `-db` | `data/inventree.db` | Path to the SQLite database file | | `-secure-cookies` | `false` | Mark the session cookie `Secure` (enable when serving over HTTPS) | `/healthz` is available for load balancer / container health checks. ## The inventory tree The Inventory page is the default page after login and the center of the application: a folder/asset tree on the left, and a detail panel on the right that shows whatever is selected (a folder's contents, or a single asset). - **Folders** can nest arbitrarily deep, and contain both subfolders and assets. - **Expand/collapse** state is remembered per user (persisted server-side), and folder contents are fetched lazily via small AJAX requests — the page never fully reloads when you browse the tree. - **Drag and drop** folders and assets onto another folder (or onto "Inventory" itself) to move them. Admin only. - **Right-click-style actions**: each folder has a "…" action menu (New Subfolder, Add Asset, Rename, Delete). - **Deleting a folder** that still contains subfolders or assets requires confirmation, and offers a safe "move contents elsewhere" option instead of an accidental cascade. A "permanently delete everything inside" option is also available for when that's genuinely what you want. - **Search** (top of the tree pane) looks across asset ID, name, folder name, item type, assigned user, notes, and custom field values, and shows each result's full folder breadcrumb. ## Item types and custom fields Admins can define arbitrary asset types (Laptop, Switch, Firewall, …) under **Item Types**, each with its own set of custom fields (text, long text, number, date, boolean, dropdown, URL, IP address), marked required or not, with a default value and display order. A representative starter set of types and fields is seeded on first run — feel free to edit or delete it. ## CSV import / export - **Export**: from the Inventory toolbar, or `/export/assets.csv` (optionally scoped to a folder, with `?recursive=1` to include subfolders). Includes one `cf_` column per distinct custom field in use. - **Import**: CSV with columns `Asset ID` (optional — auto-generated if blank), `Name`, `Item Type`, `Folder` (a `/`-separated path, e.g. `Main Office/Network`), `Status`, `Assigned User`, `Notes`, plus `cf_` columns for custom fields. Existing assets are matched and updated by Asset ID; everything else is created. Missing folders in the path can optionally be created automatically. A full backup/restore of everything (folders, assets, types, custom fields, statuses) is just `inventree database backup` — it's a consistent snapshot of the whole SQLite database. ## Project layout ``` cmd/inventree/ CLI entrypoint (serve, version, database migrate/backup) internal/ auth/ session management, secure cookies database/ SQLite connection, pragmas, migrations migrations/ embedded .sql migration files models/ shared domain types folders/ nested folder tree assets/ asset CRUD, search, CSV import/export itemtypes/ admin-defined types + custom field definitions users/ accounts statuses/ configurable asset statuses settings/ key/value app settings web/ HTTP router, handlers, template rendering web/ templates/ Go html/template pages and partials (embedded) static/ Bootstrap 5, Bootstrap Icons, app.css, app.js (embedded) deploy/ systemd unit example ``` ## Development ```sh go build ./... go vet ./... go test ./... ``` The SQLite driver is [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite), a pure-Go implementation, so `CGO_ENABLED=0` builds work out of the box and the compiled binary has no C library dependencies. ## Docker ```sh docker compose up --build ``` This builds the image, starts inventree on port 8080, and persists the database in a named volume (`inventree-data`, mounted at `/app/data`). Or directly: ```sh docker build -t inventree . docker run -p 8080:8080 -v inventree-data:/app/data inventree ``` ## systemd See `deploy/inventree.service` for an example unit. Adjust the paths, then: ```sh sudo useradd --system --home /opt/inventree --shell /usr/sbin/nologin inventree sudo mkdir -p /opt/inventree/data sudo cp inventree /opt/inventree/inventree sudo chown -R inventree:inventree /opt/inventree sudo cp deploy/inventree.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now inventree ``` ## Scope inventree is intentionally a focused MVP: folders, assets, custom types, statuses, users, search, and CSV import/export. It does not include ticketing, purchasing, monitoring, RMM, MDM, or accounting features — if you need those, look elsewhere and integrate via CSV.