Moving to a simpler API interface


#1

Emby, and hence Jellyfin, had a bit of a problem trying to be “everything”, especially in its implementation of a custom webserver. This has ultimately resulted in a number of problems both for advanced administrators, as well as causing numerous problems with apps (requiring “WAN IP”, HTTP Chromecast removal in Chrome 72, etc.)

There has already been discussions about using Kestrel as the webserver, and that is a good idea. However, I have a more expansive idea to help us eliminate the current woes.

Fundamentally I think the problem is that Jellyfin will always assume that it is a proper webserver, capable of serving HTTP and HTTPS directly on the listening IP and port, without any concern for reverse proxies, etc. This is, frankly, bad app design - it introduces a huge amount of complexity just in order to have a “port” field in the UI.

Very very few other apps work this way. For instance, Django apps, NodeJS apps, and a lot of Ruby apps are instead designed to always run behind a webserver/reverse proxy, such as nginx. Frankly, I don’t see why we can’t or shouldn’t go this route as well.

The end goal with this plan would be to have a simple API running in the core server, listening on a single port (configurable, not via UI, but via a proper configuration file or an environment variable) likely on localhost, with nginx installed to both proxy the API as well as, if the (now-optional) WebUI within its webdir. The API can pretty much handle what it does now, but we could have it properly respond to proxy headers from NGinX, and encourage putting nginx in front of it.

This plan also serves as a double-edged sword for fully splitting out the Jellyfin web interface - we can always then assume we have a webserver running, and handle that properly.

The main downside I can see with this method is in installation: it’s “less easy” than just running a binary and going to the port. But it’s more flexible instead.

Our deployment guides would just need to be updated with this new setup procedure, and we could leverage platform-specific install scripts, OS packages, and tools like Ansible. Yes, this is a bit more complex for “ordinary” users, requiring nginx and the web UI, but a proper installer should solve that problem in each OS.


#2

Further discussion reveals I was misunderstanding Kestrel’s power, so yea this would be one particular implementation of the configurability of Kestrel. It should still be possible to run standalone by default of course, with full SSL support.


#3

As I mentioned in the discussion, I am ADAMANTLY against forcing potential users to setup a reverse proxy just to even try JF.

The ideal is that Kestrel replaces the custom HTTP server Luke made and allows us to package a full functional HTTP(S) server that serves up the web UI by default.

Those defaults can and should be overrideable by an admin allow you to put the server+webui behind the same proxy or even put them on different hosts without having to rely on Kestrel for security.

There are also frameworks we can put in place to turn up security on kestrel by default like turning on HSTS with SSL and the like.

I’m all for being able to piece and part out the server and secure it properly with big name web servers. I will not stand behind adding more layers for folks that don’t care or just want to try the software.


#4

I wanted to add that if something is configurable in a configuration file, then the UI should expose a way to change that setting as long as the configuration is writable. That helps those that don’t like messing with config files and keeps the philosophy clean :slight_smile:
I can see that jellyfin currently does rewrite the ip when it sees the header that reverse proxies set, so at least it has a little bit of regard for reverse proxies. But I think the API that the server uses to hand out its ip/port has to go, because the server cannot assume it knows where the client should connect and clients need to find better ways to find out where the server is (See where it currently is connecting, for example). Currently this only leads to clients connecting to the wrong place.

Regarding choice of HTTP framework, I have no idea about C# so I’m neutral in that regard :slight_smile:


#5

Disagree in a sense.
The idea of server knowing how to connect to it is fine, it’s just it cannot autodetect this thing when there’s a reverse proxy involved. So this probably should just be a setting - a lot of web projects have that setting (e.g. OnlyOffice and Nextcloud - last two I had experience with installing behind a reverse proxy).


#6

I still think it should go unless there’s a really important reason why things can’t work without it, but your proposal is fine to me and I’d be okay with that too since it ultimately lets me get things running correctly