Locker Open-source file storage and knowledge platform. A self-hostable alternative to Dropbox and Google Drive — with built-in search, doc…
Locker Open-source file storage and knowledge platform. A self-hostable alternative to Dropbox and Google Drive — with built-in search, doc…
Open-source file storage and knowledge platform. A self-hostable alternative to Dropbox and Google Drive — with built-in search, document transcription, and an AI-powered knowledge base.
ls, cd, find, cat, grep, etc. via just-bash…pnpm installdocker compose up -dcp .env.example .envThe defaults work out of the box for local development. Edit .env to change the storage provider or add OAuth credentials.
pnpm db:generate
pnpm db:migratepnpm devOpen http://localhost:3000, create an account, and start uploading files.
Locker auto-detects which platform it's running on and adjusts its capabilities accordingly. Persistent runtimes (Docker, Fly.io, Railway) support all features. Serverless runtimes (Vercel) disable long-running operations like store sync and bulk KB ingestion.
Every deployment needs:
BETTER_AUTH_SECRET — generate with openssl rand -base64 32NEXT_PUBLIC_APP_URL — the public URL of your deploymentThe included docker-compose.yml bundles PostgreSQL, migrations, and the web app. This is the fastest way to self-host.
# 1. Clone and configure
git clone https://github.com/zmeyer44/Locker.git && cd Locker
cp .env.example .env
# 2. Set the required secret
# Replace the placeholder in .env or export it:
export BETTER_AUTH_SECRET=$(openssl rand -base64 32)
# 3. Start everything
docker compose up -dOpen http://localhost:3000. Files are stored on a Docker volume (blob_data) by default.
To use S3 or R2 instead of local storage, set BLOB_STORAGE_PROVIDER and the matching credentials in your .env before starting.
To enable optional search services:
docker compose --profile search up -dRailway provides managed PostgreSQL and persistent disk, so all features work out of the box.
Create a new project and add a PostgreSQL service. Copy the DATABASE_URL.
Add a new service from the Locker repo. Railway will detect the Dockerfile automatically.
Set these environment variables on the web service:
| Variable | Value |
|---|---|
DATABASE_URL |
The PostgreSQL connection string from step 1 |
BETTER_AUTH_SECRET |
openssl rand -base64 32 |
BETTER_AUTH_URL |
Your Railway public URL (e.g. https://locker-production.up.railway.app) |
NEXT_PUBLIC_APP_URL |
Same as BETTER_AUTH_URL |
BLOB_STORAGE_PROVIDER |
local (default) or s3 / r2 with matching credentials |
If using local storage, attach a volume mounted at /app/local-blobs.
Deploy. Railway runs migrations automatically via the migrate service in Docker Compose, or you can add a deploy command: pnpm db:migrate && node apps/web/server.js.
Fly provides persistent VMs with attached volumes.
Create a PostgreSQL cluster:
fly postgres create --name locker-dbLaunch the app from the repo root:
fly launch --dockerfile DockerfileAttach the database:
fly postgres attach locker-dbCreate a volume for local storage:
fly volumes create blob_data --size 10 --region your-regionAdd to fly.toml:
[mounts]
source = "blob_data"
destination = "/app/local-blobs"Set secrets:
fly secrets set \
BETTER_AUTH_SECRET=$(openssl rand -base64 32) \
BETTER_AUTH_URL=https://your-app.fly.dev \
NEXT_PUBLIC_APP_URL=https://your-app.fly.devRun migrations and deploy:
fly deploy./Dockerfile./app/local-blobs for local file storage.DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL, NEXT_PUBLIC_APP_URL.Vercel runs Next.js on serverless functions. Locker auto-detects this and disables features that require a persistent runtime:
You must use a cloud storage provider (Vercel Blob, S3, or R2).
Import the repo into Vercel.
Set the framework preset to Next.js and the root directory to apps/web.
Add a PostgreSQL database (Vercel Postgres, Neon, Supabase, etc.) and set DATABASE_URL.
Set environment variables:
| Variable | Value |
|---|---|
BETTER_AUTH_SECRET |
openssl rand -base64 32 |
BETTER_AUTH_URL |
Your Vercel deployment URL |
NEXT_PUBLIC_APP_URL |
Same as BETTER_AUTH_URL |
BLOB_STORAGE_PROVIDER |
vercel (recommended) or s3 / r2 |
BLOB_READ_WRITE_TOKEN |
From Vercel Blob (if using vercel provider) |
Deploy. Run migrations manually or via a build command: pnpm db:migrate && pnpm build.
Locker detects the hosting platform automatically from environment variables (VERCEL, FLY_REGION, RAILWAY_ENVIRONMENT, etc.). If detection is wrong or you want to test serverless behavior locally, set:
LOCKER_RUNTIME_ENV=vercel # or: docker, fly, railway, render, developmentSet BLOB_STORAGE_PROVIDER in .env to configure the default storage backend for new workspaces:
| Provider | Value | Required Env Vars |
|---|---|---|
| Local filesystem | local |
LOCAL_BLOB_DIR |
| AWS S3 | s3 |
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET |
| Cloudflare R2 | r2 |
R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET |
| Vercel Blob | vercel |
BLOB_READ_WRITE_TOKEN |
Workspace admins can attach additional stores from Settings > Stores. Each store can be configured as:
Stores use their own credentials (BYOB), so different teams can bring different backends. A primary store is designated per workspace for new uploads; replicas receive copies automatically.
Locker ships with a built-in plugin system. Plugins are installed per-workspace and can add search, transcription, file actions, and more.
| Plugin | Description |
|---|---|
| QMD Search | Semantic document search powered by QMD embeddings |
| Full-Text Search | Lightweight SQLite FTS5 search — no external service required |
| Document Transcription | AI-powered OCR for images and PDFs, making non-text files searchable |
| Google Drive Sync | Import files from and export files to Google Drive |
| Knowledge Base | Build an AI-powered wiki from tagged documents with chat and graph view |
QMD and FTS run as standalone microservices. Enable them with the search Docker Compose profile:
docker compose --profile search up -d| Command | Description |
|---|---|
pnpm dev |
Start all packages in dev mode |
pnpm build |
Production build |
pnpm typecheck |
Type-check all packages |
pnpm lint |
Lint all packages |
pnpm db:generate |
Generate a new Drizzle migration |
pnpm db:migrate |
Apply pending migrations |
pnpm db:seed |
Seed the database |
pnpm format |
Format code with Prettier |
Locker includes a read-only virtual filesystem over workspace files/folders, powered by just-bash.
The shell API is available on tRPC router vfsShell:
vfsShell.createSession({ cwd? }) → create a workspace-scoped shell sessionvfsShell.exec({ sessionId, command, timeoutMs? }) → run a bash commandvfsShell.session({ sessionId }) → get session cwd + expiryvfsShell.closeSession({ sessionId }) → close a sessionImplementation details:
folders + files and cached in memory.rm, mv, redirections, etc.) fail with EROFS (read-only filesystem).MIT
No open issues yet, or sync has not completed.