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.
curl -fsSL https://yourdrive.app/install.sh | sudo bashThe 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
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
MinIO (local Docker)
Click "Quick fill: Docker Dev (MinIO defaults)" in the setup wizard to auto-populate:
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
https://<account-id>.r2.cloudflarestorage.comEnvironment Variables
The install script generates and sets these for you. Listed here for reference, or if you're customising a manual deploy.
| Variable | Required | Description |
|---|---|---|
| DATABASE_URL | Yes | PostgreSQL connection string |
| JWT_SECRET | Yes | Min 32 chars. Signs all JWT auth tokens. |
| ENCRYPTION_KEY | Yes | Min 32 chars. AES-256 key for storage credentials. |
| PORT | No | Backend port (default: 3001) |
| CORS_ORIGIN | No | Allowed frontend origin (default: localhost:5173) |
| SIGNED_URL_EXPIRES | No | Signed URL TTL in seconds (default: 3600) |
| MAX_FILE_SIZE | No | Max upload size in bytes (default: 500 MB) |
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:
YOURDRIVE_DIR=/opt/yourdrive # install directory
YOURDRIVE_DOMAIN=drive.example.com # skip the prompt
YOURDRIVE_TAG=latest # image version to deployThis 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/register | Register a new user. First user becomes admin. |
| POST | /auth/login | Returns { token, user } on success. |
| GET | /auth/me | Returns 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/stats | Library stats: counts by type + total bytes. |
| GET | /files/trash | List soft-deleted files. |
| POST | /files/bulk | Bulk operation: { action, fileIds, folderId? }. action includes move. |
| GET | /files/:id/content | Stream file content through backend. |
| GET | /files/:id/thumbnail | Stream a video's poster frame (JPEG); 404 if none exists. |
| GET | /files/:id/url | Get signed URL for direct download. |
| PATCH | /files/:id/favorite | Toggle favourite status. |
| POST | /files/:id/restore | Restore file from trash. |
| DELETE | /files/:id | Soft delete (moves to trash). |
| DELETE | /files/:id/permanent | Permanently delete from storage + DB. |
Folders
| GET | /folders/browse?folderId= | Returns { breadcrumb, folders, files } for a folder (root if omitted). |
| GET | /folders | Flat list of all folders, used by the move picker. |
| POST | /folders | Create a folder: { name, parentId? }. |
| PATCH | /folders/:id | Rename or move a folder: { name?, parentId? }. |
| DELETE | /folders/:id | Delete a folder. Its files move to Trash; child folders cascade. |
Admin (admin role required)
| GET | /admin/storage/status | Returns { configured, provider, providerLabel } — providerLabel is auto-detected (e.g. "Cloudflare R2"). |
| GET | /admin/storage | Returns current config (credentials masked). |
| POST | /admin/storage | Save storage configuration. |
| POST | /admin/storage/test | Test connection without saving. |
| DELETE | /admin/storage | Remove storage configuration. |
| GET | /users | List all user accounts with file counts. |
| POST | /users | Create a new user account. |
| PATCH | /users/:id | Change a user's role (USER or ADMIN). |
| DELETE | /users/:id | Delete a user and their files/folders. |