{"id":48848506,"url":"https://github.com/renzynx/buh1","last_synced_at":"2026-04-15T06:37:08.041Z","repository":{"id":325580385,"uuid":"1101699775","full_name":"renzynx/buh1","owner":"renzynx","description":"A modern, self-hosted file storage solution built with Vike, React, and Hono. Features resumable TUS uploads, nested folders, built-in file previews, ShareX integration, and a robust admin dashboard with RBAC and 2FA for complete data sovereignty.","archived":false,"fork":false,"pushed_at":"2025-12-06T20:46:12.000Z","size":248,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-10T05:58:15.973Z","etag":null,"topics":["better-auth","docker","drizzle-orm","file-storage","file-upload","hono","self-hosted","shadcn","sharex","sqlite","tailwindcss","trpc","tus-protocol","typescript","vike"],"latest_commit_sha":null,"homepage":"https://zotari.systems","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/renzynx.png","metadata":{"files":{"readme":".github/README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-22T04:32:48.000Z","updated_at":"2025-12-06T20:46:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/renzynx/buh1","commit_stats":null,"previous_names":["renzynx/buh1"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/renzynx/buh1","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renzynx%2Fbuh1","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renzynx%2Fbuh1/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renzynx%2Fbuh1/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renzynx%2Fbuh1/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renzynx","download_url":"https://codeload.github.com/renzynx/buh1/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renzynx%2Fbuh1/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31830151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"online","status_checked_at":"2026-04-15T02:00:06.175Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["better-auth","docker","drizzle-orm","file-storage","file-upload","hono","self-hosted","shadcn","sharex","sqlite","tailwindcss","trpc","tus-protocol","typescript","vike"],"created_at":"2026-04-15T06:37:07.363Z","updated_at":"2026-04-15T06:37:08.019Z","avatar_url":"https://github.com/renzynx.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Buh 🚀\n\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![GHCR Image](https://img.shields.io/badge/ghcr-available-blue.svg)](https://github.com/renzynx/buh1/pkgs/container/buh1) [![Docker Image](https://img.shields.io/badge/docker-ready-blue.svg)](https://github.com/renzynx/buh1/pkgs/container/buh1) [![CI Status](https://img.shields.io/github/actions/workflow/status/renzynx/buh1/ci.yml?branch=master)](https://github.com/renzynx/buh1/actions)\n\nBuh is a modern, self-hosted file storage solution focused on privacy, speed, and data ownership. It functions as a personal cloud with an admin dashboard, role-based access control (RBAC), and ShareX integration — all runnable on your infrastructure.\n\n## Key Features ✨\n\n- **Resumable uploads** (TUS protocol) for reliable chunked uploads that resume after connection drops.\n- **Nested folders** with a hierarchical structure similar to desktop file explorers.\n- **Built-in previews** for images, video, audio, PDFs, and code in the browser.\n- **Fast search** across all folders by name or type.\n- **Bulk actions** (delete, download as ZIP).\n- **Public links \u0026 QR codes** for easy sharing.\n- **ShareX support** with a pre-configured `.sxcu` file for Windows screenshots.\n- **API keys** for automation and integrations.\n\n## Security \u0026 Administration 🔒\n\n- Secure authentication using Better Auth with HTTP-only cookies.\n- Optional 2FA via TOTP (Google Authenticator, Authy).\n- RBAC with three roles: `Superadmin`, `Admin`, and `User`.\n- Admin impersonation for safe troubleshooting.\n- Analytics dashboard for storage usage and activity.\n- System settings for upload limits, chunk sizes, and blocked extensions.\n- Per-user or global quotas and invite-only registration.\n\n## Tech Stack 🧰\n\n- Frontend: Vike (Vite + SSR) \u0026 React\n- Backend: Hono \u0026 Node.js\n- Database: SQLite (better-sqlite3) \u0026 Drizzle ORM\n- State \u0026 API: TanStack Query, Zustand, \u0026 tRPC\n- Styling: Tailwind CSS v4 \u0026 Shadcn UI\n\n## Getting Started 🏁\n\n### Requirements\n\n- Node.js v20+\n- pnpm\n\n### Local setup\n\nClone and install dependencies:\n\n```bash\ngit clone https://github.com/renzynx/buh.git\ncd buh\npnpm install\n```\n\nCreate a `.env` file (example):\n\n```env\nPORT=3000\nAUTH_BASE_URL=http://localhost:3000\nAPP_NAME=Buh\nDATABASE_URL=sqlite.db\nAUTH_SECRET=your_super_secret_string_min_32_chars\n```\n\nInitialize the database:\n\n```bash\npnpm run drizzle:push\n```\n\nRun in development:\n\n```bash\npnpm run dev\n```\n\nOpen http://localhost:3000 — the first registered user becomes `Superadmin`.\n\n### Production\n\nBuild and start the optimized server:\n\n```bash\npnpm run build\npnpm run start\n```\n\nRun in development:\n\n```bash\npnpm run dev\n```\n\nOpen http://localhost:3000 — the first registered user becomes `Superadmin`.\n\n### Production\n\nBuild and start the optimized server:\n\n```bash\npnpm run build\npnpm run start\n```\n\n## Docker deployment 🐳\n\n### Using docker compose (recommended)\n\nCreate a `.env` file:\n\n```env\nAUTH_SECRET=your_super_secret_string_min_32_chars_change_me\nAUTH_BASE_URL=http://localhost:3000\nAPP_NAME=Buh\n```\n\nUse the included `docker compose.yml`:\n\n```bash\ndocker compose up -d\n```\n\nOr create your own `docker compose.yml`:\n\n```yaml\nservices:\n  buh:\n    image: ghcr.io/renzynx/buh1:latest\n    container_name: buh\n    restart: unless-stopped\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DATABASE_URL=/app/db/sqlite.db\n      - AUTH_SECRET=${AUTH_SECRET}\n      - AUTH_BASE_URL=${AUTH_BASE_URL:-http://localhost:3000}\n      - APP_NAME=${APP_NAME:-Buh}\n      - PORT=3000\n    volumes:\n      - storage_data:/app/storage\n      - db_data:/app/db\n\nvolumes:\n  storage_data:\n  db_data:\n```\n\n### Using Docker CLI\n\nShell / macOS / Linux:\n\n```bash\ndocker pull ghcr.io/renzynx/buh1:latest\ndocker run -d \\\n \t-p 3000:3000 \\\n \t-v \"$(pwd)/storage:/app/storage\" \\\n \t-v \"$(pwd)/db:/app/db\" \\\n \t-e DATABASE_URL=/app/db/sqlite.db \\\n \t-e AUTH_SECRET=your_generated_secret \\\n \t-e AUTH_BASE_URL=https://your-domain.com \\\n \tghcr.io/renzynx/buh1:latest\n```\n\nPowerShell (Windows):\n\n```powershell\ndocker pull ghcr.io/renzynx/buh1:latest\ndocker run -d `\n \t-p 3000:3000 `\n \t-v \"${PWD}\\storage:/app/storage\" `\n \t-v \"${PWD}\\db:/app/db\" `\n \t-e DATABASE_URL=/app/db/sqlite.db `\n \t-e AUTH_SECRET=your_generated_secret `\n \t-e AUTH_BASE_URL=https://your-domain.com `\n \tghcr.io/renzynx/buh1:latest\n```\n\n**Important notes:**\n\n- `DATABASE_URL` must be set to `/app/db/sqlite.db` (inside the container)\n- Mount both `./storage` and `./db` directories to persist data\n- The database file will be created automatically on first run\n\n## Updating ⚙️\n\nKeep a current backup of your database and storage before updating. The steps below show typical update flows for a source/manual (self-hosted) install and for Docker deployments.\n\n### Manual / Source install\n\n1. Stop the running service or server (systemd, pm2, or however you run the app).\n2. Backup your database and storage directories (example paths in repo root):\n\n- PowerShell:\n\n  ```powershell\n  Stop-Process -Name node -ErrorAction SilentlyContinue\n  Copy-Item -Path .\\db\\sqlite.db -Destination .\\db\\sqlite.db.bak -Force\n  Copy-Item -Path .\\storage -Destination .\\storage.bak -Recurse -Force\n  ```\n\n- Bash / sh:\n\n  ```bash\n  # stop your process (systemd, pm2, etc.) before copying\n  cp db/sqlite.db db/sqlite.db.bak\n  cp -a storage storage.bak\n  ```\n\n3. Pull the latest code and install dependencies:\n\n```bash\ngit pull origin master\npnpm install\n```\n\n4. Apply any database migrations (same command used for initial setup):\n\n```bash\npnpm run drizzle:push\n```\n\n5. Build and restart the app:\n\n```bash\npnpm run build\n# restart your process manager, or run:\npnpm run start\n```\n\n6. Verify the app and check logs for errors.\n\n### Docker (docker compose)\n\n1. Backup your `db` and `storage` directories on the host (stop compose first):\n\n```bash\ndocker compose down\ncp db/sqlite.db db/sqlite.db.bak\ncp -a storage storage.bak\n```\n\n2. Pull the new image and restart the service (recommended):\n\n```bash\ndocker compose pull\ndocker compose up -d --force-recreate --remove-orphans\n```\n\n3. Migrations: New migrations are applied automatically when the container starts. Because the production container doesn't install development dependencies, do not attempt to run `pnpm run drizzle:push` inside the running container. To apply migrations, recreate the container so the startup process can perform them against the mounted database.\n\n4. Confirm the service is running and review logs:\n\n```bash\ndocker compose ps\ndocker compose logs -f\n```\n\n### Docker CLI (single container)\n\n1. Stop and remove the existing container, pull the new image, then recreate the container. PowerShell example:\n\n```powershell\ndocker pull ghcr.io/renzynx/buh1:latest\ndocker stop buh; docker rm buh\ndocker run -d \\\n  -p 3000:3000 \\\n  -v \"${PWD}\\storage:/app/storage\" \\\n  -v \"${PWD}\\db:/app/db\" \\\n  -e DATABASE_URL=/app/db/sqlite.db \\\n  -e AUTH_SECRET=your_generated_secret \\\n  -e AUTH_BASE_URL=https://your-domain.com \\\n  --name buh \\\n  ghcr.io/renzynx/buh1:latest\n```\n\n2. Verify logs and that the app responds on your configured URL/port.\n\n### Notes \u0026 recommendations\n\n- Always backup your `db` file and `storage` directory before updating.\n- Test upgrades in a staging environment when possible.\n- If you use a process manager (systemd, pm2), use its standard commands to restart and check status.\n\n## Environment variables ⚙️\n\n| Variable        |                                    Description | Required / Default      |\n| --------------- | ---------------------------------------------: | ----------------------- |\n| `DATABASE_URL`  | Database connection string (SQLite file path). | Required                |\n| `AUTH_SECRET`   |         Session encryption key (min 32 chars). | Required                |\n| `AUTH_BASE_URL` |                                Public app URL. | `http://localhost:3000` |\n| `APP_NAME`      |                              App display name. | `Buh`                   |\n| `PORT`          |                         Server listening port. | `3000`                  |\n\n## License 📄\n\nOpen-source under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenzynx%2Fbuh1","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenzynx%2Fbuh1","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenzynx%2Fbuh1/lists"}