Documentation

Getting Started

One command, and YourDrive is running on your server.

Quick Start

SSH into your server and run one command. It installs Docker if needed, generates secrets, and starts YourDrive — nothing to clone or configure by hand.

bash
curl -fsSL https://yourdrive.app/install.sh | sudo bash

The script asks for the domain or IP the server is reachable at (or auto-detects one — just hit enter). When it finishes, open the printed URL and register your account. The first registered user automatically becomes admin and is guided to the Storage Setup Wizard to connect a storage backend.

Requirements

ServerLinux, root/sudo access
DockerInstalled automatically if missing
Object storageS3, Azure, MinIO, R2, or Wasabi bucket
Disk space~500 MB for images

You don't need Node.js, npm, or Docker pre-installed — the install script handles all of it.

Storage Configuration

Storage credentials are configured through the admin UI — no environment variable editing required. After registering as admin, navigate to Storage Settings in the sidebar.

AWS S3

ProviderS3
Regione.g. us-east-1
BucketYour S3 bucket name
Access Key IDIAM access key (needs S3 read/write on the bucket)
EndpointLeave blank for standard AWS S3

MinIO (local Docker)

Click "Quick fill: Docker Dev (MinIO defaults)" in the setup wizard to auto-populate:

env
Endpoint:        http://minio:9000
Public URL:      http://localhost:9000
Bucket:          yourdrive-dev
Access Key ID:   minioadmin
Secret Key:      minioadmin123
Path-style URLs: ✓ (checked)

Cloudflare R2

Endpointhttps://<account-id>.r2.cloudflarestorage.com
Regionauto
Path-styleLeave unchecked

Environment Variables

The install script generates and sets these for you. Listed here for reference, or if you're customising a manual deploy.

VariableRequiredDescription
DATABASE_URLYesPostgreSQL connection string
JWT_SECRETYesMin 32 chars. Signs all JWT auth tokens.
ENCRYPTION_KEYYesMin 32 chars. AES-256 key for storage credentials.
PORTNoBackend port (default: 3001)
CORS_ORIGINNoAllowed frontend origin (default: localhost:5173)
SIGNED_URL_EXPIRESNoSigned URL TTL in seconds (default: 3600)
MAX_FILE_SIZENoMax upload size in bytes (default: 500 MB)
Important: The ENCRYPTION_KEY must remain stable. Changing it will make existing storage configurations in the database unreadable.

Server Install Reference

Covered in Quick Start above — this section covers what the install script does under the hood, and how to customise it.

Under /opt/yourdrive (or wherever YOURDRIVE_DIR points), the script generates strong secrets, writes a production docker-compose.yml that pulls the published images, and starts the stack — no source checkout, no manual .env editing.

It's safe to re-run — it reuses the existing install and just pulls the latest images. Useful overrides, set as env vars before the pipe:

env
YOURDRIVE_DIR=/opt/yourdrive       # install directory
YOURDRIVE_DOMAIN=drive.example.com # skip the prompt
YOURDRIVE_TAG=latest               # image version to deploy

This does not set up HTTPS. Put a reverse proxy (Caddy, nginx, Cloudflare Tunnel) in front of port 80 to terminate TLS before handling real user data.

API Reference

All API routes are prefixed with /api/v1 and require a Authorization: Bearer <token> header unless noted.

Authentication

POST/auth/registerRegister a new user. First user becomes admin.
POST/auth/loginReturns { token, user } on success.
GET/auth/meReturns the currently authenticated user.

Files

POST/files/upload?folderId=Multipart file upload. Streams directly to storage; optional destination folder.
GET/files?q=&type=&favorite=&page=&limit=List/search files. type accepts all, media, image, or video.
GET/files/statsLibrary stats: counts by type + total bytes.
GET/files/trashList soft-deleted files.
POST/files/bulkBulk operation: { action, fileIds, folderId? }. action includes move.
GET/files/:id/contentStream file content through backend.
GET/files/:id/thumbnailStream a video's poster frame (JPEG); 404 if none exists.
GET/files/:id/urlGet signed URL for direct download.
PATCH/files/:id/favoriteToggle favourite status.
POST/files/:id/restoreRestore file from trash.
DELETE/files/:idSoft delete (moves to trash).
DELETE/files/:id/permanentPermanently delete from storage + DB.

Folders

GET/folders/browse?folderId=Returns { breadcrumb, folders, files } for a folder (root if omitted).
GET/foldersFlat list of all folders, used by the move picker.
POST/foldersCreate a folder: { name, parentId? }.
PATCH/folders/:idRename or move a folder: { name?, parentId? }.
DELETE/folders/:idDelete a folder. Its files move to Trash; child folders cascade.

Admin (admin role required)

GET/admin/storage/statusReturns { configured, provider, providerLabel } — providerLabel is auto-detected (e.g. "Cloudflare R2").
GET/admin/storageReturns current config (credentials masked).
POST/admin/storageSave storage configuration.
POST/admin/storage/testTest connection without saving.
DELETE/admin/storageRemove storage configuration.
GET/usersList all user accounts with file counts.
POST/usersCreate a new user account.
PATCH/users/:idChange a user's role (USER or ADMIN).
DELETE/users/:idDelete a user and their files/folders.