ViTransfer Documentation
Deploy, configure, and operate the self-hosted video review platform.
Documentation
Overview
ViTransfer is a self-hosted, open-source video review and approval platform designed for video professionals. It enables secure video sharing, timestamped feedback, and streamlined approval workflows without relying on third-party services.
Key Features
Video Processing
Automatic FFmpeg transcodes to 720p and 1080p with resumable uploads via the TUS protocol.
Collaboration
Timestamped comments with threaded replies that stay tied to the exact playback position.
Approval Workflow
Clients can approve on the share page; admins can approve/unapprove. Projects move between In Review and Approved; share-only projects can be created for delivery-only access.
Security
Password or email OTP for share links, optional guest mode, and bearer-token API authentication.
Customization
Project-level watermarking and company/client naming on share pages.
Analytics
Track page visits and download events to understand project activity.
System Requirements
Minimum Requirements
| Component | Requirement | Notes |
|---|---|---|
| CPU | 2 cores | 4+ cores recommended for video transcoding |
| RAM | 4GB | 8GB+ recommended for multiple concurrent uploads |
| Storage | 20GB | Varies based on video library size |
| OS | Linux, macOS, Windows | Any OS that supports Docker |
Software Dependencies
- Docker: Version 20.10 or higher
- Docker Compose: Version 2.0 or higher
- FFmpeg: Included in Docker image (no manual installation needed)
Installation
Quick Start with Docker Hub
The fastest way to get ViTransfer running is using the pre-built Docker image from Docker Hub.
Step 1: Create Project Directory
mkdir vitransfer && cd vitransferStep 2: Download Configuration Files
curl -O https://raw.githubusercontent.com/MansiVisuals/ViTransfer/main/docker-compose.ymlcurl -O https://raw.githubusercontent.com/MansiVisuals/ViTransfer/main/.env.examplecp .env.example .envStep 3: Generate Required Secrets
Use hex for database/Redis (URL-safe), base64 for encryption/JWT/share secrets.
openssl rand -hex 32
openssl rand -hex 32openssl rand -base64 32
openssl rand -base64 64
openssl rand -base64 64
openssl rand -base64 64Step 4: Configure Environment Variables
Edit the .env file and set at minimum:
APP_PORT=4321
POSTGRES_USER=vitransfer
POSTGRES_PASSWORD=REQUIRED
POSTGRES_DB=vitransfer
REDIS_PASSWORD=REQUIREDENCRYPTION_KEY=REQUIRED
JWT_SECRET=REQUIRED
JWT_REFRESH_SECRET=REQUIRED
SHARE_TOKEN_SECRET=REQUIRED[email protected]
ADMIN_PASSWORD=Admin1234NEXT_PUBLIC_APP_URL=http://localhost:4321
HTTPS_ENABLED=false # set true when running behind HTTPSStep 5: Start ViTransfer
docker-compose up -dStep 6: Access the Application
Open your browser and navigate to:
http://localhost:4321 (or your chosen APP_PORT)Building from Source
If you want to build from source instead of using the Docker Hub image:
# Clone the repository
git clone https://github.com/MansiVisuals/ViTransfer.git
cd ViTransfer
# Copy the env file and fill the required values (same as above)
cp .env.example .env
# Build and run locally
docker-compose up -d --buildConfiguration
Environment Variables
ViTransfer reads configuration from the .env file (see .env.example for defaults). Key settings:
Core Settings
| Variable | Description | Default | Required |
|---|---|---|---|
APP_PORT |
Port exposed by the app container | 4321 | No |
NEXT_PUBLIC_APP_URL |
Public URL used in links/emails | http://localhost:4321 | No |
TZ |
Timezone for scheduling and logging | UTC | No |
PUID |
Host user ID for file permissions | 1000 | No |
PGID |
Host group ID for file permissions | 1000 | No |
HTTPS_ENABLED |
Enforce HTTPS headers/HSTS (set true in production) | true | No |
Database & Redis
| Variable | Description | Default | Required |
|---|---|---|---|
POSTGRES_USER |
Database user | vitransfer | No |
POSTGRES_PASSWORD |
Database password | - | Yes |
POSTGRES_DB |
Database name | vitransfer | No |
REDIS_PASSWORD |
Redis password | - | Yes |
Security Keys
| Variable | Description | Default | Required |
|---|---|---|---|
ENCRYPTION_KEY |
Encrypts sensitive data (base64) | - | Yes |
JWT_SECRET |
Access token signing secret (base64) | - | Yes |
JWT_REFRESH_SECRET |
Refresh token signing secret (base64) | - | Yes |
SHARE_TOKEN_SECRET |
Share link token signing secret (base64) | - | Yes |
Admin Account
| Variable | Description | Default | Required |
|---|---|---|---|
ADMIN_EMAIL |
Initial admin email | [email protected] | Yes |
ADMIN_PASSWORD |
Initial admin password | - | Yes |
Optional
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_TUS_ENDPOINT |
Custom TUS upload origin (leave empty for same origin) | - |
CLOUDFLARE_TUNNEL |
Set to true when running behind a Cloudflare tunnel |
false |
.env.
Features Guide
Project Management
Creating a Project
- Log in as an admin and click "New Project" from the dashboard.
- Enter the project title, optional description, and company/client name.
- Add an optional primary recipient (name/email) for notifications.
- Select authentication mode: Password, Email OTP, Both, or None.
- Set a share password if using password-based modes (auto-generated by default).
- Toggle guest mode if you want view-only access; guests see the latest version by default.
- Create the project, then adjust watermark, download, and notification settings in Project Settings.
Watermarking
ViTransfer supports project-level watermarking to protect preview renders:
- Enable/Disable: Control watermarks globally and per project.
- Custom Text: Override the default watermark text (up to 100 characters).
Video Upload & Processing
Uploading Videos
ViTransfer uses the TUS protocol for resumable uploads and validates MP4/MOV headers before starting:
- Open the project and click "Upload Video".
- Enter a video name and optional version label.
- Select your MP4/MOV file.
- Start the upload; it will resume automatically after interruptions.
Automatic Transcoding
Videos are automatically transcoded to watermarked previews (720p/1080p based on project/global settings). Original files are preserved for download once approved.
Review & Collaboration
Timestamped Comments
Add timestamped feedback tied to the playback position and keep discussions organized with threaded replies. Email notifications are sent when SMTP is configured.
Guest Mode
Share links support Password, Email OTP, Both, or guest access (when enabled). Guest mode is view-only and, by default, shows the latest version only. Downloads and assets remain blocked until videos are approved.
Approval Workflow
Clients on the project share page can approve when allowed. Admins can approve or unapprove individual video versions; projects move between IN REVIEW and APPROVED, and you can create dedicated SHARE ONLY projects for delivery-only access. Auto-approval can mark the project approved when every video has an approved version. After approval, clients can download original-quality video files and, if enabled, any attached assets (single files or ZIP bundles).
Asset Management
Attaching Supporting Files
Attach related assets to keep everything organized:
- Images/Thumbnails: JPG, PNG, GIF, WEBP, BMP, TIFF, SVG
- Audio: MP3, WAV, AAC, FLAC, OGG, M4A, WMA
- Documents: PDF, DOC/DOCX, TXT, RTF
- Project Files & Archives: PRPROJ, AEP, FCP, DaVinci, ZIP/RAR/7Z
- Supporting Videos: MP4, MOV, AVI, MKV, MXF
- Captions/Subtitles: SRT, VTT, ASS/SSA, SUB
Assets are extension-checked at upload, validated by magic bytes in the worker, and categorized (image/thumbnail, audio, video, subtitle, project, document, other). Admins can always download; clients/guests can download single assets or ZIP bundles only when the video is approved and the project’s “Allow asset download” setting is enabled.
You can set a custom thumbnail per video version using an uploaded image asset; if removed, the system falls back to the generated thumbnail.
Analytics & Insights
Activity Tracking
Monitor project engagement with built-in analytics (when enabled in Security Settings):
- Page visits per video/project
- Download events
Security events (rate limits, access violations) and advanced security settings (rate limits, token TTLs, hotlink protection) are available in the Security dashboard when enabled.
API Reference
ViTransfer provides authenticated JSON endpoints for the admin dashboard and share links. All requests use bearer tokens in the Authorization header.
Authentication
Admin login returns access and refresh tokens:
POST /api/auth/login
{
"email": "[email protected]",
"password": "your_password"
}Refresh tokens with POST /api/auth/refresh. Passkey enrollment and authentication live under /api/auth/passkey/* (optional).
Share Link Authentication
POST /api/share/[token]/verify– verify a project password.POST /api/share/[token]/send-otp– send an email OTP to a configured recipient.POST /api/share/[token]/verify-otp– verify OTP and issue a share token.POST /api/share/[token]/guest– guest access when enabled.
Projects API
GET /api/projects– list projects (admin).POST /api/projects– create a project (title, description, authMode, sharePassword, recipient info).GET /api/projects/:id– retrieve project details with videos, comments, and recipients.PATCH /api/projects/:id– update status, authentication mode, watermark/download settings, notifications, and guest options.DELETE /api/projects/:id– delete a project and its files.
Videos API
POST /api/videos– create a video record before upload (projectId, name, versionLabel, originalFileName, originalFileSize).TUS /api/uploads(pages API) – resumable uploads for videos and assets.PATCH /api/videos/:id– update name, version label, or approval state.DELETE /api/videos/:id– remove a video and associated files./api/videos/:id/assetsand related routes – create/list/delete assets, set thumbnails, generate download/zip tokens, or copy assets between versions.
Comments API
GET /api/comments?projectId=...– list comments for a project.POST /api/comments– create a comment or reply (projectId, videoId, content, timestamp, optional parentId).DELETE /api/comments/:id– delete a comment.
Analytics API
POST /api/analytics/visit– record a page visit (used by share pages).GET /api/analytics– aggregated analytics for all projects (admin).GET /api/analytics/:id– analytics for a single project (admin).
Deployment Options
Standard Docker
The recommended deployment method using Docker Compose:
docker-compose up -dUnraid
Use the Docker Compose Manager plugin on Unraid (recommended flow in README):
- Install "Docker Compose Manager" via the Unraid Apps tab.
- Download
docker-compose.unraid.ymland.env.examplefrom the repo. - Generate secrets, copy
.env.exampleto.env, and fill required values. - Check and adjust volume paths in
docker-compose.unraid.ymlfor your Unraid storage. - Create a new stack in Compose Manager, paste the compose file, and add your
.envcontents. - Compose Up, wait for initialization, then access
http://UNRAID-IP:4321.
TrueNAS Scale
- Navigate to "Apps" in TrueNAS web interface
- Click "Discover Apps"
- Search for "ViTransfer" or use custom app
- Configure application settings:
- Set container image:
crypt010/vitransfer:latest - Configure storage (recommend separate dataset)
- Set environment variables
- Set container image:
- Deploy application
Podman with Quadlet
Use the Quadlet templates in the quadlet/ directory for systemd-managed Podman deployments.
Create Quadlet File
Create ~/.config/containers/systemd/vitransfer.container (or copy quadlet/vitransfer-app.container) and set the required secrets:
[Container]
Image=docker.io/crypt010/vitransfer:latest
Environment=APP_PORT=4321
Environment=POSTGRES_PASSWORD=...
Environment=REDIS_PASSWORD=...
Environment=ENCRYPTION_KEY=...
Environment=JWT_SECRET=...
Environment=JWT_REFRESH_SECRET=...
Environment=SHARE_TOKEN_SECRET=...
[email protected]
Environment=ADMIN_PASSWORD=Admin1234
PublishPort=4321:4321
Volume=vitransfer-uploads:/app/uploads
[Service]
Restart=always
[Install]
WantedBy=default.targetRun the accompanying Postgres and Redis Quadlet units from quadlet/ or point the app container to existing services.
Enable and Start
systemctl --user daemon-reload
systemctl --user enable --now vitransferReverse Proxy Setup
CLOUDFLARE_TUNNEL=true when needed.
Troubleshooting
Quick Checks
- Review logs:
docker-compose logs(addapporworkerfor specific services). - Verify
.envis complete and matches your compose file. - Ensure disk space is available:
df -h. - If uploads fail, confirm proxy/body size limits and retry with a small file.
# All service logs
docker-compose logs
# Tail app logs
docker-compose logs -f app
# Tail worker logs
docker-compose logs -f workerSecurity Best Practices
Secret Management
- Generate Strong Secrets: Use
openssl rand -hex 32for DB/Redis (URL-safe) andopenssl rand -base64 32/64for encryption/JWT/share secrets - Rotate Regularly: Change secrets periodically, especially after team member changes
Access Control
- Strong Admin Password: Use minimum 16 characters with mixed case, numbers, symbols
- Limit Admin Accounts: Create admin accounts only when necessary
- Guest Mode Security: Use only for non-sensitive content
- Authentication Protection: Enable project passwords and/or OTP for sensitive content
- Passkeys: Enable passkey (WebAuthn) login for admins for phishing-resistant auth
Network Security
- Use HTTPS: Always deploy with SSL/TLS in production
- Firewall Rules: Restrict access to database and internal services
- Reverse Proxy: Use a hardened tunnel/proxy (tested with Cloudflare Tunnels)
- Rate Limiting: Built-in rate limits for auth, share, and uploads; tune in Security Settings
File Security
- Upload Validation: Server-side extension and magic-byte checks for videos and assets
- Storage Permissions: Ensure proper file system permissions on data volumes
Database Security
- Strong DB Password: Use complex database password (see secret management)
- Network Isolation: Keep database on private Docker network
Monitoring & Logging
- Security Events: Track rate-limit hits, OTP attempts, and access violations (toggle in Security Settings)
- Monitor Failed Logins: Review security events for suspicious authentication attempts
- Regular Reviews: Periodically review access and download activity (Analytics and Security pages)
Update Management
- Stay Updated: Regularly update to latest ViTransfer version
- Security Patches: Apply security updates promptly
- Dependency Updates: Keep Docker and system dependencies current
- Changelog Review: Read release notes for security advisories
Incident Response
If you suspect a security breach:
- Isolate: Immediately disconnect affected systems from network
- Assess: Review logs to determine scope of breach
- Contain: Change all passwords and secrets
- Notify: Inform affected users and stakeholders
- Report: If vulnerability in ViTransfer, report to maintainers
- Recover: Restore from clean backups if necessary
- Review: Analyze incident and improve security measures
