Rename project from inventree to vibetree

- go.mod module path (and every internal/vibetree import) inventree -> vibetree
- cmd/inventree/ -> cmd/vibetree/, deploy/inventree.service -> vibetree.service
- Default site name (seed data + the siteName template func's fallback)
  is now "vibetree", shown in the navbar, <title>, and login page
- Session cookie renamed inventree_session -> vibetree_session
- Default DB path data/inventree.db -> data/vibetree.db, CLI/log text,
  Dockerfile, docker-compose.yml, README, .gitignore/.dockerignore all
  updated to match

Existing installs: this changes the session cookie name (users will be
signed out once) and the default DB filename (point -db at your existing
file, or rename it, to keep your data).
This commit is contained in:
Owen
2026-08-17 17:14:52 -05:00
parent 14e2f3bb77
commit f3a959334f
47 changed files with 139 additions and 139 deletions
+1 -1
View File
@@ -3,4 +3,4 @@ data/
*.db-shm
*.db-wal
.git/
inventree
vibetree
+1 -1
View File
@@ -1,4 +1,4 @@
/inventree
/vibetree
/data/
*.db
*.db-shm
+7 -7
View File
@@ -9,19 +9,19 @@ RUN go mod download
COPY . .
ARG VERSION=dev
RUN go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" -o /out/inventree ./cmd/inventree
RUN go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" -o /out/vibetree ./cmd/vibetree
FROM alpine:3.20
RUN apk add --no-cache ca-certificates tzdata && \
addgroup -S inventree && adduser -S inventree -G inventree
addgroup -S vibetree && adduser -S vibetree -G vibetree
WORKDIR /app
COPY --from=build /out/inventree /usr/local/bin/inventree
RUN mkdir -p /app/data && chown -R inventree:inventree /app/data
COPY --from=build /out/vibetree /usr/local/bin/vibetree
RUN mkdir -p /app/data && chown -R vibetree:vibetree /app/data
USER inventree
USER vibetree
VOLUME ["/app/data"]
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s CMD wget -qO- http://127.0.0.1:8080/healthz || exit 1
ENTRYPOINT ["inventree"]
CMD ["serve", "-addr", ":8080", "-db", "/app/data/inventree.db"]
ENTRYPOINT ["vibetree"]
CMD ["serve", "-addr", ":8080", "-db", "/app/data/vibetree.db"]
+25 -25
View File
@@ -1,6 +1,6 @@
# inventree
# vibetree
A small, self-contained IT asset inventory system. The heart of inventree is a
A small, self-contained IT asset inventory system. The heart of vibetree is a
nested folder tree — like a file manager — for organizing physical and
virtual IT assets (servers, switches, laptops, printers, etc.).
@@ -14,8 +14,8 @@ virtual IT assets (servers, switches, laptops, printers, etc.).
## Quick start
```sh
go build -o inventree ./cmd/inventree
./inventree serve
go build -o vibetree ./cmd/vibetree
./vibetree serve
```
Then open http://localhost:8080 and log in with:
@@ -28,18 +28,18 @@ 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
The database file is created automatically at `data/vibetree.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
vibetree # same as `vibetree serve`
vibetree serve # start the web server
vibetree version # print the version
vibetree database migrate # apply pending migrations and exit
vibetree database backup [path] # write a consistent VACUUM INTO snapshot
```
`serve` flags:
@@ -47,7 +47,7 @@ inventree database backup [path] # write a consistent VACUUM INTO snapshot
| Flag | Default | Description |
|---------------------|------------------------|--------------------------------------------|
| `-addr` | `:8080` | Listen address |
| `-db` | `data/inventree.db` | Path to the SQLite database file |
| `-db` | `data/vibetree.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.
@@ -158,13 +158,13 @@ fresh one over a few peeled-off labels.
references with examples are documented right on that page.
A full backup/restore of everything (folders, assets, types, custom fields,
statuses, users) is just `inventree database backup` — it's a consistent
statuses, users) is just `vibetree database backup` — it's a consistent
snapshot of the whole SQLite database.
## Project layout
```
cmd/inventree/ CLI entrypoint (serve, version, database migrate/backup)
cmd/vibetree/ CLI entrypoint (serve, version, database migrate/backup)
internal/
auth/ session management, secure cookies
database/ SQLite connection, pragmas, migrations
@@ -201,33 +201,33 @@ the compiled binary has no C library dependencies.
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`).
This builds the image, starts vibetree on port 8080, and persists the
database in a named volume (`vibetree-data`, mounted at `/app/data`).
Or directly:
```sh
docker build -t inventree .
docker run -p 8080:8080 -v inventree-data:/app/data inventree
docker build -t vibetree .
docker run -p 8080:8080 -v vibetree-data:/app/data vibetree
```
## systemd
See `deploy/inventree.service` for an example unit. Adjust the paths, then:
See `deploy/vibetree.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 useradd --system --home /opt/vibetree --shell /usr/sbin/nologin vibetree
sudo mkdir -p /opt/vibetree/data
sudo cp vibetree /opt/vibetree/vibetree
sudo chown -R vibetree:vibetree /opt/vibetree
sudo cp deploy/vibetree.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now inventree
sudo systemctl enable --now vibetree
```
## Scope
inventree is intentionally a focused MVP: folders, assets, custom types,
vibetree 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.
+14 -14
View File
@@ -1,4 +1,4 @@
// Command inventree runs the inventree IT asset inventory server, or one of
// Command vibetree runs the vibetree IT asset inventory server, or one of
// its supporting subcommands (version, database migrate, database backup).
package main
@@ -14,8 +14,8 @@ import (
"syscall"
"time"
"inventree/internal/database"
"inventree/internal/web"
"vibetree/internal/database"
"vibetree/internal/web"
)
// version is set at build time via -ldflags "-X main.version=...".
@@ -36,11 +36,11 @@ func run(args []string) error {
case "serve":
return runServe(args[1:])
case "version":
fmt.Println("inventree", version)
fmt.Println("vibetree", version)
return nil
case "database":
if len(args) < 2 {
return fmt.Errorf("usage: inventree database <migrate|backup>")
return fmt.Errorf("usage: vibetree database <migrate|backup>")
}
switch args[1] {
case "migrate":
@@ -60,22 +60,22 @@ func run(args []string) error {
}
func printUsage() {
fmt.Println(`inventree - a small IT asset inventory system
fmt.Println(`vibetree - a small IT asset inventory system
Usage:
inventree [serve] Start the web server (default command)
inventree version Print the version
inventree database migrate Apply pending database migrations
inventree database backup [path] Write a consistent backup snapshot
vibetree [serve] Start the web server (default command)
vibetree version Print the version
vibetree database migrate Apply pending database migrations
vibetree database backup [path] Write a consistent backup snapshot
Flags for "serve":
-addr string listen address (default ":8080")
-db string path to the SQLite database file (default "data/inventree.db")
-db string path to the SQLite database file (default "data/vibetree.db")
-secure-cookies mark the session cookie Secure (enable when serving over HTTPS)`)
}
func dbPathFlag(args []string) (dbPath string, rest []string) {
dbPath = "data/inventree.db"
dbPath = "data/vibetree.db"
for i := 0; i < len(args); i++ {
if args[i] == "-db" && i+1 < len(args) {
dbPath = args[i+1]
@@ -137,7 +137,7 @@ func ensureDir(path string) error {
func runServe(args []string) error {
var (
addr = ":8080"
dbPath = "data/inventree.db"
dbPath = "data/vibetree.db"
secureCookies = false
)
for i := 0; i < len(args); i++ {
@@ -196,7 +196,7 @@ func runServe(args []string) error {
}
}()
log.Info("inventree listening", "addr", addr, "db", dbPath)
log.Info("vibetree listening", "addr", addr, "db", dbPath)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
return err
}
@@ -1,13 +1,13 @@
[Unit]
Description=inventree - IT asset inventory
Description=vibetree - IT asset inventory
After=network.target
[Service]
Type=simple
User=inventree
Group=inventree
WorkingDirectory=/opt/inventree
ExecStart=/opt/inventree/inventree serve -addr :8080 -db /opt/inventree/data/inventree.db
User=vibetree
Group=vibetree
WorkingDirectory=/opt/vibetree
ExecStart=/opt/vibetree/vibetree serve -addr :8080 -db /opt/vibetree/data/vibetree.db
Restart=on-failure
RestartSec=2
@@ -15,7 +15,7 @@ RestartSec=2
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/inventree/data
ReadWritePaths=/opt/vibetree/data
PrivateTmp=true
[Install]
+5 -5
View File
@@ -1,13 +1,13 @@
services:
inventree:
vibetree:
build: .
image: inventree:latest
container_name: inventree
image: vibetree:latest
container_name: vibetree
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- inventree-data:/app/data
- vibetree-data:/app/data
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/healthz"]
interval: 30s
@@ -16,4 +16,4 @@ services:
start_period: 5s
volumes:
inventree-data:
vibetree-data:
+1 -1
View File
@@ -1,4 +1,4 @@
module inventree
module vibetree
go 1.25.0
+3 -3
View File
@@ -11,9 +11,9 @@ import (
"strings"
"time"
"inventree/internal/folders"
"inventree/internal/models"
"inventree/internal/settings"
"vibetree/internal/folders"
"vibetree/internal/models"
"vibetree/internal/settings"
)
var (
+5 -5
View File
@@ -8,11 +8,11 @@ import (
"strings"
"testing"
"inventree/internal/assets"
"inventree/internal/database"
"inventree/internal/folders"
"inventree/internal/models"
"inventree/internal/settings"
"vibetree/internal/assets"
"vibetree/internal/database"
"vibetree/internal/folders"
"vibetree/internal/models"
"vibetree/internal/settings"
)
// Seed data from migrations/0002_seed.sql gives us stable IDs to rely on:
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"inventree/internal/models"
"vibetree/internal/models"
)
const (
+3 -3
View File
@@ -4,9 +4,9 @@ import (
"context"
"testing"
"inventree/internal/assets"
"inventree/internal/itemtypes"
"inventree/internal/models"
"vibetree/internal/assets"
"vibetree/internal/itemtypes"
"vibetree/internal/models"
)
func TestQuantityFixedAtOneForUniqueTypes(t *testing.T) {
+1 -1
View File
@@ -3,7 +3,7 @@ package assets
import (
"context"
"inventree/internal/models"
"vibetree/internal/models"
)
// Search performs a global, case-insensitive substring search across asset
+3 -3
View File
@@ -10,12 +10,12 @@ import (
"net/http"
"time"
"inventree/internal/models"
"inventree/internal/users"
"vibetree/internal/models"
"vibetree/internal/users"
)
const (
CookieName = "inventree_session"
CookieName = "vibetree_session"
SessionTTL = 7 * 24 * time.Hour
contextUserK = ctxKey("current_user")
)
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"path/filepath"
"testing"
"inventree/internal/auth"
"inventree/internal/database"
"inventree/internal/users"
"vibetree/internal/auth"
"vibetree/internal/database"
"vibetree/internal/users"
)
func testDB(t *testing.T) *sql.DB {
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"path/filepath"
"testing"
"inventree/internal/database"
"vibetree/internal/database"
)
func TestOpenSetsPragmasAndMigrates(t *testing.T) {
+1 -1
View File
@@ -1,4 +1,4 @@
-- Initial schema for inventree
-- Initial schema for vibetree
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
+1 -1
View File
@@ -14,7 +14,7 @@ INSERT INTO settings (key, value) VALUES
('asset_id_prefix', 'IT-'),
('asset_id_padding', '6'),
('asset_id_seq', '0'),
('site_name', 'inventree');
('site_name', 'vibetree');
INSERT INTO item_types (name, description, icon, enabled, sort_order) VALUES
('Laptop', 'Portable computer', 'bi-laptop', 1, 1),
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"fmt"
"time"
"inventree/internal/models"
"vibetree/internal/models"
)
var (
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"path/filepath"
"testing"
"inventree/internal/database"
"inventree/internal/folders"
"inventree/internal/models"
"vibetree/internal/database"
"vibetree/internal/folders"
"vibetree/internal/models"
)
func testDB(t *testing.T) *sql.DB {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strings"
"time"
"inventree/internal/models"
"vibetree/internal/models"
)
var (
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"path/filepath"
"testing"
"inventree/internal/database"
"inventree/internal/itemtypes"
"inventree/internal/models"
"vibetree/internal/database"
"vibetree/internal/itemtypes"
"vibetree/internal/models"
)
func testDB(t *testing.T) *sql.DB {
+1 -1
View File
@@ -1,4 +1,4 @@
// Package models defines the core domain types shared across inventree.
// Package models defines the core domain types shared across vibetree.
package models
import "time"
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"io"
"strings"
"inventree/internal/models"
"vibetree/internal/models"
)
type ImportResult struct {
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"strings"
"testing"
"inventree/internal/database"
"inventree/internal/statuses"
"vibetree/internal/database"
"vibetree/internal/statuses"
)
func testDB(t *testing.T) *sql.DB {
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"errors"
"time"
"inventree/internal/models"
"vibetree/internal/models"
)
var (
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"golang.org/x/crypto/bcrypt"
"inventree/internal/models"
"vibetree/internal/models"
)
var (
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"path/filepath"
"testing"
"inventree/internal/database"
"inventree/internal/models"
"inventree/internal/users"
"vibetree/internal/database"
"vibetree/internal/models"
"vibetree/internal/users"
)
func testDB(t *testing.T) *sql.DB {
+8 -8
View File
@@ -1,5 +1,5 @@
// Package web implements the HTTP server: routing, session middleware,
// template rendering, and all page/API handlers for inventree.
// template rendering, and all page/API handlers for vibetree.
package web
import (
@@ -9,13 +9,13 @@ import (
"net/http"
"time"
"inventree/internal/assets"
"inventree/internal/auth"
"inventree/internal/folders"
"inventree/internal/itemtypes"
"inventree/internal/settings"
"inventree/internal/statuses"
"inventree/internal/users"
"vibetree/internal/assets"
"vibetree/internal/auth"
"vibetree/internal/folders"
"vibetree/internal/itemtypes"
"vibetree/internal/settings"
"vibetree/internal/statuses"
"vibetree/internal/users"
)
// App holds every dependency HTTP handlers need: data stores, templates, and
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"net/http"
"strconv"
"inventree/internal/models"
"vibetree/internal/models"
)
type assetRequest struct {
+1 -1
View File
@@ -3,7 +3,7 @@ package web
import (
"net/http"
"inventree/internal/auth"
"vibetree/internal/auth"
)
type loginPageData struct {
+2 -2
View File
@@ -5,12 +5,12 @@ import (
"net/http"
"time"
"inventree/internal/assets"
"vibetree/internal/assets"
)
func (a *App) handleExportCSV(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
filename := fmt.Sprintf("inventree-assets-%s.csv", time.Now().Format("2006-01-02"))
filename := fmt.Sprintf("vibetree-assets-%s.csv", time.Now().Format("2006-01-02"))
w.Header().Set("Content-Type", "text/csv; charset=utf-8")
w.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"errors"
"net/http"
"inventree/internal/folders"
"inventree/internal/models"
"vibetree/internal/folders"
"vibetree/internal/models"
)
// handleFolderOptions returns every folder as a flat, indented list for
+2 -2
View File
@@ -3,8 +3,8 @@ package web
import (
"net/http"
"inventree/internal/assets"
"inventree/internal/models"
"vibetree/internal/assets"
"vibetree/internal/models"
)
// InventoryPageData is the top-level data passed to templates/pages/inventory.html.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"strconv"
"strings"
"inventree/internal/models"
"vibetree/internal/models"
)
type itemTypesListData struct {
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"strconv"
"strings"
"inventree/internal/assets"
"inventree/internal/models"
"vibetree/internal/assets"
"vibetree/internal/models"
)
// LabelTemplate describes a sheet of adhesive labels: cell size, grid, and
+1 -1
View File
@@ -3,7 +3,7 @@ package web
import (
"net/http"
"inventree/internal/models"
"vibetree/internal/models"
)
type SearchPanelData struct {
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"net/http"
"strconv"
"inventree/internal/models"
"vibetree/internal/models"
)
type settingsPageData struct {
@@ -17,7 +17,7 @@ type settingsPageData struct {
func (a *App) handleSettingsPage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
siteName, err := a.Settings.Get(ctx, "site_name", "inventree")
siteName, err := a.Settings.Get(ctx, "site_name", "vibetree")
if err != nil {
writeErr(w, http.StatusInternalServerError, err.Error())
return
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"net/http"
"net/url"
"inventree/internal/assets"
"inventree/internal/models"
"vibetree/internal/assets"
"vibetree/internal/models"
)
type settingsImportPageData struct {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"net/http"
"strconv"
"inventree/internal/models"
"vibetree/internal/models"
)
// parseRole maps a form's role value to a models.Role, defaulting to
+2 -2
View File
@@ -3,8 +3,8 @@ package web
import (
"net/http"
"inventree/internal/auth"
"inventree/internal/models"
"vibetree/internal/auth"
"vibetree/internal/models"
)
// loadSession attaches the current user (if any) to the request context
+3 -3
View File
@@ -10,7 +10,7 @@ import (
"strings"
"time"
content "inventree/web"
content "vibetree/web"
)
// templateFuncs are available to every template (pages and fragments).
@@ -101,9 +101,9 @@ func loadTemplates(a *App) (*templateSet, error) {
// used by layout.html for the <title> and navbar brand text.
appFuncs := template.FuncMap{
"siteName": func() string {
name, err := a.Settings.Get(context.Background(), "site_name", "inventree")
name, err := a.Settings.Get(context.Background(), "site_name", "vibetree")
if err != nil || name == "" {
return "inventree"
return "vibetree"
}
return name
},
+2 -2
View File
@@ -3,10 +3,10 @@ package web
import (
"net/http"
content "inventree/web"
content "vibetree/web"
)
// Router builds the complete HTTP handler for inventree: static assets,
// Router builds the complete HTTP handler for vibetree: static assets,
// authentication, the AJAX-driven inventory tree, and the traditional
// full-page admin sections (item types, users, settings).
func (a *App) Router() http.Handler {
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"context"
"fmt"
"inventree/internal/assets"
"inventree/internal/models"
"vibetree/internal/assets"
"vibetree/internal/models"
)
// treeAssetLimit bounds how many assets are rendered directly inside a
+4 -4
View File
@@ -11,9 +11,9 @@ import (
"strings"
"testing"
"inventree/internal/database"
"inventree/internal/models"
"inventree/internal/web"
"vibetree/internal/database"
"vibetree/internal/models"
"vibetree/internal/web"
)
func testApp(t *testing.T) *web.App {
@@ -49,7 +49,7 @@ func loginAs(t *testing.T, srv *httptest.Server, username, password string) *htt
t.Fatalf("expected redirect on login, got %d", res.StatusCode)
}
for _, c := range res.Cookies() {
if c.Name == "inventree_session" {
if c.Name == "vibetree_session" {
return c
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Package content embeds inventree's HTML templates and static assets
// Package content embeds vibetree's HTML templates and static assets
// (Bootstrap CSS/JS, icons, vanilla JS) into the compiled binary.
package content
+1 -1
View File
@@ -1,4 +1,4 @@
// inventree - vanilla JS driving the inventory tree and AJAX panels.
// vibetree - vanilla JS driving the inventory tree and AJAX panels.
// No build step, no frameworks: plain DOM APIs + fetch.
//
// Interaction model: the tree and panels behave like a native file manager.