[GH-ISSUE #1009] Feature request: Allow hosting / running the web app in sub path #707

Open
opened 2026-05-07 00:26:46 +02:00 by BreizhHardware · 8 comments

Originally created by @Raschmaschine on GitHub (Jan 23, 2024).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/1009

Hello there! First of all, I'd like to thank you for your awesome work on ntfy so far. Very appreciated!

At the moment, I'm running ntfy in a Docker container and using an Apache-based reverse proxy to embed the service into a sub path of my current infrastructure's domain web server. The relevant part of the site configuration boils down to something like this:

<Location /ntfy>
  ProxyPass http://<My Docker host's IP>:<ntfy port> upgrade=websocket
  ProxyPassReverse http://<My Docker host's IP>:<ntfy port>
</Location>

As expected, this allows subscribing and publishing to topics in the documented ways using HTTP (Webhook or PUT / POST requests) or WebSocket like PUT https://<My Domain>/ntfy/<topic>/send?..., https://<My Domain>/ntfy/<topic>, https://<My Domain>/ntfy/<topic>/ws. However, the web app under https://<My Domain>/ntfy or https://<My Domain>/ntfy/app falsely interprets its sub path as topic name ntfy and (according to my investigation) continuously tries to establish WS connections to /ntfy/ws. This path obviously does not exist or rather does not support WS.
grafik

I'm not quite sure about how the frontend determines its "base directory" for resolving topic paths, but I guess it's always the server root, or it is using absolute paths.

Due to the strange behavior of the web app, I have disabled it using some RewriteRules and a CSP header until further notice, but I'd love to deliver a more decent solution. (I'm aware you can disable the web app entirely, but I'd like to keep it enabled for testing purposes on the local network)

Using a subdomain as proposed in #398 is not achievable in my use case due to underlying circumstances I cannot influence.

In view of a couple of other similar requests, please consider implementing this web app feature. If I find enough time, I'll try to implement it myself and do a PR.

💡 Idea
Add the ability to specify the base directory / sub path / subdirectory / root directory (However named) in ntfy's web app.

💻 Target components
Web GUI (only that, I guess)

Related to: #398, #256, #258

Originally created by @Raschmaschine on GitHub (Jan 23, 2024). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/1009 Hello there! First of all, I'd like to thank you for your awesome work on ntfy so far. Very appreciated! At the moment, I'm running ntfy in a Docker container and using an Apache-based reverse proxy to embed the service into a sub path of my current infrastructure's domain web server. The relevant part of the site configuration boils down to something like this: ``` <Location /ntfy> ProxyPass http://<My Docker host's IP>:<ntfy port> upgrade=websocket ProxyPassReverse http://<My Docker host's IP>:<ntfy port> </Location> ``` As expected, this allows subscribing and publishing to topics in the documented ways using HTTP (Webhook or PUT / POST requests) or WebSocket like `PUT https://<My Domain>/ntfy/<topic>/send?...`, `https://<My Domain>/ntfy/<topic>`, `https://<My Domain>/ntfy/<topic>/ws`. However, the web app under `https://<My Domain>/ntfy` or `https://<My Domain>/ntfy/app` falsely interprets its sub path as topic name `ntfy` and (according to my investigation) continuously tries to establish WS connections to `/ntfy/ws`. This path obviously does not exist or rather does not support WS. ![grafik](https://github.com/binwiederhier/ntfy/assets/65172002/7e408dac-449f-4f11-85cd-0a19bc723cf1) I'm not quite sure about how the frontend determines its "base directory" for resolving topic paths, but I guess it's always the server root, or it is using absolute paths. Due to the strange behavior of the web app, I have disabled it using some RewriteRules and a CSP header until further notice, but I'd love to deliver a more decent solution. (I'm aware you can [disable the web app entirely](https://docs.ntfy.sh/config/?h=ntfy_web_root#config-options), but I'd like to keep it enabled for testing purposes on the local network) Using a subdomain as proposed in #398 is not achievable in my use case due to underlying circumstances I cannot influence. In view of a couple of other similar requests, please consider implementing this web app feature. If I find enough time, I'll try to implement it myself and do a PR. :bulb: **Idea** Add the ability to specify the base directory / sub path / subdirectory / root directory (However named) in ntfy's web app. :computer: **Target components** Web GUI (only that, I guess) Related to: #398, #256, #258
Author
Owner

@IjvenR commented on GitHub (Jan 31, 2024):

I second this.

Love the functionality, integrates easily in home integration and many other things (I use it with Node-Red automation), but I have the same issue with the webapp.
For now I have the "push notification" running by rewriting the url in NGINX proxy over "https://my.domain/ntfy" but opening the webapp via this url results in css, js and other type files being pulled up as "https://my.domain/app.css" instead of "https://my.domain/ntfy/app.css".

when I'm inside the LAN I use the webapp over the direct http route, but I would love to be able to use it on the go as well.

Here is my NGINX config if somebody is looking for a solution.

      location /ntfy {
        rewrite /ntfy/(.*) /$1 break;
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 3m;
        proxy_send_timeout 3m;
        proxy_read_timeout 3m;

        proxy_redirect off;
        client_max_body_size 0; # Stream request body to backend
        }

Keep up the good work!

Kind regards,
IjvenR

<!-- gh-comment-id:1919248547 --> @IjvenR commented on GitHub (Jan 31, 2024): I second this. Love the functionality, integrates easily in home integration and many other things (I use it with Node-Red automation), but I have the same issue with the webapp. For now I have the "push notification" running by rewriting the url in NGINX proxy over "https://my.domain/ntfy" but opening the webapp via this url results in css, js and other type files being pulled up as "https://my.domain/app.css" instead of "https://my.domain/ntfy/app.css". when I'm inside the LAN I use the webapp over the direct http route, but I would love to be able to use it on the go as well. Here is my NGINX config if somebody is looking for a solution. ``` location /ntfy { rewrite /ntfy/(.*) /$1 break; proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 3m; proxy_send_timeout 3m; proxy_read_timeout 3m; proxy_redirect off; client_max_body_size 0; # Stream request body to backend } ``` Keep up the good work! Kind regards, IjvenR
Author
Owner

@binwiederhier commented on GitHub (Mar 7, 2024):

I'd like that too, but honestly it requires too much work for too little gain. It does come up frequently, but it's likely going to break a bunch of things in various clients, so I wouldn't hold my breath.

<!-- gh-comment-id:1984117508 --> @binwiederhier commented on GitHub (Mar 7, 2024): I'd like that too, but honestly it requires too much work for too little gain. It does come up frequently, but it's likely going to break a bunch of things in various clients, so I wouldn't hold my breath.
Author
Owner

@christaikobo commented on GitHub (Nov 30, 2024):

@binwiederhier Hi, I understand making subpath work for web app is probably a lot of hassle.

Is it possible to at least make it work for attachments and Email notifications? Right now if I specify subpath in base url the docker container simply refuses to start...It used to work in older versions. I can strip off subpath using my reverse proxy.

<!-- gh-comment-id:2509136053 --> @christaikobo commented on GitHub (Nov 30, 2024): @binwiederhier Hi, I understand making subpath work for web app is probably a lot of hassle. Is it possible to at least make it work for attachments and Email notifications? Right now if I specify subpath in base url the docker container simply refuses to start...It used to work in older versions. I can strip off subpath using my reverse proxy.
Author
Owner

@manazoid commented on GitHub (Jan 9, 2025):

@binwiederhier Hello, why it is not planned yet? When I can wait the feature with subpath?

I need to put ntfy in traefik load-balancer. And it works fine with other software. But not with ntfy: /config.js breaks all logic of the application behind proxy.

<!-- gh-comment-id:2580579659 --> @manazoid commented on GitHub (Jan 9, 2025): @binwiederhier Hello, why it is not planned yet? When I can wait the feature with subpath? I need to put ntfy in traefik load-balancer. And it works fine with other software. But not with ntfy: /config.js breaks all logic of the application behind proxy.
Author
Owner

@chudbigot commented on GitHub (Mar 5, 2025):

Here are 2 nginx.conf blocks to make files work as well (/files, because /ntfy/files would probably break in some clients)

location /ntfy/ {
        proxy_pass http://127.0.0.1:2586;
        rewrite ^/ntfy(/.*) $1 break;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 3m;
        proxy_send_timeout 3m;
        proxy_read_timeout 3m;

        client_max_body_size 0; # Stream request body to backend
}

location /file/ {
        proxy_pass http://127.0.0.1:2586;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 10m;
        proxy_send_timeout 10m;
        proxy_read_timeout 10m;

        client_max_body_size 0; # Stream request body to backend
}

/ntfy/app/ however is still broken and just displays a white screen without any css (or js?) for me. curling /ntfy/app/config.js returns {"code":40401,"http":404,"error":"page not found"} (from ntfy, not nginx), but /ntfy/config.js works for some reason. Any idea how i can tell it to respect my sub-sub paths? I already tried setting web-root: to / and curling /ntfy/, it looks exactly like http://127.0.0.1:2586/ but unlike connecting to it directly, it still throws me a white screen.
I can also curl /ntfy/static/media/index-c5f33103.js, so I really don't see what the problem could be, unless there are some weird hard coded paths that should be easy to fix.
Anyway, ntfy with attachments works so far, so I won't complain, but I'd still like to see less spaghetti code with hard coded paths :)

<!-- gh-comment-id:2699874561 --> @chudbigot commented on GitHub (Mar 5, 2025): Here are 2 nginx.conf blocks to make files work as well (/files, because /ntfy/files would probably break in some clients) ```nginx location /ntfy/ { proxy_pass http://127.0.0.1:2586; rewrite ^/ntfy(/.*) $1 break; proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 3m; proxy_send_timeout 3m; proxy_read_timeout 3m; client_max_body_size 0; # Stream request body to backend } location /file/ { proxy_pass http://127.0.0.1:2586; proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 10m; proxy_send_timeout 10m; proxy_read_timeout 10m; client_max_body_size 0; # Stream request body to backend } ``` /ntfy/app/ however is still broken and just displays a white screen without any css (or js?) for me. curling /ntfy/app/config.js returns `{"code":40401,"http":404,"error":"page not found"}` (from ntfy, not nginx), but /ntfy/config.js works for some reason. Any idea how i can tell it to respect my sub-sub paths? I already tried setting `web-root:` to `/` and curling /ntfy/, it looks exactly like http://127.0.0.1:2586/ but unlike connecting to it directly, it still throws me a white screen. I can also curl /ntfy/static/media/index-c5f33103.js, so I really don't see what the problem could be, unless there are some weird hard coded paths that should be easy to fix. Anyway, ntfy with attachments works so far, so I won't complain, but I'd still like to see less spaghetti code with hard coded paths :)
Author
Owner

@chudbigot commented on GitHub (Mar 5, 2025):

@binwiederhier Hi, I understand making subpath work for web app is probably a lot of hassle.

Is it possible to at least make it work for attachments and Email notifications? Right now if I specify subpath in base url the docker container simply refuses to start...It used to work in older versions. I can strip off subpath using my reverse proxy.

I would need to figure out how to set it up with email, but if this doesn't depend on J*vaScript, it should be fine. Actually, try copypasting my config blocks and adjust them for your sub paths as needed. Sadly I can't make it work as /ntfy/file/foo.bar, and have to rely on /file/foo.bar directly, so you'll have to sacrifice your /mail/ dir (or whatever email needs, I haven't read the whole docs yet) for it.

<!-- gh-comment-id:2699894657 --> @chudbigot commented on GitHub (Mar 5, 2025): > [@binwiederhier](https://github.com/binwiederhier) Hi, I understand making subpath work for web app is probably a lot of hassle. > > Is it possible to at least make it work for attachments and Email notifications? Right now if I specify subpath in base url the docker container simply refuses to start...It used to work in older versions. I can strip off subpath using my reverse proxy. I would need to figure out how to set it up with email, but if this doesn't depend on J*vaScript, it should be fine. Actually, try copypasting my config blocks and adjust them for your sub paths as needed. Sadly I can't make it work as /ntfy/file/foo.bar, and have to rely on /file/foo.bar directly, so you'll have to sacrifice your /mail/ dir (or whatever email needs, I haven't read the whole docs yet) for it.
Author
Owner

@NathanSweet commented on GitHub (Jan 4, 2026):

Hosting ntfy on a domain makes it discoverable with a port scan (subdomain is even worse). Running ntfy on a subpath prevents it from being discoverable, which is not crucial but nice.

<!-- gh-comment-id:3708365528 --> @NathanSweet commented on GitHub (Jan 4, 2026): Hosting ntfy on a domain makes it discoverable with a port scan (subdomain is even worse). Running ntfy on a subpath prevents it from being discoverable, which is not crucial but nice.
Author
Owner

@ksemele-public commented on GitHub (Feb 4, 2026):

+1 for proxy functionality

<!-- gh-comment-id:3848751211 --> @ksemele-public commented on GitHub (Feb 4, 2026): +1 for proxy functionality
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy#707
No description provided.