Foreword
This tutorial is designed for complete beginners, guiding them through setting up a personal media library using Rclone and Jellyfin.
Jellyfin vs. Emby
Jellyfin and Emby are two of the most popular media library software options available today, each with its own set of pros and cons. Here’s a summary:
| Feature | Jellyfin (Free Version) | Emby (Free Version) |
|---|---|---|
| License | Completely open-source (GPLv2) | Partially open-source (core is open-source) |
| Cost | Completely free | Core features are free; some require payment to unlock |
| Client App Support | Widely supported, all apps are free | Some apps (like Android, Roku, Apple TV) require Emby Premiere |
| Live TV & DVR | Fully supported | Live TV is available, but DVR recording requires Emby Premiere |
| Hardware Transcoding | Fully supported for free | Requires Emby Premiere |
| Plugin Support | Community-driven, with a rich selection of free plugins | Offers official and community plugins (some are limited in the free version) |
| User Management | Full support, including user profiles and parental controls | Available |
| Metadata Fetching | Freely customizable, supports various free sources | Supported |
| Transcoding | Supported, with full control | Supported, but hardware-accelerated transcoding requires Emby Premiere |
| Remote Access | Supported for free, self-hosted | Supported for free, but Emby Connect is recommended for easier setup |
| UI & User Experience | Modern and clean, customizable | Polished and professional-looking interface |
| Update Frequency | Active community, frequent updates | Officially maintained, free version updates are slower |
| Community Support | Strong support from the open-source community | Official forum support, limited for free users |
| Privacy | No default data collection, user is in full control | Some telemetry is enabled by default (can be turned off manually) |
Given Jellyfin’s completely open-source nature and broad client support, I believe it’s a better choice for beginners and personal users compared to Emby. Therefore, this tutorial will be based on setting up Jellyfin.
Basic vs. Enhanced Version
This guide is split into two tutorials, which will walk you through setting up a “Basic” version and an “Enhanced” version, respectively. The differences and prerequisites for each are outlined below:
Basic Version
1️⃣ Introduction: The Basic version is primarily for users who don’t have a dedicated server with large storage. The main idea is to use Rclone to mount a cloud drive to your VPS locally, and then use this mounted media as the library for Jellyfin.
2️⃣ Prerequisites:
- A cloud drive with sufficient capacity. The required size will vary based on personal needs. If you also need BT download functionality, Pikpak is recommended, along with a premium subscription (only premium members have WebDAV access). If you prefer the more tedious method of downloading files locally first and then uploading them to the cloud, overseas cloud drives like Google Drive or OneDrive are recommended. Of course, if your content is legitimate, you can also use domestic cloud services. However, based on the overall experience, overseas cloud drives are the top recommendation. Additionally, to get enough storage space and decent upload/download speeds, subscribing to a premium plan for your chosen cloud service is highly advisable to meet your media storage needs.
- A VPS. Ensure you have a good direct connection to it from your local machine, and that it has decent bandwidth—around 100Mbps should suffice. A 1-core CPU with 1GB of RAM is enough.
- A domain name. This is optional; you can use the IP address and port, but you won’t be able to use HTTPS.
Enhanced Version
1️⃣ Introduction: The Enhanced version uses a server with large local storage to store media files and a separate server with better network routes to act as a reverse proxy. This approach enhances the viewing experience and improves the speed and efficiency of operations like library scanning.
2️⃣ Prerequisites:
- A storage server. Purchase one with a hard drive size that meets your needs.
- A routing server. If connecting directly to your storage server doesn’t provide a good experience, it’s recommended to use a routing server that has low latency and high-speed connections to both your local machine and the storage server. For example, use a server with RETN routes for a European storage server, or a premium US West Coast route for a US-based storage server.
- A domain name. This is optional; you can use the IP address and port, but you won’t be able to use HTTPS.
Rclone Installation and Configuration
Introduction to Rclone
Rclone is a command-line program to manage files on cloud storage. It is a feature-rich alternative to cloud vendors’ web storage interfaces. Over 70 cloud storage products support rclone including S3 object stores, business & consumer file storage services, as well as standard transfer protocols.
Rclone has powerful cloud equivalents to the unix commands rsync, cp, mv, mount, ls, ncdu, tree, rm, and cat. Rclone’s familiar syntax includes shell pipeline support, and --dry-run protection. It is used at the command line, in scripts or via its API.
Rclone mounts any local, cloud or virtual filesystem as a disk on Windows, macOS, linux and FreeBSD, and also serves these over SFTP, HTTP, WebDAV, FTP and DLNA.
Installation
Server-Side
Run the following script to install (for Linux/macOS/BSD): sudo -v ; curl https://rclone.org/install.sh | sudo bash
Local Machine
1️⃣ If you’re on macOS or Linux, you can run the same command as above: sudo -v ; curl https://rclone.org/install.sh | sudo bash
2️⃣ If you’re on Windows, go to the Rclone downloads page, select the appropriate version, and add the directory containing rclone.exe to your system’s environment variables. To confirm it’s installed correctly, open cmd and run rclone—it should execute without errors.
Configuration — Google Drive
After installation, run rclone config to add a new configuration.
n) New remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
n/r/c/s/q> n
Select n to create a new remote.
Type of storage to configure.
Choose a number from below, or type in your own value
[snip]
XX / Google Drive
\ "drive"
[snip]
Choose the type of storage. Select Google Drive, and be careful not to confuse it with Google Cloud Storage or Google Photos.
Google Application Client Id - leave blank normally.
client_id>
Google Application Client Secret - leave blank normally.
client_secret>
Leave client_id and client_secret blank and just press Enter.
Scope that rclone should use when requesting access from drive.
Choose a number from below, or type in your own value
1 / Full access all files, excluding Application Data Folder.
\ "drive"
2 / Read-only access to file metadata and file contents.
\ "drive.readonly"
/ Access to files created by rclone only.
3 | These are visible in the drive website.
| File authorization is revoked when the user deauthorizes the app.
\ "drive.file"
/ Allows read and write access to the Application Data folder.
4 | This is not visible in the drive website.
\ "drive.appfolder"
/ Allows read-only access to file metadata but
5 | does not allow any access to read or download file content.
\ "drive.metadata.readonly"
scope> 1
Next is the access permission setting. Option 1 grants access to all files on your Google Drive. If you don’t have any special requirements, just select 1. If you want read-only access, choose 2. For more restricted access, select one of the other options.
Service Account Credentials JSON file path - needed only if you want use SA instead of interactive login.
service_account_file>
Leave this blank and press Enter.
Use web browser to automatically authenticate rclone with remote?
* Say Y if the machine running rclone has a web browser you can use
* Say N if running rclone on a (remote) machine without web browser access
If not sure try Y. If Y failed, try N.
y) Yes
n) No
y/n> n
Since a VPS typically runs Linux without a GUI, select n here. We will complete the token acquisition on our local computer.
Copy the URL provided into your local browser. It will prompt you to log in to your Google account; choose the account for the Drive you want to mount. After successful authentication, you will see a “Success!” message.
Your terminal will then display the acquired token. Copy this token and paste it back into your VPS terminal.
Configuration — Pikpak
The initial steps are the same: create a new remote. I’ll name mine pikpak and select the following option:
58 / WebDAV
\ (webdav)
Next, go to the Pikpak official website, navigate to Settings -> Experimental Features -> WebDAV. PS: This feature requires a Pikpak premium membership and is currently read-only.

Obtain the following information: Endpoint, Username, Password, and Bearer Token.
Enter the URL into Rclone:
Option url.
URL of http host to connect to.
E.g. https://example.com.
Enter a value.
url> https://your_endpoint
Then choose option 8. Other.
Name of the WebDAV site/service/software you are using.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
1 / Fastmail Files
\ (fastmail)
2 / Nextcloud
\ (nextcloud)
3 / Owncloud 10 PHP based WebDAV server
\ (owncloud)
4 / ownCloud Infinite Scale
\ (infinitescale)
5 / Sharepoint Online, authenticated by Microsoft account
\ (sharepoint)
6 / Sharepoint with NTLM authentication, usually self-hosted or on-premises
\ (sharepoint-ntlm)
7 / rclone WebDAV server to serve a remote over HTTP via the WebDAV protocol
\ (rclone)
8 / Other site/service or software
\ (other)
Next, enter your username, password, and bearer token sequentially:
Option user.
User name.
In case NTLM authentication is used, the username should be in the format 'Domain\User'.
Enter a value. Press Enter to leave empty.
user> your_name
Option pass.
Password.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> y
Enter the password:
password:
Confirm the password:
password:
Option bearer_token.
Bearer token instead of user/pass (e.g. a Macaroon).
Enter a value. Press Enter to leave empty.
bearer_token> your_bearer_token
Edit advanced config?
y) Yes
n) No (default)
y/n> n
Configuration complete.
Options:
- type: webdav
- url: https://your_endpoint
- vendor: other
- user: your_name
- pass: *** ENCRYPTED ***
- bearer_token: your_bearer_token
Keep this "pikpak" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Mounting to the Local VPS
This step is the same for any configured cloud drive. First, create a mount point:
mkdir -p /mnt/pikpak
Then, run the following command to mount it:
rclone mount pikpak: /mnt/pikpak --daemon --allow-other --vfs-cache-mode writes --dir-cache-time 1000h
If you encounter an error, first install fuse: sudo apt install -y fuse3*
Command Parameter Explanation
1️⃣ rclone mount: The command to mount a remote.
2️⃣ pikpak:: The name of the remote you configured in Rclone. The colon : at the end signifies the root directory of the remote.
3️⃣ /mnt/pikpak: The local directory where the remote will be mounted.
4️⃣ --daemon: Runs Rclone as a background daemon process, so the mount persists even after you close the terminal.
5️⃣ --allow-other: Allows other users (including system services like Jellyfin) to access the mount point. This requires specific system configuration. You can omit this parameter if you are the only user.
6️⃣ --vfs-cache-mode writes: Sets the Virtual File System (VFS) cache mode to writes. This caches files locally before uploading them, which can improve the stability and speed of file writes and prevent failures due to network issues.
7️⃣ --dir-cache-time 1000h: Sets the directory structure cache time. Significantly increasing the cache time (1000 hours here) can drastically reduce the number of API requests to the cloud provider, speeding up file listing.
8️⃣ --log-file /var/log/rclone.log: Specifies the path for the log file, which is useful for troubleshooting.
9️⃣ --log-level INFO: Sets the log level to INFO, recording general information and errors. For debugging, you can change this to DEBUG.
You can add, remove, or modify these parameters as needed.
At this point, you’ve successfully mounted your cloud drive to your local system!
Installing and Configuring Jellyfin
Install Jellyfin
Run the command: curl -s https://repo.jellyfin.org/install-debuntu.sh | sudo bash
If you don’t have curl installed, you can use wget -q -O- instead. For more advanced users, the complete installation steps can be found in the official documentation. After installation, Jellyfin will run as a service. You can manage it using sudo systemctl {action} jellyfin.service or sudo service jellyfin {action}.
Configure Jellyfin
After the installation is complete, Jellyfin will be running on the default port 8096. Open your browser and navigate to http://your_ip:8096 to begin the configuration. When adding a media library, select the absolute path of your locally mounted directory as the media location.
Enhanced Version
Copying Files from Pikpak to Local Storage
Run the following command: rclone copy pikpak:path_to_your_file /media/path_to_your_dir --progress --checksum --transfers=8 --checkers=8
Command Explanation
1️⃣ rclone copy: This command copies files. It will only copy files that are new or different on the source (Pikpak) compared to the destination (local), and it will not delete any extra files at the destination.
2️⃣ pikpak:: The name of the Pikpak remote you configured in Rclone. The trailing colon : signifies the root directory.
3️⃣ /media/: Your local destination folder. Ensure you have write permissions for this directory.
4️⃣ --progress (or -P): Displays a real-time progress bar in the terminal, showing transfer speed, elapsed time, estimated remaining time, etc. Highly recommended.
5️⃣ --checksum: By default, Rclone determines if files are identical based on size and modification time. This flag forces Rclone to compare file hashes (checksums) after copying to ensure data integrity. It adds a small amount of CPU overhead but greatly increases reliability.
6️⃣ --transfers=8: Sets the number of concurrent file transfers. The default is 4. If you have a good network connection and many small files, increasing this value (e.g., to 8 or 16) can significantly boost overall transfer speed.
7️⃣ --checkers=8: Sets the number of parallel threads for checking files. This can speed up the initial check phase when comparing a large number of files.
Using a Routing Server as a Reverse Proxy
Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Alternatively, install Testing releases:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-testing-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-testing.list
sudo apt update
sudo apt install caddy
Configure the Caddyfile
Edit the Caddyfile using nano or vim:
your_domain:8066 {
reverse_proxy your_ip:8096 {
transport http {
read_buffer 0
read_timeout 300s
write_buffer 0
write_timeout 300s
}
# Remove sensitive headers
header_up -X-Real-IP
header_up -X-Forwarded-For
header_up -X-Forwarded-Proto
header_up Host {host}
header_up X-Forwarded-Host {host}
}
}
Save the file, exit the editor, and run systemctl reload caddy. You can now log in to your Jellyfin server through your client using your_domain:8066. This setup also enables HTTPS!
Change the Media Path
Since your media files are now stored locally on the storage server, remember to update the media path in Jellyfin to the local storage path instead of the cloud drive mount path!
And that’s a wrap! 🎉🎉🎉