Self-Hosted Google Drive CMS, Explorer & Streaming Platform
Transform your Google Drive into a professional portfolio website, media gallery, or file repository.
Features Shared Drive management, Instant Navigation, and High-Performance Streaming.
Zee-Index transforms your Google Drive into a powerful, self-hosted file system and media server.
| Feature | Description |
|---|---|
| Virtualized Rendering | Built with @tanstack/react-virtual for smooth scrolling through folders with 10,000+ files without lag |
| Instant Visual Feedback | Immediate click response with loading spinners on all interactive elements |
| Global Progress Bar | Visual top-loading bar for premium app-like navigation experience |
| Smart Prefetching | Intelligently preloads folder contents on hover for instant navigation |
| Turbopack Bundler | Uses Next.js 16's Turbopack for blazing-fast development builds |
| Redis Caching | Multi-layer caching with Redis for optimized API responses |
| Feature | Description |
|---|---|
| Direct Stream | Optimized headers (Cache-Control: no-transform) ensure video streams without re-encoding |
| Universal Audio Dock | Persistent audio player that continues playing while navigating |
| Adaptive Video Player | Integrated with VidStack for professional video playback experience |
| Auto-Subtitle Detection | Automatic detection of .srt and .vtt subtitle files |
| Modern Gallery | High-performance lightboxes for images using yet-another-react-lightbox |
| PDF Viewer | Built-in PDF viewer with react-pdf integration |
| Archive Preview | Preview contents of ZIP archives without downloading |
| Feature | Description |
|---|---|
| Recursive Folder Protection | Parent folder locks automatically protect all nested content |
| Two-Factor Authentication | Optional 2FA with TOTP using otplib |
| Role-Based Access Control | Configurable Guest, User, and Admin roles |
| Rate Limiting | Built-in API protection with configurable rate limits |
| Share Link Protection | JWT-signed share links with optional authentication requirement |
| Security Headers | Comprehensive security headers (X-Frame-Options, CSP, etc.) |
| Feature | Description |
|---|---|
| Unified Sidebar | Consolidate multiple Personal, Shared, and Team Drives |
| Folder Aliases | Rename folders in UI without changing Google Drive names |
| Private Folders | Configure specific folders to be hidden from non-admins |
| Manual Drive Addition | Add additional drives via configuration |
| Favorites & Pinned Items | Quick access to frequently used files and folders |
| Feature | Description |
|---|---|
| Code Editor | Syntax highlighting for 20+ programming languages |
| Data Usage Monitor | Real-time storage usage calculation with progress tracking |
| File Request | Create secure public upload links |
| Bulk Download | Download multiple files as ZIP archive |
| Trash Management | View and restore deleted files |
| Search | Full-text search across all accessible files |
| Tags | Organize files with custom tags |
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16.1.x | React framework with App Router |
| React | 19.x | UI library |
| TypeScript | 5.x | Type safety |
| Technology | Purpose |
|---|---|
| Tailwind CSS | Utility-first CSS |
| Framer Motion | Animations |
| Radix UI | Accessible components |
| Lucide React | Icons |
| Technology | Purpose |
|---|---|
| Zustand | Global state |
| TanStack Query | Server state & caching |
| SWR | Data fetching |
| Technology | Purpose |
|---|---|
| NextAuth.js | Authentication |
| Redis | Caching layer |
| Google Drive API v3 | File storage |
| Technology | Purpose |
|---|---|
| Vitest | Unit testing |
| Playwright | E2E testing |
| ESLint | Linting |
| Prettier | Code formatting |
| Husky | Git hooks |
zee-index/
βββ π app/ # Next.js App Router
β βββ π [locale]/ # Internationalized routes
β β βββ π (main)/ # Main layout group
β β βββ π admin/ # Admin dashboard pages
β β βββ π folder/ # Folder view pages
β β βββ π share/ # Share link pages
β β βββ π ... # Other pages
β βββ π api/ # API Routes
β β βββ π admin/ # Admin-only APIs
β β βββ π auth/ # NextAuth handlers
β β βββ π files/ # File operations
β β βββ π share/ # Share link APIs
β β βββ π cron/ # Scheduled tasks
β β βββ π ... # Other API routes
β βββ π providers.tsx # Global providers
β βββ π global-error.tsx # Error boundary
β βββ π manifest.ts # PWA manifest
β
βββ π components/ # React Components
β βββ π admin/ # Admin dashboard components
β βββ π charts/ # Data visualization
β βββ π common/ # Shared components
β βββ π features/ # Feature-specific components
β βββ π file-browser/ # File listing & navigation
β βββ π file-details/ # File preview & info
β βββ π layout/ # Layout components
β βββ π modals/ # Modal dialogs
β βββ π providers/ # Context providers
β βββ π ui/ # Base UI components
β
βββ π lib/ # Utility Functions
β βββ π drive/ # Google Drive API helpers
β βββ π auth.ts # Auth utilities
β βββ π authOptions.ts # NextAuth configuration
β βββ π kv.ts # Redis/KV client
β βββ π store.ts # Zustand stores
β βββ π ratelimit.ts # Rate limiting utilities
β βββ π env.ts # Environment validation
β βββ π utils.ts # General utilities
β
βββ π hooks/ # Custom React Hooks
βββ π types/ # TypeScript Definitions
βββ π messages/ # i18n Translation Files
β βββ π en.json # English
β βββ π id.json # Indonesian
β
βββ π __tests__/ # Unit Tests
βββ π e2e/ # End-to-End Tests
βββ π public/ # Static Assets
βββ π .github/ # GitHub Configuration
β βββ π workflows/ # CI/CD Pipelines
β
βββ π .env.example # Environment Template
βββ π docker-compose.yml # Production Docker
βββ π docker-compose.redis.yml # Dev Redis Container
βββ π Dockerfile # Multi-stage Build
βββ π middleware.ts # Next.js Middleware
βββ π next.config.mjs # Next.js Configuration
βββ π tailwind.config.ts # Tailwind Configuration
βββ π package.json # Dependencies
Before you begin, ensure you have the following installed:
| Requirement | Version | Download |
|---|---|---|
| Node.js | 20.x or higher | nodejs.org |
| pnpm | 9.x or higher | pnpm.io |
| Docker Desktop | Latest | docker.com |
| Git | Latest | git-scm.com |
You'll also need:
- A Google Cloud Project with Drive API enabled
- OAuth 2.0 Credentials (Client ID & Secret)
- A Google Drive folder to use as root
Choose the installation method that best fits your needs:
This mode runs Redis in a lightweight Docker container for persistent caching while using pnpm dev for hot module replacement.
# 1. Clone the repository
git clone https://github.com/ifauzeee/Zee-Index.git
cd Zee-Index
# 2. Install dependencies
pnpm install
# 3. Configure environment
cp .env.example .env
# Edit .env with your credentials (see Configuration section)
# 4. Start Redis container
pnpm redis:up
# 5. Start development server (in a new terminal)
pnpm dev
# 6. Open http://localhost:3000 in your browserAdditional Commands:
# Stop Redis when done
pnpm redis:down
# Run without Turbopack (if issues arise)
pnpm dev:webpack
# Type checking
pnpm typecheck
# Linting
pnpm lint
# Run all checks
pnpm check:allBuild and run the entire application in Docker for a production-like environment.
# 1. Clone and configure
git clone https://github.com/ifauzeee/Zee-Index.git
cd Zee-Index
cp .env.example .env
# Edit .env with your credentials
# 2. Build and start
docker compose up --build
# 3. Access at http://localhost:3000Deploy with optimized production settings.
# Build optimized production image
docker compose build
# Run in detached mode
docker compose up -d
# View logs
docker compose logs -f zee-index
# Stop the container
docker compose downThese variables must be set for the application to function:
| Variable | Description | Example |
|---|---|---|
NEXTAUTH_URL |
Your application URL | http://localhost:3000 or https://yourdomain.com |
NEXTAUTH_SECRET |
Random encryption key (min 32 chars) | Generate with openssl rand -base64 32 |
GOOGLE_CLIENT_ID |
OAuth Client ID from Google Cloud | xxx.apps.googleusercontent.com |
GOOGLE_CLIENT_SECRET |
OAuth Client Secret | GOCSPX-xxx |
GOOGLE_REFRESH_TOKEN |
OAuth Refresh Token | Obtained via /setup flow |
NEXT_PUBLIC_ROOT_FOLDER_ID |
Google Drive folder ID to use as root | 1abc...xyz |
ADMIN_EMAILS |
Comma-separated admin emails | admin@example.com,owner@example.com |
ADMIN_PASSWORD |
Password for admin fallback login | Strong password |
SHARE_SECRET_KEY |
Random key for signing share URLs (min 32 chars) | Generate with openssl rand -base64 32 |
| Variable | Description | Default |
|---|---|---|
REDIS_URL |
Alternative Redis connection string | redis://localhost:6379 |
STORAGE_PROVIDER |
Storage backend | google-drive |
NEXT_PUBLIC_ROOT_FOLDER_NAME |
Display name for root folder | Home |
NEXT_PUBLIC_MANUAL_DRIVES |
JSON array of additional drives | [] |
PRIVATE_FOLDER_IDS |
JSON array of private folder IDs | [] |
STORAGE_LIMIT_GB |
Storage warning limit in GB | 15 |
STORAGE_WARNING_THRESHOLD |
Warning threshold (0-1) | 0.90 |
NEXT_PUBLIC_SENTRY_DSN |
Sentry error tracking DSN | Empty |
CRON_SECRET |
Secret for cron job authentication | Random string |
SKIP_ENV_VALIDATION |
Skip env validation during build | false |
| Variable | Description | Default |
|---|---|---|
SMTP_HOST |
SMTP server hostname | smtp.gmail.com |
SMTP_PORT |
SMTP server port | 465 |
SMTP_USER |
SMTP username/email | - |
SMTP_PASS |
SMTP password or app password | - |
EMAIL_FROM |
Sender email address | Zee Index <no-reply@example.com> |
# ==============================================================================
# ZEE-INDEX CONFIGURATION
# ==============================================================================
# ------------------------------------------------------------------------------
# 1. CORE APPLICATION SETTINGS
# ------------------------------------------------------------------------------
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-super-secret-key-minimum-32-characters-long"
SHARE_SECRET_KEY="another-secret-key-minimum-32-characters-long"
ADMIN_EMAILS="admin@example.com"
ADMIN_PASSWORD="your-secure-admin-password"
# ------------------------------------------------------------------------------
# 2. STORAGE CONFIGURATION
# ------------------------------------------------------------------------------
STORAGE_PROVIDER="google-drive"
NEXT_PUBLIC_ROOT_FOLDER_ID="your-google-drive-folder-id"
NEXT_PUBLIC_ROOT_FOLDER_NAME="Home"
# Optional: Add multiple drives (JSON array)
# NEXT_PUBLIC_MANUAL_DRIVES='[{"id":"drive_id","name":"Drive Name"}]'
# Optional: Private folder IDs (JSON array)
# PRIVATE_FOLDER_IDS='["folder_id_1","folder_id_2"]'
# ------------------------------------------------------------------------------
# 3. GOOGLE DRIVE PROVIDER
# ------------------------------------------------------------------------------
GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-client-secret"
GOOGLE_REFRESH_TOKEN="your-refresh-token"
# ------------------------------------------------------------------------------
# 4. REDIS/CACHE CONFIGURATION
# ------------------------------------------------------------------------------
# For Local Docker Redis:
# KV_REST_API_URL="redis://localhost:6379"
# KV_REST_API_TOKEN=""
# ------------------------------------------------------------------------------
# 5. LIMITS & MONITORING
# ------------------------------------------------------------------------------
STORAGE_LIMIT_GB=15
STORAGE_WARNING_THRESHOLD=0.90
NEXT_PUBLIC_SENTRY_DSN=""
# ------------------------------------------------------------------------------
# 6. EMAIL CONFIGURATION (Optional)
# ------------------------------------------------------------------------------
# SMTP_HOST="smtp.gmail.com"
# SMTP_PORT="465"
# SMTP_USER="your-email@gmail.com"
# SMTP_PASS="your-app-password"
# EMAIL_FROM="Zee Index <no-reply@example.com>"
# ------------------------------------------------------------------------------
# 7. CRON & WEBHOOKS
# ------------------------------------------------------------------------------
CRON_SECRET="random-string-for-cron-protection"
# WEBHOOK_URL=""
# ------------------------------------------------------------------------------
# 8. BUILD SETTINGS
# ------------------------------------------------------------------------------
SKIP_ENV_VALIDATION=false-
Create a Google Cloud Project
- Go to Google Cloud Console
- Create a new project or select an existing one
-
Enable Google Drive API
- Navigate to APIs & Services β Library
- Search for "Google Drive API"
- Click Enable
-
Create OAuth 2.0 Credentials
- Go to APIs & Services β Credentials
- Click Create Credentials β OAuth client ID
- Select Web application
- Add Authorized redirect URIs:
- For development:
http://localhost:3000/setup - For production:
https://yourdomain.com/setup
- For development:
- Save your Client ID and Client Secret
-
Configure OAuth Consent Screen
- Go to APIs & Services β OAuth consent screen
- Fill in required fields (App name, support email, etc.)
- Add scopes:
https://www.googleapis.com/auth/drivehttps://www.googleapis.com/auth/drive.filehttps://www.googleapis.com/auth/userinfo.emailhttps://www.googleapis.com/auth/userinfo.profile
-
Start the application with your Google credentials in
.env:GOOGLE_CLIENT_ID="your-client-id" GOOGLE_CLIENT_SECRET="your-client-secret" GOOGLE_REFRESH_TOKEN="" # Leave empty initially
-
Navigate to
/setupin your browser -
Complete the OAuth flow by signing in with your Google account
-
Copy the Refresh Token displayed and add it to your
.env: -
Start the application with your Google credentials in
.env:GOOGLE_CLIENT_ID="your-client-id" GOOGLE_CLIENT_SECRET="your-client-secret" GOOGLE_REFRESH_TOKEN="" # Leave empty initially
-
Navigate to
/setupin your browser -
Complete the OAuth flow by signing in with your Google account
-
Copy the Refresh Token displayed and add it to your
.env:GOOGLE_REFRESH_TOKEN="your-newly-obtained-refresh-token" -
Restart the application to apply changes
- Create a new project on Railway
- Connect your GitHub repository
- Add environment variables
- Deploy
- Create a new Web Service on Render
- Connect your repository
- Set build command:
pnpm install && pnpm build - Set start command:
pnpm start - Add environment variables
- Create a new App on DigitalOcean
- Connect your repository
- Configure as Node.js app
- Add environment variables
- Deploy
The project includes an optimized multi-stage Dockerfile with the following features:
- Alpine-based images for minimal size (~150MB)
- pnpm for efficient caching
- Non-root user for security
- Health checks for reliability
- dumb-init for proper signal handling
Production Deployment:
# Build and run
docker compose up --build -d
# View logs
docker compose logs -f
# Stop
docker compose downDocker Compose Configuration:
services:
zee-index:
container_name: zee-index
build:
context: .
dockerfile: Dockerfile
args:
NEXT_PUBLIC_ROOT_FOLDER_ID: ${NEXT_PUBLIC_ROOT_FOLDER_ID}
NEXT_PUBLIC_ROOT_FOLDER_NAME: ${NEXT_PUBLIC_ROOT_FOLDER_NAME}
BUILDKIT_INLINE_CACHE: 1
restart: always
ports:
- "3000:3000"
env_file:
- .env
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sThe Dockerfile accepts these build arguments for environment variables needed at build time:
| Argument | Description |
|---|---|
NEXT_PUBLIC_ROOT_FOLDER_ID |
Root folder ID (required at build) |
NEXT_PUBLIC_ROOT_FOLDER_NAME |
Root folder display name |
NEXT_PUBLIC_SENTRY_DSN |
Sentry DSN for error tracking |
The container includes health checks that monitor the /api/health endpoint:
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1The attached docker-compose.yml includes built-in support for DuckDNS (Dynamic DNS) and Caddy (Reverse Proxy & Auto SSL).
-
Obtain DuckDNS Token
- Go to DuckDNS
- Create a domain (e.g.,
my-drive.duckdns.org) - Copy your Token
-
Configure Environment
- Add these lines to your
.envfile:DUCKDNS_DOMAIN="my-drive" DUCKDNS_TOKEN="your-duckdns-token"
- Change
NEXTAUTH_URLin.envto your new HTTPS URL:NEXTAUTH_URL="https://my-drive.duckdns.org"
- Add these lines to your
-
Deploy
- Caddy will automatically provision an SSL certificate from Let's Encrypt.
- DuckDNS container will keep your home IP address updated.
Zee-Index supports multiple authentication methods:
| Method | Description | Configuration |
|---|---|---|
| Google OAuth | Sign in with Google account | Configure OAuth credentials |
| Admin Password | Fallback admin login | Set ADMIN_PASSWORD |
| Guest Access | Limited read-only access | Enabled by default |
| 2FA (TOTP) | Optional two-factor auth | Admin configuration |
| Role | Permissions |
|---|---|
| ADMIN | Full access to all features, settings, and configuration |
| USER | Standard access to files in permitted folders |
| GUEST | Read-only access to public folders |
| Route | Required Role | Description |
|---|---|---|
/admin/* |
ADMIN | Admin dashboard and settings |
/folder/* |
USER+ | File browsing |
/share/* |
PUBLIC | Shared links (with token) |
/setup |
PUBLIC | Initial setup (only when unconfigured) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/health |
Health check endpoint |
GET |
/api/config/public |
Public configuration |
GET |
/api/files |
List files with optional token |
GET |
/api/download/[id] |
Download file (with token) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/folder/[id] |
Get folder contents |
GET |
/api/filedetails/[id] |
Get file details |
GET |
/api/search |
Search files |
GET |
/api/datausage |
Get storage usage |
POST |
/api/favorites |
Manage favorites |
POST |
/api/share/create |
Create share link |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/admin/stats |
Dashboard statistics |
GET |
/api/admin/activity |
Activity logs |
POST |
/api/admin/config |
Update configuration |
POST |
/api/admin/2fa/setup |
Configure 2FA |
DELETE |
/api/admin/clearcache |
Clear cache |
| Method | Endpoint | Description | Schedule |
|---|---|---|---|
GET |
/api/cron/storage-check |
Check storage usage | Daily at 5 AM |
GET |
/api/cron/weekly-report |
Generate weekly report | Sundays at 6 AM |
| Key | Function |
|---|---|
Cmd/Ctrl + K |
Open Command Palette |
/ |
Focus Search |
Space |
Quick Preview |
Delete |
Delete Selected File |
Ctrl + A |
Select All Files |
F2 |
Rename Selected File |
Escape |
Close Modal / Clear Selection |
Enter |
Open Selected Item |
G then H |
Go to Home |
Zee-Index supports multiple languages using next-intl:
| Language | Code | File |
|---|---|---|
| English | en |
messages/en.json |
| Indonesian | id |
messages/id.json |
-
Create a new JSON file in
messages/:cp messages/en.json messages/fr.json
-
Translate all strings in the new file
-
Add the locale to
middleware.ts:const intlMiddleware = createMiddleware({ locales: ["en", "id", "fr"], defaultLocale: "en", localePrefix: "always", });
-
Update
i18n.tsif needed
# Run tests
pnpm test
# Run in watch mode
pnpm test -- --watch
# Generate coverage report
pnpm test -- --coverage# Install browsers (first time)
npx playwright install
# Run E2E tests
pnpm test:e2e
# Run with UI
npx playwright test --ui
# Generate HTML report
npx playwright show-report__tests__/ # Unit tests
βββ components/ # Component tests
βββ lib/ # Utility tests
βββ api/ # API route tests
e2e/ # End-to-end tests
βββ *.spec.ts # Playwright specs
| Workflow | Trigger | Description |
|---|---|---|
ci.yml |
Push/PR to main | Lint, typecheck, test, build |
test.yml |
Push/PR | Run unit tests |
playwright.yml |
Push/PR | Run E2E tests |
docker-publish.yml |
Release | Build and push Docker image |
graph LR
A[Push/PR] --> B[Install]
B --> C[Lint]
C --> D[Typecheck]
D --> E[Test]
E --> F[Build]
F --> G[Deploy]
| Secret | Description |
|---|---|
DOCKER_USERNAME |
Docker Hub username |
DOCKER_PASSWORD |
Docker Hub password |
- Request logging with path and duration
- Error logging with stack traces
- Activity logging for admin actions
-
Add your Sentry DSN:
NEXT_PUBLIC_SENTRY_DSN="https://xxxxx@sentry.io/xxxxx" -
Errors will be automatically reported to Sentry
curl http://localhost:3000/api/healthResponse:
{
"status": "healthy",
"timestamp": "2025-01-01T00:00:00Z"
}Login Failed
Symptoms: Unable to login, credentials rejected
Solutions:
- Check
ADMIN_EMAILSin.envmatches your email exactly - Ensure
ADMIN_PASSWORDis set correctly (no quotes around value) - Clear browser cookies and try again
- Check server logs for specific error messages
Redis Connection Error
Symptoms: Cache errors, slow performance
Solutions:
- For local development, ensure Redis container is running:
pnpm redis:up docker ps # Verify container is running - Check
KV_REST_API_URLmatches your Redis setup:- Local Docker:
redis://localhost:6379
- Local Docker:
Google Drive API Errors
Symptoms: Files not loading, 401/403 errors
Solutions:
- Verify
GOOGLE_REFRESH_TOKENis valid - Re-run the
/setupflow to get a new token - Check API quotas in Google Cloud Console
- Ensure the service account has access to the folders
Build Failures
Symptoms: Build fails with environment variable errors
Solutions:
- Check all required env variables are set
- For CI/CD, add mock values for build:
SKIP_ENV_VALIDATION=true pnpm build
- Verify
next.config.mjshas no syntax errors
Docker Build Issues
Symptoms: Docker build fails or container crashes
Solutions:
- Ensure Docker BuildKit is enabled:
export DOCKER_BUILDKIT=1 - Check memory allocation for Docker
- Verify
.dockerignoreexcludesnode_modules - Try building without cache:
docker compose build --no-cache
Performance Issues
Symptoms: Slow page loads, timeouts
Solutions:
- Enable Redis caching (don't rely on in-memory cache)
- Check Google Drive API quotas
- Reduce folder sizes (virtualization helps but has limits)
- Enable PWA caching
We welcome contributions from the community! Please read our Contributing Guide before submitting a Pull Request.
# 1. Fork the repository
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/Zee-Index.git
# 3. Create a feature branch
git checkout -b feature/amazing-feature
# 4. Make your changes
pnpm install
pnpm dev
# 5. Run all checks
pnpm check:all
# 6. Commit your changes
git commit -m "feat: add amazing feature"
# 7. Push and create a Pull Request
git push origin feature/amazing-featureWe follow Conventional Commits:
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
style |
Code style (formatting, etc.) |
refactor |
Code refactoring |
test |
Adding tests |
chore |
Maintenance |
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) with an additional attribution requirement.
- β Free to use, modify, and distribute
- β Commercial use allowed
β οΈ Attribution Required: You must display the following notice:Β© 2025 All rights reserved - Muhammad Ibnu Fauzi
β οΈ If you host a modified version, you must share the source codeβ οΈ Changes must be documented
See the LICENSE file for full details.
- Next.js Team - For the amazing framework
- Radix UI - For accessible components
- TanStack - For React Query and Virtual
- VidStack - For the video player
This project is built with many amazing open source libraries. See package.json for the full list.
β If you find this project useful, please give it a star!
Crafted with β€οΈ by Muhammad Ibnu Fauzi