Build a Personal Media Server

Self-host your photos, videos, and docs with Jellyfin and Tailscale.

Introduction

30 Second Summary

Your phone is full of photos, your laptop has home videos from years ago, and your documents are scattered across folders you forgot existed. Wouldn't it be great to stream all of it from any device, like your own personal Netflix, without handing your files over to a cloud service?

In this project, you will set up a personal media server on your Windows laptop using Jellyfin, organize your media into libraries, install the Moonbase plugin for enhanced client support, and make everything securely accessible from any device using Tailscale.

What You'll Build

A personal media streaming service running on your Windows laptop that serves your photos, videos, and documents to any device on your private Tailscale network.

By the end of this project, you'll have:

  • A running Jellyfin media server with organized libraries for your photos, videos, and books.
  • The Moonbase plugin installed with the Moonfin web interface accessible alongside the stock Jellyfin dashboard.
  • Secure remote access via Tailscale so any device on your tailnet can stream your content from anywhere.
  • Secret Mission: Set up Tailscale Serve for clean HTTPS access with a memorable URL instead of an IP address and port number.

Are there any prerequisites?

You need a Windows 11 laptop and a Tailscale account with at least one other device connected (a phone, TV, or another computer). This guide walks you through installing and configuring everything else from scratch.

Install Jellyfin and Complete the Setup Wizard

To stream your photos, videos, and documents from anywhere, you need a media server running on your laptop. Jellyfin is a free, open-source media server that gives you full control over your content without subscriptions or cloud lock-in.

In this step, you will download and install Jellyfin on your Windows 11 machine, then walk through its setup wizard to create your admin account and configure networking for remote access.

In this step, get ready to:
  • Install the Jellyfin server on Windows 11 as a tray application.
  • Complete the setup wizard and create an administrator account.
  • Configure networking settings for remote access via Tailscale.
Download and install Jellyfin

Jellyfin runs as a lightweight tray application on your laptop. You will download the official Windows installer, run it, and Jellyfin will start automatically in the background.

  • Open your browser and navigate to the Jellyfin downloads page.
  • Select the Windows tab under Stable.
  • Download the .exe installer.
  • Run the installer once the download completes.

Do not install as a service

During installation, the installer will offer an optional step to install Jellyfin as a Windows service. Skip this option. The tray application mode is recommended for laptops because it only runs when you are logged in, which saves system resources when you are not actively serving media.

  • Accept the default settings and let the installer finish.
  • Once installation completes, Jellyfin starts automatically and appears as an icon in your system tray (the bottom-right corner of your taskbar).

What is the system tray?

The system tray is the small area at the bottom-right of your Windows taskbar, next to the clock. If you do not see the Jellyfin icon, click the up arrow (^) to expand the hidden icons area.

Jellyfin icon not appearing?

Make sure the installer finished without errors. If the tray icon is missing, try opening http://localhost:8096 in your browser. If the page loads, Jellyfin is running in the background but the icon is hidden. Click the up arrow in your taskbar to find it.

If the page does not load, restart your computer and check again. The installer sometimes needs a reboot to fully register.

help me troubleshoot why Jellyfin is not appearing in my system tray after installation on Windows 11

Complete the initial setup wizard

Now that Jellyfin is running, you need to configure it through the first-time setup wizard. This is where you create your admin account and set up networking for remote access.

  • Open your browser and navigate to http://localhost:8096.
  • The setup wizard loads automatically on a fresh install.

What are the setup wizard steps?

The wizard walks you through five pages: selecting a display language, creating an administrator account, adding media libraries, choosing a preferred metadata language, and configuring networking settings. You will skip the library setup for now and handle it properly in the next step.

  • On the Select Language page, choose your preferred language and click Next.
  • On the Setup Administrator Account page, enter a username and a strong password for your admin account.
  • Click Next.
  • On the Add Media Libraries page, click Next without adding anything. You will set up libraries properly in Step 2.
  • On the Set Preferred Metadata Language page, confirm your language and country, then click Next.
  • On the Networking Settings page, check the box for Allow remote access to this server.
  • Make sure Enable automatic port mapping is unchecked (disabled).
  • Click Next to finish the wizard.
  • Log in with the admin username and password you just created.

Why disable automatic port mapping?

Automatic port mapping uses UPnP to punch a hole through your router's firewall. This exposes your server directly to the public internet, which is a security risk.

You already have Tailscale running on your laptop. Tailscale creates a secure private network between your devices without exposing any ports publicly. It is a much safer approach for remote access.

Verify Jellyfin is running
  • Confirm you can see the Jellyfin dashboard in your browser at http://localhost:8096.
  • Check that the Jellyfin tray icon is present in your system tray (click the up arrow in the taskbar if it is not visible).

You should see the Jellyfin home screen with your admin username displayed in the top-right corner. The dashboard might look empty since you have not added any media libraries yet.

Seeing a blank page or login error?

If the setup wizard did not appear when you first visited http://localhost:8096, try pressing Ctrl+F5 to perform a hard refresh. The browser may have cached an older page.

If you see a login screen but cannot log in, the admin account may not have been created. Right-click the Jellyfin tray icon, select Stop Server, then Start Server. Refresh the browser and the wizard should reappear.

help me fix my Jellyfin setup wizard or login issues on Windows 11

Your Jellyfin server is installed and ready to serve content. Next up, you will organize your media files into folders and create libraries so Jellyfin knows where to find your photos, videos, and documents.

Organize Media and Create Libraries

Your Jellyfin server is up and running. Now it is time to give it something to serve.

A media server without media is like an empty bookshelf. In this step, you will create a clean folder structure for your files, then tell Jellyfin where to find them by creating libraries.

In this step, get ready to:
  • Create an organized folder structure for photos, videos, and books.
  • Add three media libraries in Jellyfin pointing to your new folders.
  • Verify your media files appear in the Jellyfin dashboard.
Create a media folder structure

Jellyfin needs a dedicated place on your computer to look for media files. A consistent folder structure keeps things tidy and makes adding new content easy later.

  • Press the Windows key to open your search bar.
  • Type PowerShell and press Enter to open it.
  • Create your root media folder and three subfolders by running these commands:
# Create the root media folder and subfolders
mkdir C:\Media\Photos
mkdir C:\Media\Videos
mkdir C:\Media\Books

What do these commands do?

The mkdir command creates directories. Windows automatically creates the parent C:\Media folder when you create a subfolder inside it.

Each subfolder will hold a different type of media. Keeping them separate lets Jellyfin apply the right metadata handling for each type.

  • Confirm the folders exist by running:
ls C:\Media

You should see Books, Photos, and Videos listed in the output.

  • Copy some sample media files into each folder. A few photos in C:\Media\Photos, a video or two in C:\Media\Videos, and a PDF or ebook in C:\Media\Books.

Use whatever files you have handy

Holiday photos, phone recordings, or downloaded PDFs all work perfectly. You just need a few files so Jellyfin has something to display.

Seeing 'Access Denied' errors?

Make sure you are running PowerShell as your regular user, not as Administrator. The C:\Media folder should be accessible to your normal user account without elevation.

Help me fix a permissions error when creating folders on Windows.

Add libraries in Jellyfin

Libraries tell Jellyfin which folders to scan and what type of content lives inside them. Each library gets its own section on the home page.

  • In the Jellyfin dashboard, click the gear icon in the sidebar to open Administration.
  • Select Libraries under the Server section.
  • Click the + button to add a new media library.

You will create three libraries, one at a time. Start with Photos.

  • Select Photos as the Content Type.
  • Set the Display Name to Photos.
  • Click the + button next to Folders to add a folder path.
  • Navigate to C:\Media\Photos and select it.
  • Click Save.

Now repeat the process for your Videos library.

  • Click the + button to add another media library.
  • Select Mixed Content as the Content Type.
  • Set the Display Name to Videos.
  • Click the + button next to Folders.
  • Navigate to C:\Media\Videos and select it.
  • Click Save.

Why Mixed Content instead of Movies?

The Mixed Content type is designed for personal or home videos. If you chose "Movies", Jellyfin would try to match your files against online metadata databases and fail to find results for personal recordings.

Finally, add your Books library.

  • Click the + button to add another media library.
  • Select Books as the Content Type.
  • Set the Display Name to Books.
  • Click the + button next to Folders.
  • Navigate to C:\Media\Books and select it.
  • Click Save.

Can't find your folder in the file picker?

Make sure you navigate to the C:\ drive root first, then open Media, then select the correct subfolder. The folder picker starts at a different location depending on your system.

Help me find my media folder in the Jellyfin library setup.

Verify your libraries appear
  • Click the Jellyfin logo in the top left corner to return to the home page.

You should see all three libraries listed on your home page: Photos, Videos, and Books. After a moment, Jellyfin scans your folders and your media files start appearing inside each library.

  • Click into each library to confirm your files are visible.

What if my files have not appeared yet?

Jellyfin scans new libraries automatically, but it can take a few seconds for files to show up. If you do not see them after 30 seconds, go to Administration, then Dashboard, and check the Scheduled Tasks section. You can manually trigger a library scan from there.

Your media is organized and Jellyfin knows where to find it. Next up, you will install the Moonbase plugin to unlock the Moonfin client experience.

Install the Moonbase Plugin

Your media libraries are stocked and ready to serve. Now it's time to extend your Jellyfin server with a plugin that unlocks support for Moonfin clients across all your devices.

Moonbase is the official server-side plugin for the Moonfin ecosystem. It enables settings sync across devices and serves a modern Flutter web interface right alongside the standard Jellyfin dashboard.

In this step, get ready to:
  • Add the Moonfin plugin repository to Jellyfin.
  • Install the Moonbase plugin from the catalog.
  • Verify the Moonfin web interface loads at its dedicated URL.
Add the Moonfin plugin repository

Jellyfin does not include the Moonfin plugin by default. You need to point Jellyfin at the Moonfin repository so it knows where to find the plugin files.

  • In the Jellyfin dashboard, click the gear icon in the sidebar to open Administration.
  • Select Plugins from the menu.
  • Click the Repositories tab at the top of the page.
  • Click the + button to add a new repository.
  • In the Name field, enter Moonfin.
  • In the URL field, paste the following repository URL:
https://raw.githubusercontent.com/Moonfin-Client/Plugin/refs/heads/master/manifest.json
  • Click Save.

What is a plugin repository?

A plugin repository is a URL that points to a manifest file. The manifest tells Jellyfin which plugins are available, their versions, and where to download them from.

By adding the Moonfin repository, you are telling Jellyfin to check this URL for available Moonfin plugins whenever you browse the catalog.

Don't see the Repositories tab?

In some Jellyfin versions, the tab may be labeled differently. Look for a Manage Repositories button in the top-right corner of the Plugins page instead.

help me find the Repositories section in my Jellyfin Plugins page

Install the Moonbase plugin

With the repository added, Jellyfin can now see the Moonfin plugin in its catalog. Time to install it.

  • Switch to the Catalog tab within the Plugins page.
  • Find Moonfin in the catalog list and click on it.
  • Click Install.
  • Restart Jellyfin by right-clicking the Jellyfin tray icon in your system tray and selecting Restart Server.
  • Wait for Jellyfin to restart, then log back in at http://localhost:8096.

Why do I need to restart?

Jellyfin loads plugins at startup. After installing a new plugin, the server needs a fresh start to pick up the new files and activate the plugin.

Can't see the tray icon?

Click the small up arrow in your Windows taskbar to reveal hidden system tray icons. The Jellyfin icon should appear there.

Verify Moonbase is working

Moonbase serves its own web interface at a dedicated URL path. If the plugin installed correctly, you can load this interface right now.

  • Open a new browser tab and navigate to http://localhost:8096/Moonfin/Web/.
  • You should see the Moonfin Flutter web interface load. This is a separate, modern UI that runs alongside the standard Jellyfin web interface.
  • Confirm your media libraries are visible within the Moonfin interface.

What is the Moonfin web interface?

The Moonfin web interface is a Flutter-based UI that runs at /Moonfin/Web/ on your server. It provides a different viewing experience from the stock Jellyfin dashboard while connecting to the same libraries and user accounts.

This is the same interface that Moonfin client apps use. Having it accessible in a browser means any device on your network can use it without installing a dedicated app.

  • As a second check, return to the Jellyfin dashboard at http://localhost:8096.
  • Navigate to Administration (gear icon), then select Plugins.
  • Confirm that Moonfin appears in the list of installed plugins.

Moonfin web interface not loading?

If you see a blank page or error at http://localhost:8096/Moonfin/Web/, the plugin's web assets may not have been deployed yet.

  • Go to Administration, then Scheduled Tasks.
  • Find the Moonfin Startup task and run it manually.
  • Refresh the /Moonfin/Web/ page in your browser.

If the page still does not load, try closing Jellyfin entirely from the system tray and reopening it.

help me troubleshoot the Moonfin web interface not loading after plugin installation

Your server now speaks the Moonfin language. Next up, you will connect to it remotely from another device on your Tailscale network and stream your media through a Moonfin client.

Connect via Tailscale and Moonfin Clients

Your Jellyfin server has organized media libraries and the Moonbase plugin is serving its Flutter web interface. Everything works on your laptop, but the real value of a media server is accessing it from anywhere.

Tailscale already connects your devices into a secure private network. In this step, you will find your laptop's Tailscale IP, create a dedicated viewer account, and connect a Moonfin client on another device to stream your media remotely.

In this step, get ready to:
  • Find your Tailscale IP and verify Jellyfin is reachable from another device on your tailnet.
  • Create a viewer user account so others can log in without your admin credentials.
  • Install and connect a Moonfin client on a remote device to stream your media.
Find your Tailscale IP and verify connectivity

Every device on your Tailscale network receives a stable IP address in the 100.x.x.x range. You need this address so your other devices know where to find the Jellyfin server.

  • Right-click the Tailscale tray icon in your system tray. If it is not visible, click the up arrow (^) in the taskbar to find it in the overflow area.
  • Look for your device's IP address displayed in the menu. It will start with 100. (for example, 100.64.0.1).
  • Write down or copy this IP address. You will need it throughout this step.

Use the CLI as an alternative

You can also find your Tailscale IP by opening PowerShell and running:

tailscale ip -4

This returns only your IPv4 address in the 100.x.x.x range.

Now verify that Jellyfin is reachable from another device on your tailnet.

  • Pick up another device that is already connected to your tailnet (such as your smartphone or another computer).
  • Open a web browser on that device.
  • Navigate to the following URL, replacing the placeholder with your actual Tailscale IP:
http://[[TAILSCALE_IP="your Tailscale IP (e.g. 100.64.0.1)"]]:8096

You should see the Jellyfin login page load on your remote device.

What is a tailnet?

A tailnet is your personal Tailscale network. It includes every device where you have signed into Tailscale with the same account. These devices can reach each other securely, no matter where they are physically located.

Traffic between tailnet devices is encrypted end-to-end. No one outside your tailnet can access your Jellyfin server, even though it has no firewall rules or port forwarding configured.

Don't see the Jellyfin login page?

Make sure both devices are signed into the same Tailscale account. Check that the Tailscale icon on your laptop shows a connected (active) state.

Confirm Jellyfin is still running by checking for its icon in your system tray on the laptop. If it is not there, reopen Jellyfin from the Start menu.

Double-check that you typed the IP address and port (:8096) correctly with no extra spaces.

Still stuck? Help me troubleshoot why my Jellyfin server is not reachable from my other device via Tailscale.

Create a user account for your viewers

Your admin account has full control over the server. For anyone else who will watch your media, create a separate viewer account with limited permissions.

  • Return to the Jellyfin dashboard on your laptop at http://localhost:8096.
  • Click the gear icon in the sidebar to open Administration.
  • Select Users from the menu.
  • Click the + button to add a new user.
  • Enter a username for your viewer (for example, viewer or a family member's name).
  • Set a password for this account.
  • Under the user's settings, confirm that Enable access to all libraries is checked. This is enabled by default.
  • Confirm that Allow remote connections to this server is checked for this user.
  • Click Save.

Why create a separate viewer account?

Your admin account can change server settings, delete libraries, and manage plugins. A viewer account can only browse and play media. This protects your server from accidental changes if someone else uses it.

Connect a Moonfin client

Moonfin is a dedicated media client built for Jellyfin servers. It provides a polished playback experience across phones, TVs, and computers.

  • On one of your other tailnet devices (Smart TV, phone, or computer), download and install the Moonfin app from the appropriate source:
  • Open the Moonfin app once installed.
  • When prompted to add a server, enter the following address (replacing the placeholder with your Tailscale IP):
http://[[TAILSCALE_IP="your Tailscale IP (e.g. 100.64.0.1)"]]:8096
  • Log in with the viewer account you just created (or your admin account).
  • Browse your media libraries and play a file to confirm streaming works.

You should see your Photos, Videos, and Books libraries listed. Select a video or photo and confirm it plays or displays correctly on your remote device.

Moonfin can't connect to the server?

Make sure you included the port number :8096 at the end of the address. Without it, the client will not find Jellyfin.

Confirm the device running Moonfin is connected to Tailscale. Check its Tailscale app to verify it shows an active connection to your tailnet.

If you see a certificate or HTTPS error, make sure you are using http:// (not https://). HTTPS is covered in the Secret Mission.

Help me troubleshoot why my Moonfin client cannot connect to my Jellyfin server over Tailscale.

Secret mission

Set Up Tailscale Serve for Clean HTTPS Access

Right now, accessing your Jellyfin server means remembering a 100.x.x.x IP address and a port number. That works, but it is not exactly memorable. In this secret mission, you will give your server a clean HTTPS URL that works automatically for anyone on your tailnet. No port numbers, no IP addresses, and a valid TLS certificate to boot.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on your local machine with free, open-source tools. There are no ongoing cloud costs or subscriptions to worry about.

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Jellyfin server installed on your Windows 11 laptop (includes Moonbase plugin, libraries, and user accounts).
  • Media folders at C:\Media (Photos, Videos, Books).
  • Tailscale Serve configuration proxying port 8096 over HTTPS.
  • Moonfin client app installed on your remote device.

Keep everything running

No action needed. Choose this if you are still actively using your media server and want it available at all times.

  • Leave Jellyfin running via the system tray icon for always-on access.
  • Your laptop must be powered on and connected to the internet for remote access to work.
  • Tailscale Serve continues running in the background, keeping your HTTPS URL active.

Pause - I'll come back to this later

Shut down the server to free up system resources, but keep everything installed so you can pick up where you left off.

  • Stop Tailscale Serve by opening PowerShell and running the command below.
  • Right-click the Jellyfin tray icon in your system tray and select Quit Jellyfin.
  • Your media files, libraries, and all configuration remain intact for next time.
tailscale serve off

What does this do?

The tailscale serve off command stops Tailscale from proxying traffic to your Jellyfin server. Your HTTPS URL will stop working until you run tailscale serve --bg 8096 again.

Delete - I don't want to use this again

Remove all project resources from your machine and start fresh. Follow these steps in order.

  • Stop Tailscale Serve by opening PowerShell and running:
tailscale serve off
  • Right-click the Jellyfin tray icon and select Quit Jellyfin to stop the server.
  • Open Settings on your Windows machine.
  • Select Apps, then Installed apps.
  • Find Jellyfin Server in the list, click the three-dot menu, and select Uninstall.
  • After the uninstaller finishes, manually delete the leftover data folder by running this in PowerShell:
Remove-Item -Recurse -Force "C:\ProgramData\Jellyfin"

Why delete this folder separately?

The Jellyfin uninstaller removes the program files but leaves your server configuration, plugin data, and library metadata behind in C:\ProgramData\Jellyfin. Deleting this folder ensures a complete removal.

  • Delete your media folders by running:
Remove-Item -Recurse -Force "C:\Media"
  • On your remote device, uninstall the Moonfin app through your device's app settings or app store.

Your media files are gone too

The command above deletes C:\Media and everything inside it. If you copied important files there, move them to another location before running this command.

That's a Wrap!

That's a Wrap!

Nice work! You just built a fully functional personal media server that streams your photos, videos, and documents to any device on your Tailscale network.

You've learned how to:

  • Installed and configured a Jellyfin media server on Windows 11 with organized libraries for photos, videos, and documents.
  • Enhanced your server with the Moonbase plugin, enabling Moonfin client support and a Flutter web interface for a polished viewing experience.
  • Connected your server to your Tailscale network for secure remote access and verified end-to-end streaming from a Moonfin client on another device.
  • Secret Mission: Configured Tailscale Serve for clean HTTPS access with automatic TLS certificates and a memorable URL.

Ready to quiz yourself?