louislam / uptime-kuma

A fancy self-hosted monitoring tool
https://uptime.kuma.pet
MIT License
57.48k stars 5.19k forks source link

Subfolder support (publicPath) #147

Open siimots opened 3 years ago

siimots commented 3 years ago

Problem: I'm using nginx to proxy localhost:3001 to domain.com/kuma, but at the moment vue app expects that everything is served from root (domain.com/assets/vendor.a54d5402.js) and all assets get 404, because all files are in kuma subfolder (domain.com/kuma/assets/vendor.a54d5402.js) not in root directory.

Solution: I'm not familiar with vue, but I guess it needs this public path setting for relative paths: https://cli.vuejs.org/config/#publicpath https://vitejs.dev/config/#base

If there are no other obvious limitations then please consider using relative paths.

It is great app & thanks for your work!

louislam commented 3 years ago

Just trying to implement this and realized that it is much harder than I thought, because express.js itself is not so friendly with subdirectory.

For example, in express.js you defined a route "/", it still points to "domain.com" rather than "domain.com/kuma", no matter what you have done in reverse proxy.

I cannot find any solution from the Internet that without hardcoded the subdirectory in the source code. I marked it as "help wanted" see if anyone know how to do it in a smart way.

chakflying commented 3 years ago

I guess a really dumb way would be to define a route in the server

.get('/basepath', function (req, res, next) {
    if (req.accepts("html")) {
        res.send(process.env.basepath);
        ...

and then in the front-end, check this route on load, and use this path to construct all links.

siimots commented 3 years ago

Loading js/css assets works fine with this vite.config.js:

export default defineConfig({
  base: "./",
  plugins: [
      vue(),
      legacy({
          targets: ['ie > 11'],
          additionalLegacyPolyfills: ['regenerator-runtime/runtime']
      })
  ]
})

Both root & subfolder are fine and resources are found.

But in subfolder websocket socket.io url is still fixed to root path. wss://example.com/socket.io/?EIO=4&transport=websocket

should be (kuma subfolder) wss://example.com/kuma/socket.io/?EIO=4&transport=websocket

Websocket.io has several path options, but I'm not sure what is best way to make it work in both root&subfolder setup at the moment.

Edit: After some testing I haven't found good & reasonable solution. Subdomain is better choice at the moment :)

louislam commented 3 years ago

Do you know which open source web apps are supported to map to a subdirectory? Maybe I can look into their source code.

xorguy commented 3 years ago

Linuxserver.io (https://github.com/linuxserver/reverse-proxy-confs) have several config samples for applications supporting being on subfolder and subdomain, maybe this can help. Vaultwarden (https://github.com/dani-garcia/vaultwarden) is another tool that have websockets, if I'm not mistaken, and can be deployed to subdomain or subfolder.

mind-overflow commented 3 years ago

Just commenting to follow the issue, as I'm really interested in this too.

gaby commented 3 years ago

@louislam @siimots Try using this:

location ^~ /kuma {
    rewrite ^/kuma(.*)$ $1 last;
}

It should rewrite (internally) any request to /subfolder to /

trogper commented 3 years ago

Wouldn't the problems be solved if all the links on frontend were relative? Additionally HTML Base element could be used

ghost commented 3 years ago

@louislam @siimots Try using this:

location ^~ /kuma {
    rewrite ^/kuma(.*)$ $1 last;
}

It should rewrite (internally) any request to /subfolder to /

Confirming that I haven't managed to find any combination of rewrite rules that will allow Uptime-Kuma to be proxied from a subfolder (including the one above).

trogper commented 3 years ago

@es9o @gaby this still leaves a few issues on the frontend, which has "hard-coded" absolute paths e.g. to /assets/ and /socket.io/ My temporary solution is to host kuma on another port of the same (sub)domain. Apache listens on port 443 (https) and proxies it to kuma on 3001

louislam commented 2 years ago

After 12 hours of testing and trying and researching on the internet, I'm at the end. Nothing really works. (I am crazy in my head.)

Please solve the problem. Thank you.

My personal workaround is to exclude the "other" folders.

        ProxyPass        /test.html     !
        ProxyPass        /index.html    !
        ProxyPass        /html          !
        ProxyPass        /shop          !

That why I said before:

Just trying to implement this and realized that it is much harder than I thought

It is almost impossible, because express.js do not support it. Also need to deal with Vue.js / WebSocket path issues.

I close it now, as it is technically impossible.

mind-overflow commented 2 years ago

Hello and thanks for your answer. You should keep it open to give the chance to add some more information or an other workaround.

I am convinced that there is a solution if there is someone who knows the apache rewrite rules well.

Yeah exactly, closing the issue doesn't make it a non-issue. The issue is still there, just not tracked. Someone will probably open another identical one in a few months/weeks as this wasn't solved. Maybe just add a "later" label instead?

michaelkrieger commented 2 years ago

I am convinced that there is a solution if there is someone who knows the apache rewrite rules well. This isn't a matter of rewrite. It is properly rewriting to the appropriate spot on the web server. Reverse proxies add the X-Forwarded-Prefix in whatever they remove so the application, when building a URL, will know to add that to anything it generates. It gets to the right place ( you can view source to see ) but then the /assets/ and so on are hardcoded. These appear to be done at build time by the underlying tools like Vue.

You should keep it open to give the chance to add some more information or an other workaround. I agree. In an era of reverse proxies behind SSL for everything, having a custom X-Forwarded-Proto, X-Forwarded-Prefix and X-Forwarded-Host should be obeyed. Or at the very least, the app could be manually configured with an environment variable BASE_URL which is then brought in with import.meta.env.BASE_URL which is determined by by the base config option. Not sure if that's at runtime of buildtime though.

I'd just like this issue to stay open. Maybe one day the underlying tools will come around.

michaelkrieger commented 2 years ago

If there's an interest, I'm happy to explore this issue more.

There is some suggestion here that sys "if the value (publicPath) is set to an empty string ('') or a relative path (./) so that all assets are linked using relative paths. This allows the built bundle to be deployed under any public path". Wouldn't that solve our issue entirely just by setting the public path to a relative URL?

louislam commented 2 years ago

I had spent some time on this previously, as I said before I am quite sure that it is impossible. Just don't want to give a false hope to anyone, that's why I closed it.

Because Uptime Kuma bundled everything in a single application, we have to deal with:

Three things all come together that make it impossible to support a reverse proxy on a sub-directory.

trogper commented 2 years ago

image Look Ma! Kuma in subdirectory!

I have pushed the changes to my fork I have tested it only manually in the browser, there might b something broken and the implementation is not very clean. Treat it as a proof of concept and feel free to improve it

Edit: the BASE_PATH must start and end with slash, e.g. /kuma/

louislam commented 2 years ago

image Look Ma! Kuma in subdirectory!

I have pushed the changes to my fork I have tested it only manually in the browser, there might b something broken and the implementation is not very clean. Treat it as a proof of concept and feel free to improve it

Edit: the BASE_PATH must start and end with slash, e.g. /kuma/

OMG, you are genius! Thank you for proofing me wrong!

trogper commented 2 years ago

@pm-pm no idea. I am not working on it right now. I need to run existing tests and probably create new ones. I think it is not much of work, probably for less than a day. @louislam Have you looked at current implementation? Do you approve it?

louislam commented 2 years ago

@pm-pm no idea. I am not working on it right now. I need to run existing tests and probably create new ones. I think it is not much of work, probably for less than a day. @louislam Have you looked at current implementation? Do you approve it?

Feel free to create a pull request first. I am not quite free recently and there are many pull requests that I still have not reviewed, so it may get longer time to be approved.

m1cypher commented 2 years ago

I am late to this game so I might be opening a can of worms or missed an update. But I see the Primary Base URL in the settings and set it to https://kuma.domain.com and it doesn't work. I also realize that I think it is specifically asking for something like https://domain.com/kuma but that isn't how I do this in my environment so before I made a large change, I wanted to make sure I understand how you had it setup as well as if the fix for this had been pushed alreay.

Thank you for your reply.

trogper commented 2 years ago

I think primary base URL in settings is only used to generate URLs for push-type monitor. My subfolder deployment uses ENV variable to set the path. The path can be anything, it doesn't need to be exactly "/kuma"

m1cypher commented 2 years ago

What is your ENV variable?

trogper commented 2 years ago

See my comment https://github.com/louislam/uptime-kuma/issues/147#issuecomment-996979446 Or the PR https://github.com/louislam/uptime-kuma/pull/1092

trogper commented 2 years ago

@pm-pm what do you mean?

trogper commented 2 years ago

@pm-pm oh, alright. The PR is already open, #1092 I am willing to work on it, but I have a few questions about technical concerns, already stated in the PR. Louislam has not yet answered them

rbeier commented 2 years ago

Hi all :) any updates on this? When will the PR be merged?

trogper commented 2 years ago

I need someone to provide some feedback to the PR, then I can move on

fawqsir commented 2 years ago

I am using Version: 1.16.1 of uptime kuma just wondering on the progress? I am having the same issue of a blank page when trying to view example.com/kuma. I am using traefik. When I go to the site all is blank. When I strip the prefix 'kuma' and goto example.com/kuma it is instantly redirected to example.com/dashboard.

trogper commented 2 years ago

It is still not merged, I need to do some work on it before it's ready. Did not have much time for it until this week, so it might probably be ready in the coming weeks.

Ruskyy commented 2 years ago

Hi, im using version 1.17.1. And im facing a similar situation, where im tryhing to "park" kuma under a path using Nginx Has there been any development on this ?

trogper commented 2 years ago

@Ruskyy Yes, it is done in my fork of kuma and it's ready to be merged into official one. Merging is not my job, so can't give you any ETA

navilg commented 2 years ago

I am also stuck with same issue. @louislam Any possibility of getting this feature ?

vaughngx4 commented 2 years ago

@louislam Are we ready to merge this yet? I have a strange setup that this may fix. I have nginx in front of the app, proxied root to uptime.internal.lan/ and public status page at /status/mypage/ proxied uptime.mydomain.com/ which is blank with the same errors as stated above.

wtfz commented 2 years ago

@vaughngx4

I have similar situation. I use Cloudflare for my DNS and enable SSL encryption mode in Full (strict). Initially it works without HTTPS (80) but with HTTPS (443) it will shows blank page.Then I disable Browser Integrity Check based on https://github.com/louislam/uptime-kuma/wiki/Cloudflare-Side-Note. After that, both with and without HTTPS works. Hope this helps.

trogper commented 2 years ago

@vaughngx4 sorry, I don't think that this would help you. Kuma needs access to all urls, not just /status/mypage/. Most of the data (if not all) on status pages is sent through websocket at /socket.io/.

Maybe you could

But be aware this might not be secure, as the socket could be used to access other data

vaughngx4 commented 2 years ago

@wtfz @trogper thank you. I was not aware of the sockets path being used. I will look into it and see what can be done. The pages fails to load js and CSS as well, is this related to sockets path or root path?

trogper commented 2 years ago

@vaughngx4 Sorry, I forgot about that. I think they are in /assets/

jamshidyerzakov commented 2 years ago

Hey guys :)

Any updates on this?

trogper commented 2 years ago

@jamshidyerzakov No

vaughngx4 commented 1 year ago

@vaughngx4 sorry, I don't think that this would help you. Kuma needs access to all urls, not just /status/mypage/. Most of the data (if not all) on status pages is sent through websocket at /socket.io/.

Maybe you could

* redirect `uptime.mydomain.com/` to `uptime.mydomain.com/status/mypage/`

* proxy `uptime.mydomain.com/status/mypage/` to `uptime.internal.lan/status/mypage/`

* proxy `uptime.mydomain.com/socket.io/` to `uptime.internal.lan/socket.io/`

But be aware this might not be secure, as the socket could be used to access other data @trogper

I was able to get this working without the use of /sockets.io/. By doing the following:

and I assume /api is protected by authorization?

I don't mind sharing since it's public: https://uptime.sintelli-tech.com

Seems to be working fine.

trogper commented 1 year ago

@vaughngx4 The website does not load for me. I get a bunch of 503 and 403 errors in devtools. image

vaughngx4 commented 1 year ago

@trogper I see, will do more testing but the page mostly works yes? The logo doesn't load but the service status shows correctly. The setup is getting a bit complicated, using HAproxy to match the domain name and paths.

EDIT: 503 would be because the route is blocked or unkown to the proxy and 403 I presume it's looking in the wrong base path. Will look into it.

trogper commented 1 year ago

No, it does not lead at all, the page stays white

vaughngx4 commented 1 year ago

No, it does not lead at all, the page stays white

@trogper Strange as I can view it using an external connection ( Firefox )

vaughngx4 commented 1 year ago

@trogper Sorry for diluting this thread, my final note on the redirects:

Using HAProxy this is my ACL: uptime-acl

These are the corresponding actions: uptime-actions

I realized that I was viewing a cached version earlier. This should work fine.

zszen commented 1 year ago

Need this optimazed

thedev132 commented 1 year ago

@louislam Is this still in progress? I'm trying to make my own and I almost succeeded until the js file in the dist folder I downloaded started showing errors about it trying to connect to 127.0.0.1:3001/socket.io/ but my web socket is on 127.0.0.1:3001/kuma/socket.io/. I can't seem to adjust the code in that js file because it is completely unreadable. Did anyone have any issues with this? Any help is appreciated!

trogper commented 1 year ago

You have to edit the source code, not the built minified file. Look at changes in my PR to see what needed to be changed. It is an older version, so there will probably need more to change. #1092/changes

thedev132 commented 1 year ago

I saw your changes, but where can I find the source code of the minified file? Your changes don't show any files in the dust folder. Your fork also does not have a dist folder to base off of. Thank you for helping!

trogper commented 1 year ago

The dist folder is created by the build process. The minified file is from all the js and Vue files in src (more or less)