Skip to content
Swiftly Music Blog Discord GitHub
  1. Swiftly Player
  2. Blog

Jellyfin remote access: reach your server from outside, safely (2026)

VPN mesh, reverse proxy, Cloudflare Tunnel or port forwarding for Jellyfin: security, setup effort, video terms, and the server settings that matter.

By Swiftly Player9 min read

Disclosure: we build Swiftly Player, one of the clients in this article. We point out where other apps do better.

Your Jellyfin server works at home. Now you want it on the road. There are four common ways to get there, and they differ in how much of your server they put on the public internet. This article compares them and lists the Jellyfin settings that go with each. Setting names are taken from Jellyfin 12.1, the current release at the time of writing (release v12.1).

TL;DR

  • VPN mesh (Tailscale or plain WireGuard): nothing is exposed to the public internet. Every device that watches needs the VPN client. Good default for you and your household.
  • Reverse proxy with HTTPS (Caddy or nginx): the setup Jellyfin's own docs recommend when you do want a public address. You open ports 80 and 443 to the proxy, not Jellyfin's port.
  • Cloudflare Tunnel: no open inbound ports. But on Free, Pro and Business plans, video over a public hostname falls under Cloudflare's CDN terms, which require a paid Cloudflare service for video.
  • Port forwarding straight to Jellyfin: Jellyfin's docs call it insecure and not recommended.
  • Behind a proxy, set Known proxies in Jellyfin, or remote access settings will not work correctly.
  • Set Internet streaming bitrate limit (Mbps) so remote streams fit your upload speed.

Option 1: VPN mesh with Tailscale or WireGuard

How it works

A VPN puts your phone and your server in the same private network. Jellyfin is only reachable inside it.

WireGuard is the underlying VPN protocol. It carries IP packets over UDP. Each peer has a public key, and each key is tied to the tunnel IP addresses that peer may use. WireGuard calls this Cryptokey Routing.

Tailscale builds on WireGuard. It connects your devices into a peer-to-peer mesh called a tailnet. It works across NAT and firewalls without port forwarding. When a direct connection is not possible, traffic goes through a relay. Per Tailscale's connection types page, relayed traffic is still end-to-end encrypted with WireGuard, but relays are generally slower and may have lower maximum throughput than a direct connection. For video, check whether your devices connect directly.

Setup outline (Tailscale)

Based on Tailscale's install guide:

  1. Sign up at tailscale.com with a supported identity provider.
  2. Install the Tailscale client on the Jellyfin server and log in.
  3. Install the client on each device you watch on and log in with the same account.
  4. Open the Machines page in the admin console. Your server is listed there.
  5. In your Jellyfin client, use the server's Tailscale IP (a 100.x.y.z address) or its MagicDNS name, plus port 8096.

With plain WireGuard, you do the same by hand: generate keys, write a config file per peer, and make the WireGuard endpoint at home reachable over UDP, which usually means one port forward on the router.

Tradeoffs

  • Nothing about Jellyfin is public.
  • Every viewer needs the VPN app. That is fine for your own devices. It is harder for family members on a smart TV.

Option 2: Reverse proxy with HTTPS

Why put a proxy in front

Jellyfin can serve HTTPS itself. Still, Jellyfin's networking docs strongly recommend handling HTTPS termination on a separate reverse proxy. The proxy holds the certificate and passes requests to Jellyfin. The same page advises a trusted certificate authority such as Let's Encrypt and strongly discourages self-signed certificates.

Jellyfin's reverse proxy guide says the proxy must pass on X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host. It also needs WebSocket support. You open TCP ports 80 and 443 on the router, pointing to the proxy. UDP 443 is only needed for HTTP/3. The guide also warns about logging full request paths, since URLs can contain tokens such as api_key.

Caddy

Caddy is the first option in Jellyfin's list. The Jellyfin Caddy page gives this Caddyfile:

example.com
reverse_proxy 127.0.0.1:8096

That is the whole config. According to Caddy's Automatic HTTPS docs, Caddy gets and renews the certificate itself and redirects HTTP to HTTPS. This works if the domain's A/AAAA records point to your server and ports 80 and 443 reach Caddy. The reverse_proxy directive sets the three X-Forwarded-* headers by default and handles WebSocket upgrades.

nginx

nginx needs more lines. The Jellyfin nginx example sets the forwarded headers in the main location block:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;

It adds a separate location /socket block with proxy_http_version 1.1 and the Upgrade and Connection "upgrade" headers for WebSockets. It also turns off proxy_buffering for media. The directives are described in nginx's proxy module reference.

Tradeoffs

  • Any device can connect with no extra app.
  • The Jellyfin login page is reachable by anyone who finds the address. Use strong passwords.
  • You keep the proxy updated and watch its certificate renewal.

Option 3: Cloudflare Tunnel

How it works

Per Cloudflare's Tunnel docs, a small daemon called cloudflared runs next to your server. It opens outbound-only connections to Cloudflare. You need no public IP and no open inbound port. Visitors reach a hostname on Cloudflare, and Cloudflare passes the traffic down the tunnel.

Setup, from Cloudflare's guide:

  1. Add a domain to Cloudflare. This is a prerequisite.
  2. In the dashboard, go to Networking > Tunnels and create a tunnel.
  3. Run the install command it shows on your server.
  4. On the tunnel's Routes tab, choose Add route > Published application.
  5. Enter a hostname and set Service URL to http://localhost:8096.

Video and Cloudflare's terms

Cloudflare's Service-Specific Terms (last updated June 2, 2026) have a section on the CDN for Free, Pro and Business plans. It says you must use specific paid services, such as Stream, Images or the Developer Platform, to serve video and other large files via the CDN. Cloudflare reserves the right to disable or limit your use of the CDN if you serve video without those services.

Cloudflare's page Delivering Videos with Cloudflare connects this to tunnels directly. It states that public hostname routes of Cloudflare Tunnel send traffic through Cloudflare, and on Free, Pro and Business plans that traffic is subject to these terms. The same page says the restriction does not apply to private network routes. In a violation, Cloudflare may redirect your content or take other action.

Streaming Jellyfin video over a public tunnel hostname on those plans falls under these terms. Read the current version before relying on a tunnel.

Tradeoffs

  • No open inbound ports at home.
  • You need a domain on Cloudflare.
  • Video on a public hostname conflicts with the CDN terms on Free, Pro and Business plans.

Option 4: Port forwarding directly to Jellyfin

This means forwarding port 8096 on your router straight to the server. It is the quickest setup.

The networking docs explain that opening a port gives the next network full access to that port, and that opening a port directly to the internet is insecure and not recommended. Port 8096 is plain HTTP. Without HTTPS, your password and access tokens travel unencrypted across every network between you and home. Jellyfin also has an HTTPS port (8920 by default), but it needs a certificate, and the docs still recommend a reverse proxy for HTTPS.

Comparison table

VPN meshReverse proxy + HTTPSCloudflare TunnelDirect port forward
Jellyfin public on the internetNoYes, behind the proxyYes, via a Cloudflare hostnameYes, directly
Open inbound portsNone (Tailscale) or one UDP port (WireGuard)TCP 80 and 443None8096
Encryption in transitWireGuardHTTPSThrough Cloudflare's networkNone on 8096
Setup effortLow (Tailscale), medium (WireGuard)MediumMedium, needs a domain on CloudflareLow
Extra app on every viewing deviceYesNoNoNo
Suited for streaming videoYes; relayed Tailscale links can be slowerYes, limited by your uploadPublic hostnames on Free/Pro/Business fall under CDN video termsWorks, but not recommended by Jellyfin

Jellyfin settings to set

Known proxies

In Jellyfin 12.1, go to Dashboard > Networking. The field Known proxies takes a comma-separated list of IP addresses or hostnames of your proxies. The help text says it is required to use X-Forwarded-For headers properly and that the server needs a restart after saving (source string in jellyfin-web v12.1).

Without it, Jellyfin does not use the forwarded client IP. Jellyfin's networking docs warn that external access settings through a reverse proxy only work if known proxies are set correctly. Enter the IP of your Caddy or nginx host, or of the machine running cloudflared.

The same page has LAN networks. Per its help text, these count as local for bandwidth and remote access restrictions. If it is blank, all RFC1918 addresses count as local. The switch Allow remote connections to this server sits under Remote Access Settings. Two more fields:

  • Base URL adds a subdirectory. The docs note it breaks HDHomeRun, the DLNA plugin, Sonarr and Radarr, among others.
  • Published Server URI overrides the address Jellyfin reports, based on interface or client IP.

Internet streaming bitrate limit

Go to Dashboard > Playback > Streaming. The field is Internet streaming bitrate limit (Mbps). It is an optional per-stream cap for all devices outside your network. The help text warns it can raise CPU load through transcoding. The same field also exists per user in the user's profile settings (jellyfin-web source, v12.1).

Set it a bit below your home upload speed. It only works if Jellyfin can tell remote from local clients, which brings you back to Known proxies and LAN networks.

Quick Connect

Quick Connect lets a new device sign in without a username or password. The new device shows a 6-character code. On a device that is already signed in, you open Quick Connect in the user settings and enter the code. It is on by default. The switch is Enable Quick Connect on this server in the dashboard's General settings.

FAQ

Do I need a domain name?

For a VPN, no. You use the Tailscale IP or MagicDNS name. For a reverse proxy with a trusted certificate, yes, since Caddy's automatic HTTPS needs DNS records pointing at your server. Cloudflare Tunnel also requires a domain added to Cloudflare.

Is Cloudflare Tunnel forbidden for Jellyfin?

Cloudflare's terms do not name Jellyfin. They say that on Free, Pro and Business plans, serving video via the CDN without a paid Cloudflare service can lead to limits. Cloudflare's docs say tunnel public hostname traffic is covered by that, and private network routes are not. Check the current terms before you decide.

Does the bitrate limit apply at home?

No. It applies to devices outside your network. Jellyfin decides that using LAN networks and, behind a proxy, the forwarded client IP.

Summary

For your own devices, a VPN mesh like Tailscale keeps Jellyfin off the public internet. If others need a plain address without an app, use a reverse proxy with HTTPS, and set Known proxies. Cloudflare Tunnel avoids open ports, but its public hostnames on Free, Pro and Business plans fall under Cloudflare's CDN terms for video. Jellyfin's docs advise against forwarding port 8096 directly. In every case, set Internet streaming bitrate limit (Mbps) so remote streams fit your connection.

Related articles

All articles