If you have your own private Jellyfin server and want to expose it to public, then you have come to the right place! Recently, I just got free time to handle this issue, and I want to share my solution with you.
I have a NAS that installed TrueNAS as the operating system, and I deployed many private services using the pre-installed K3S, while Jellyfin is one of them. I have no public IP, so that I need to expose services by port forwarding. Before I exposed my Jellyfin service, I had configured an OpenVPN service and mapped the port to my VPS. Some of my friends wanted to use my Jellyfin service, since sharing my own ovpn file with my friends is risky, I decided to expose the service to public.
Principle of my solution
The logic is quite similar as what I did to my OpenVPN service, which is still port forwarding, but Jellyfin is a http service, for optimizing the experience, I also applied CDN (Thank you, Cloudflare!). The following graph can illustrate the architecture clearly:
I’m going to recommend a high performance and light weight port forwarding tool writen in Rust: rathole. Its principle likes Frp (another famous port forwarding tool) but better performance. According to my comparison, the peak speeds are almost the same, while rathole can keep the peak speed longer. The another benefit of rathole is asymmetric encryption without certificates. My jellyfin ran locally without https, so the encryption is necessary if transmitting the traffic on the internet.
For the following steps, the documentation has provided detailed explanation.
- Generate a private/public key pair using rathole binary
noiseprotocol and enable your rathole server
noiseprotocol and enable your rathole client
- (Optional) Configure the firewall accepting requests from your NAS only
The following shell can help you get your IP range, please run it once per day:
The official document of Jellyfin is pretty good. They provide many configurations and optimization advices for different web server to reverse proxy. You can just copy and paste from the document.
If you don’t want to use CDN, then we have already done.
Cloudflare is the CDN provider (Thank you, Cloudflare!). With the clean and powerful UI, you can use it easily. There are only two things you need to check out. The first is enabling websocket because jellyfin need to use websocket (if you check your web server configuration, you will know that). The another thing is the cache configuration. As a media system, everything you see is static resources including your videos. According to the default configuration, when you watch videos from jellyfin, the CDN system will try to download the video and cache it on edge nodes trying make it load faster next time. However, there are a lot of videos and sizes of them are pretty big. For example, usually you won’t watch the same video for many times in a month, and it’s a private service, which means there won’t be many users who access the cache. However, when you watch the video for the first time, it might spend a lot of time to cache it, so the cache like that won’t work effectively. Therefore, You should configure the cache setting to ignore your video resources.
There are a lot of means to expose a private service to the public, obviously, it’s not the only way to go. If you have any other or better measures, please let me know!