Jitsi-meet: Jitsi cannot be run from a subdirectory

Created on 2 Dec 2019  Â·  31Comments  Â·  Source: jitsi/jitsi-meet

This Issue tracker is only for reporting bugs and tracking code related issues.

Before posting, please make sure you check community.jitsi.org to see if the same or similar bugs have already been discussed.
General questions, installation help, and feature requests can also be posted to community.jitsi.org.

## Description

Before closing this and referring to a previous issue, please consider I am a Systems Admin and have been writing JS for 7 years.

I'm VERY familiar with Nginx and how to configure it. The solution is not the web server. It may be Jitsi configuration I've overlooked.

It seems impossible to just run Jitsi not as the root application - I don't mean simply running it from a subdirectory, I mean running it as https://domain.com/jitsi-is-here/ vs. at domain URL root.

A subdomain is not a solution. This unnecessarily complicates using an SSL which is already configured for Jitsi. We should not need a separate server or SSL just for Jitsi.

## Current behavior

Running Jitsi in a location other than web root results in Jitsi exhibiting behavior that is in contrast with what you (Jitsi devs) have stated here:

https://github.com/jitsi/jitsi-meet/issues/2422

.. which is that you simply have to configure the web server.

When I provide the Jitsi Meet files in /api and try to hit my server at https://myserver.com/api, it fails to find files in relative paths - Jitsi fails to find them and update the relative paths.

This is evidenced by following the Nginx logs. Hitting my own app, for example and hitting relative paths in the URL, files load as expected, without issue; I am not rewriting or controlling the URL inside my app because this causes problems - as it appears Jitis is.

Instead of looking for it's files in the root of the path where Jitsi lives, it's looking for them at the server root.

If I wanted, for example to run my site on mysite.com/ and run Jitsi at mysite.com/api the result is that Jitsi looks for it's configuration and other files at mysite.com/ even though it is physically located in /api.

Nginx is configured to provide a path to /api. Its root is configured for /usr/share/mysite. The /api path is alias /usr/share/mysite/api which is the physical location of Jitsi Meet.

Jitsi doesn't seem to care that it's index.html loads from mysite.com/api; (it loads broken, but it loads - i.e. the web server is doing it's job) it still tries to path all of it's files relative to web root.

This is common configurable behavior (see: every CMS every created, exa. Wordpress, nearly every JVM app every created, see: Graylog, and many, many others) where you can usually set a base or root URL. There doesn't seem to be a configuration option for this.

However, I see this as a bug not because it can't be configured but because the behavior seems to ignore its own relative path. This doesn't make much sense.

If it is configurable, please let me know how, in detail I can configure this and I guess this could be closed.

## Expected Behavior

I should be able to use a subpath URL to use as Jitsi's root. Jitsi should not expect to be on the root or it should adapt.

Simply stated, I should be able to put Jitsi anywhere on my server, point the web server to this location and Jitsi should run.

## Possible Solution

  • Stop trying to force the relative path in your application.
  • Provide a specific configuration for using an alternate base URL (not web server config but application config).
  • Don't assume your app will be on the web root.

## Steps to reproduce

Move Jitsi Meet into a subdirectory. Configure Nginx to point to this directory on a non-web root path. Visit that URL and watch Jitsi break.

# Environment details

Debian Stretch.

config

Most helpful comment

I've been trying, without success, to accomplish this as well for a few days now. Can you reopen the issue @saghul ?

All 31 comments

How did you edit your cconfig.js? Specifically, what is the bosh option configured to?

How did you edit your cconfig.js? Specifically, what is the bosh option configured to?

I’ll have to check in a bit but I’m pretty sure it’s just set to the domain. Should this include the /api?

The bosh parameter yes, it’s an HTTP endpoint required to establish the signaling channel.

Other occurrences of the domain are ok since they mostly relate to XMPP configuration.

The bosh parameter yes, it’s an HTTP endpoint required to establish the signaling channel.

Other occurrences of the domain are ok since they mostly relate to XMPP configuration.

This didn't seem to have any impact. I updated this in the config.js in /etc/jitsi/meet.

So it appears as mydomain.com/api/http-bind now. This made no difference.

I am able to get the default Jitsi page with the "go" button and the auto-populating room name to load fine. It's when I click Go I get a 404.

Can you paste your nginx config? Also, when you hit go does it redirect to mydomain.com/room directly?

Can you paste your nginx config? Also, when you hit go does it redirect to mydomain.com/room directly?

Edit - sorry, yes it does go to /room.

Ultimately, since we are using this to embed Jitsi in our app, effectively recreating the UI, I will be running the UI on a separate server, in all likelihood, so this may be a non-issue, but it seems a waste to have to spin up a completely separate server just to be able to embed the iframe and also have my app on the web root.

I'll take a look at this, I suspect where the problem is.

but it seems a waste to have to spin up a completely separate server just to be able to embed the iframe and also have my app on the web root.

Not sure I understand. You don't need 2 servers. You could just use a subdomain with a different web root. Then you can proxy a subdirectory in your web root to the subdomain, but at thay point, you might as well use the subdomain directly.

I'll take a look at this, I suspect where the problem is.

but it seems a waste to have to spin up a completely separate server just to be able to embed the iframe and also have my app on the web root.

Not sure I understand. You don't need 2 servers. You could just use a subdomain with a different web root. Then you can proxy a subdirectory in your web root to the subdomain, but at thay point, you might as well use the subdomain directly.

I understand that’s possible, but it’s the same problem. It means two SSLs instead of one, it means DNS settings and it means the app isn’t a URL within routing of my app but a completely separate domain.

Again, this isn’t something that should be an hard to configure - it’s extremely common.

If Jitsi truly can be embedded in my app, it should be just that, not living on a separate domain.

There’s also the issue of accessing things inside the iframe - if things are on the same domain this is easy, if they are not it’s not allowed.

I understand that’s possible, but it’s the same problem.

I don't see how that's the case.

It means two SSLs instead of one

How is this a problem in 2019? With Let's Encrypt you pretty much don't need to do anything.

it means DNS settings

One CNAME is enough, since you are going to handle it in your own server.

it means the app isn’t a URL within routing of my app but a completely separate domain.

Not really if you proxy it from your own domain.

Again, this isn’t something that should be an hard to configure - it’s extremely common.

Agreed. I'm just trying to help you here, while this is solved on our side. This is not a feature that sees much use really so I can't promise you a speedy solution.

If Jitsi truly can be embedded in my app, it should be just that, not living on a separate domain.

We have different understandings of "embedding". What we mean by it is that any application can put the iframe as part of their application and customize it. Where the source of the iframe is, is irrelevant, as it should be transparent to the app.

There’s also the issue of accessing things inside the iframe - if things are on the same domain this is easy, if they are not it’s not allowed.

That's not entirely correct. All you need to do is set the right headers to allow it. meet.jit.si, for example, allows any origin. You could configure your installation to only allow your main domain.

I understand that’s possible, but it’s the same problem.

I don't see how that's the case.

It means two SSLs instead of one

How is this a problem in 2019? With Let's Encrypt you pretty much don't need to do anything.

it means DNS settings

One CNAME is enough, since you are going to handle it in your own server.

it means the app isn’t a URL within routing of my app but a completely separate domain.

Not really if you proxy it from your own domain.

Again, this isn’t something that should be an hard to configure - it’s extremely common.

Agreed. I'm just trying to help you here, while this is solved on our side. This is not a feature that sees much use really so I can't promise you a speedy solution.

If Jitsi truly can be embedded in my app, it should be just that, not living on a separate domain.

We have different understandings of "embedding". What we mean by it is that any application can put the iframe as part of their application and customize it. Where the source of the iframe is, is irrelevant, as it should be transparent to the app.

There’s also the issue of accessing things inside the iframe - if things are on the same domain this is easy, if they are not it’s not allowed.

That's not entirely correct. All you need to do is set the right headers to allow it. meet.jit.si, for example, allows any origin. You could configure your installation to only allow your main domain.

Setting up two domains, subdomain or not complicates a lot of things. Take into account the fact that an app developed in a corporate environment needs to meet certain requirements.

Also take into account that two domains shouldn't be technically necessary if your app was checking the for its files in the correct relative path (which is the reason I consider this a bug), and/or if the base URL was configurable.

Let's Encrypt is not a long-term option for SSL in our business environment. For a number of reasons, we must use SSLs from a specific vendor as that is our requirement, this means they are paid SSLs.

That's not entirely correct. All you need to do is set the right headers to allow it. meet.jit.si, for example, allows any origin. You could configure your installation to only allow your main domain.

As I mentioned, I'm a Sys Admin, and I have a lot of experience with Nginx so I'm aware of a number of security issues caused by improper or insecure configurations - this includes allowing something like cross-domain modification of iframes.

See this:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

Using "sameorigin" it will likely be possible to embed the iframe and also make calls and CSS modifications, but this requires the base domain to be the same; it can't be from a different subdomain.

The setting you're referring to is likely the "allow-from _uri_" which is deprecated and not supported in modern browsers, for good reason.

It seems like rather than admitting there is an actual problem, you're trying to say my use case doesn't matter.

It seems if the intention is to allow Jitsi to be embedded in an app and there is no requirement listed to run it on a separate domain, or configurable option to set the base URL, this intention and the actual functionality of Jitsi are at odds.

That's either a bug or simply something you don't want to support, but the solution isn't just "fix your web server".

Thanks for ellaborating.

It seems if the intention is to allow Jitsi to be embedded in an app and there is no requirement listed to run it on a separate domain, or configurable option to set the base URL, this intention and the actual functionality of Jitsi are at odds.

That's either a bug or simply something you don't want to support, but the solution isn't just "fix your web server".

As I said, this is something we will fix on our side. I was just trying to help you get going until we fix it because nobody (until now, that is) has noticed we have inadvertently broken this.

Hey @methodbox did you close this intentionally? AFAIK we haven't fixed this yet.

@saghul can you please reopen this issue?
For my setup it far simpler to run jitsi from a suburl of an existing server than anything else.
TIA

I really need this reopened as well. I want to run a Jitsi server that can only be used by a very select few people. My solution to this is running in at https://domain/<secret>/ but I can't make this work. This is perfectly secure if I always use a secure channel to transfer the URL to just the people I want to have access, and it avoids annoying authentication hassles.

This other guy wants to do the same thing: https://community.jitsi.org/t/how-to-modify-nginx-setup-in-order-to-use-a-soft-link-to-start-jitsi-meet/22880

I've been trying, without success, to accomplish this as well for a few days now. Can you reopen the issue @saghul ?

I have just run into this problem. I want to run jitsi-meet in a subdomain. The documentation that I read suggested (or I thought it did) that there was no difference between a domain and a subdomain. However, the quick install instructions say to set hostname to the sub-domain, which seemed to break the hostname.

I'd love to see a ROOT_URL feature as well, such that I can run jitsi behind my reverse proxy in a subfolder/path, since I only have/want one hostname.

I would suggest you all open your own, independent issues explaining what you're trying to do. They may or may not be related.

I closed the issue because I worked around the issue and don't have the luxury of time to wait for Jitsi to change it's behavior.

I also see progression toward and even less-favorable Nginx configuration in the latest version they just released which completely overrides any endpoints they don't explicitly use, which is a real pain to work around and no longer works with my previous solution.

Presently, I have solved the issue by putting our app inside a custom directory inside /usr/share/jitsi-meet. I then added the following Nginx configuration:

# assuming your folder name is /usr/share/jitsi-meet/myFolder

location = /myFolder {
    alias /usr/share/jitsi-meet/myFolder;
    index index.html;
}

This allows my app to be accessed at mydomain.com/myfolder, making this my app's webroot. It's not ideal, but it works fine.

Chris,

You have my sympathies. I always thought making things easy to install
was essential.

The fact that there is no GUI to set up any configuration is a sign that
these guys are living in a bunker for hairy chested web admins.

If my tests tomorrow don't work better we'll just go to Zoom. £11/mnth
for a meeting holder and no maintenance.

Mike

On 20/04/2020 19:42, Chris Shaffer wrote:
>

I would suggest you all open your own, independent issues explaining
what you're trying to do. They may or may not be related.

I closed the issue because I worked around the issue an don't have the
luxury of time to wait for Jitsi to change it's behavior.

I also see progression toward and even less-favorable Nginx
configuration in the latest version they just released which
completely overrides any endpoints they don't explicitly use, which is
a real pain to work around and no longer works with my previous solution.

Presently, I have solved the issue by putting our app inside a custom
directory inside |/usr/share/jitsi-meet|. I then added the following
Nginx configuration:

// assuming your folder name is /usr/share/jitsi-meet/myFolder

location= /myFolder {
alias/usr/share/jitsi-meet/clickbranch;
indexindex.html;
}

This allows my app to be accessed at |mydomain.com/myfolder|, making
this my app's webroot. It's not ideal, but it works fine.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/jitsi/jitsi-meet/issues/4917#issuecomment-616738676,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AA5NEXP54PRNGHEKZ4PFPW3RNSJQJANCNFSM4JULAIPQ.

Chris, You have my sympathies. I always thought making things easy to install was essential. The fact that there is no GUI to set up any configuration is a sign that these guys are living in a bunker for hairy chested web admins. If my tests tomorrow don't work better we'll just go to Zoom. £11/mnth for a meeting holder and no maintenance. Mike
…
On 20/04/2020 19:42, Chris Shaffer wrote: I would suggest you all open your own, independent issues explaining what you're trying to do. They may or may not be related. I closed the issue because I worked around the issue an don't have the luxury of time to wait for Jitsi to change it's behavior. I also see progression toward and even less-favorable Nginx configuration in the latest version they just released which completely overrides any endpoints they don't explicitly use, which is a real pain to work around and no longer works with my previous solution. Presently, I have solved the issue by putting our app inside a custom directory inside |/usr/share/jitsi-meet|. I then added the following Nginx configuration: // assuming your folder name is /usr/share/jitsi-meet/myFolder location= /myFolder { alias/usr/share/jitsi-meet/clickbranch; indexindex.html; } This allows my app to be accessed at |mydomain.com/myfolder|, making this my app's webroot. It's not ideal, but it works fine. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#4917 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5NEXP54PRNGHEKZ4PFPW3RNSJQJANCNFSM4JULAIPQ.

A GUI might be convenient, but managing installations via command line is standard in the Linux world. I think their configuration documentation could use some work, but I don't see this as antiquated.

As a general rule of thumb, if you aren't comfortable managing applications via command line, it's in your best interest to get a server administrator who is. It's a common misconception that all they do is install the application and it's done.

I have the benefit of being both an experienced JavaScript developer as well as a Linux server administrator, but this is commonly done by at least two individuals, one of whom should be comfortable with Bash and managing things through a shell.

I mean no insult to you, but if you don't have this experience, you also don't have the knowledge of properly maintaining and securing a server, which should be a concern.

I've solved the issue for me.

I simply had to adjust the base.html at /usr/share/jitsi-meet/base.html in the docker container (which is a bit cumbersome, as I had to find out that was the problem first, then docker cp it, adjust it and now have to bind mount it back in).
Could have been easier if there had been an environment variable for that (just like there is one for almost everything else), but once the "base" is adjusted everything works just fine!

The only problem left is, that the android app is not respecting subfolders added to the server URL and thus can't find the config.js.

I've solved the issue for me.

I simply had to adjust the base.html at /usr/share/jitsi-meet/base.html in the docker container (which is a bit cumbersome, as I had to find out that was the problem first, then docker cp it, adjust it and now have to bind mount it back in).
Could have been easier if there had been an environment variable for that (just like there is one for almost everything else), but once the "base" is adjusted everything works just fine!

The only problem left is, that the android app is not respecting subfolders added to the server URL and thus can't find the config.js.

Just in case someone wants to repeat it:
Step 1: docker cp <jitsi-web-container-id>:/usr/share/jitsi-meet/base.html .,
Step 2: Adjust the content <base href="/" /> to <base href="/<subfolder-path>/" />.
Step 3: bind mount that file back into its position in the container: -v <path-to-local>/base.html:/usr/share/jitsi-meet/base.html (either with this command in docker run or via docker-compose.yml)

At least that seems to work in my case.

@Mehrtuerer ’s post is a good example of why you should be opening separate issues - I’m not even using the Docker container, which makes these completely different issues.

``

@Mehrtuerer ’s post is a good example of why you should be opening separate issues - I’m not even using the Docker container, which makes these completely different issues.

In the end it is pretty much the same, though.
Docker(less) setup or not, you (just) need to adjust the "base" in base.html and everything works as expected.

``

@Mehrtuerer ’s post is a good example of why you should be opening separate issues - I’m not even using the Docker container, which makes these completely different issues.

In the end it is pretty much the same, though.
Docker(less) setup or not, you (just) need to adjust the "base" in base.html and everything works as expected.

I wasn’t saying your explanation was incorrect - in fact, I’m going to try it out ;).

I've solved the issue for me.
I simply had to adjust the base.html at /usr/share/jitsi-meet/base.html in the docker container

@Mehrtuerer
Thank you, your solution looks very promising, but I can't get it to work. Have you maybe done anything else in order to solve the issue?
I verified (with docker exec <webcontainername> cat /usr/share/jitsi-meet/base.html) that my volume is working correctly and I also restarted everything with docker-compose.

I still get this error when checking my-domain.de/jitsi:

Missing https://my-domain.de/jitsi/css/all.css?v=3969

Also if I check it locally on my server, I get the following:

wget localhost:8000/jitsi/css/all.css
HTTP request sent, awaiting response... 404 Not Found

My base.html looks like this:
<base href="/jitsi/" />

My nginx config looks as simple as that:

server {
  server_name my-domain.de;

  location /jitsi {
     proxy_pass http://localhost:8000;
  }

  location /other {
     proxy_pass http://localhost:8080;
  }
  #ssl stuff ...
}

If you have any hint I'd really appreciate it.

I've solved the issue for me.
I simply had to adjust the base.html at /usr/share/jitsi-meet/base.html in the docker container

@Mehrtuerer
Thank you, your solution looks very promising, but I can't get it to work. Have you maybe done anything else in order to solve the issue?
I verified (with docker exec <webcontainername> cat /usr/share/jitsi-meet/base.html) that my volume is working correctly and I also restarted everything with docker-compose.

I still get this error when checking my-domain.de/jitsi:

Missing https://my-domain.de/jitsi/css/all.css?v=3969

Also if I check it locally on my server, I get the following:

wget localhost:8000/jitsi/css/all.css
HTTP request sent, awaiting response... 404 Not Found

My base.html looks like this:
<base href="/jitsi/" />

My nginx config looks as simple as that:

server {
  server_name my-domain.de;

  location /jitsi {
     proxy_pass http://localhost:8000;
  }

  location /other {
     proxy_pass http://localhost:8080;
  }
  #ssl stuff ...
}

If you have any hint I'd really appreciate it.

My nginx config looks just slightly more complex, but I can't really explain what all the proxy_redirect and proxy_header lines are doing:

upstream jitsi {
    server jitsi:80; # Here jitsi is the jitsi-web container's name within the same docker-network as this nginx-proxy is in.
}

server {
    #ssl stuff ...

    location = /jitsi {
        return 302 /jitsi/; # Just make sure the next location rule always matches correctly
    }

    location /jitsi/ {
        proxy_pass http://jitsi/; # Here jitsi is the name of the upstream we configured earlier in the config file
        proxy_redirect off;
        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 https;
        proxy_set_header X-Forwarded-Host $server_name;
    }
}

Hope that helps.

Thank you very much for your post. I tried to use some parts of your config, but the jitsi:80 thing in your upstream didn't work for me. I use the default docker-compose for jitsi (apart from adding the volume for the base.html" and have installed nginx directly on my server. Maybe that's the problem.

Thank you very much for your post. I tried to use some parts of your config, but the jitsi:80 thing in your upstream didn't work for me. I use the default docker-compose for jitsi (apart from adding the volume for the base.html" and have installed nginx directly on my server. Maybe that's the problem.

This is getting a little off-topic: But in that case, of course, you have to publish your jitsi-web's port 80 to port 8000 (at least you are trying to reach it there (i.e. you need a "-p 8000:80" parameter when starting the jitsi-web container or the corresponding in docker-compose.yml) and it looks like the nginx-proxy does not correctly remove the "jitsi" subpath from the url, before giving it to localhost:8000. I suspect that is what the prexy_redirect and proxy_set_header entries might be doing, but I'm not a 100% sure. For me it seems to work with the config I have shown you. Best of luck.

The port mapping is already done in docker compose from 80 to 8000 (that is the reason why I used 8000 in the first place). I just didn't fully understand what your jitsi:80 did.

Anyway I noticed that I missed one important part of your nginx configuration: The trailing "/" in your proxy_pass (this was important for the part you mentioned: removing the jitsi subpath). After I added that to my config the Jitsy main page finally worked :) Thanks again for posting your config.

But when I want create/join a room I get the error that my connection as been closed. Unfortunately only GETs use the the right path. The POST for creating/joining a room does not (https://my-domain.de/http-bind?room=test Request Method: POST). I guess that is a problem for another ticket.

Here is the new part of my simple kinda working nginx config for other people with the same problem:

  location /jitsi {
    return 302 /jitsi/;
  }
  #important: 2x trailing "/" 
  location /jitsi/ {
    proxy_pass http://localhost:8000/;
  }

Thank you very much for your post. I tried to use some parts of your config, but the jitsi:80 thing in your upstream didn't work for me. I use the default docker-compose for jitsi (apart from adding the volume for the base.html" and have installed nginx directly on my server. Maybe that's the problem.

This is getting a little off-topic: But in that case, of course, you have to publish your jitsi-web's port 80 to port 8000 (at least you are trying to reach it there (i.e. you need a "-p 8000:80" parameter when starting the jitsi-web container or the corresponding in docker-compose.yml) and it looks like the nginx-proxy does not correctly remove the "jitsi" subpath from the url, before giving it to localhost:8000. I suspect that is what the prexy_redirect and proxy_set_header entries might be doing, but I'm not a 100% sure. For me it seems to work with the config I have shown you. Best of luck.

Again, a great example of why you may want to open your own issues (literally everyone else who has posted that isn't me or from Jitsi) because this isn't getting watched by Jitsi and this is way outside the scope of the original issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ralgozino picture ralgozino  Â·  3Comments

jidanni picture jidanni  Â·  3Comments

tanvir23 picture tanvir23  Â·  4Comments

mlelyakan picture mlelyakan  Â·  4Comments

rcidt picture rcidt  Â·  4Comments