isamert.net
About Feeds

Hosting Invidious on sub-folder with Nginx


If you intend to self-host Invidious within a sub-folder, like your-website.com/invidious/, this is not officially supported and is unlikely to be in the future. I understand their viewpoint, yet I believe this is a legitimate scenario. For an individual self-hoster, getting an additional domain solely for Invidious may not be that easy. While a subdomain remains an option, there are scenarios where it may not be viable.

Continuing with the example above, let's assume that you want to serve Invidious under your-website.com/invidious/. Firstly, follow the officail guide to install Invidious. Then we need to a few configuration changes in config/config.yml:

# If your nginx serves through https, then change this to 443:
external_port: 443

# Again, if your nginx serves through https, then this needs to be true:
https_only: true

# Your domain
domain: your-website.com

And here is the relevant nginx configuration:

# Change each instance of the text "/invidious/" with the subfolder
# path that you want in the following configuration:

location /invidious/ {
  # 3000 is the default port, change the following if you have changed
  # it (see config/config.yml port):
  proxy_pass http://127.0.0.1:3000/;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_set_header Host $host;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_redirect / /invidious/;

  # Now we are going to do some sub_filter'ing which is essentially
  # doing some simple string replacements on the response.

  # Disable compression (from invidious to nginx) so that sub_filter
  # works
  proxy_set_header Accept-Encoding "";

  # Disable sub_filter_once so that each instance of strings that we
  # want to replace gets replaced instead of getting replaced once.

  sub_filter_once off;
  sub_filter_types text/javascript application/json;
  sub_filter /api/ /invidious/api/;
  sub_filter /vi/ /invidious/vi/;
  sub_filter /channel /invidious/channel;
  sub_filter /ggpht/ /invidious/ggpht/;
  sub_filter /toggle_theme /invidious/toggle_theme;
  sub_filter /token /invidious/token;
  sub_filter /subscription /invidious/subscription;
  sub_filter 'src="/' 'src="/invidious/';
  sub_filter 'href="/' 'href="/invidious/';
  sub_filter 'action="/' 'action="/invidious/';
}

Also see the official nginx configuration for reference.

Of course this is not a very sound way to do things, each update to Invidious has a chance to cause some breakage but it works for now. I'll try to keep this updated.