sabre-io/Baikal

Setting the base_uri does not work, results in 404 errors.

ioogithub opened this issue · 1 comments

Baikal version:
0.95

Expected behaviour:
I would like to run baikal behind an apache reverse proxy with a base url baikal. To get this working I need to use the base_uri feature.

I am running the ckulka docker image and was happy to see this parameter in the baikal.yaml file. All other apps I am running support a similar feature and typically it is as simple as setting the parameter. I expect that if I set the base_uri parameter than baikal will make the necessary changes to get it working with the new subdomain uri. Example setting base_uri '/baikal/' will result in a working http://localhost/baikal/. I will be able to see the admin page and login successfully.

Current behaviour:
When I set the parameter to 'baikal' or any derivation: /baikal, /baikal/, /baikal. baikal/ none of them work and they all result in 404 page errors.

With base_uri set when I load http://localhost I get a broken page with no images. The links on the page such as Login and Baikal server have been rewritten to http://localhost/baikal however. When clicking on these links such as: http://localhost/baikal/admin I get 404 errors in the logs:

49#49 *1 /var/www/baikal/html/index.php is not found (2: no such file or directory), client: ip, server: , request: "GET /baikal/ HTTP/1.1, host

and

51#51: *3 FastCGI send in stderr: "PHP message: LogicException: Request uri (/dav.php/calendars/users/default) is out of the base uri (baikal/dav.php/) in /var/www/baikal/vendor/sabre/http/lib/Request...

etc.

Steps to reproduce:

  1. start baikal
  2. load initial admin page in browser
  3. stop baikal
  4. edit ./config/baikal.yaml and set the base_uri
  5. start baikal and load the / page, see the images missing
  6. click on the upper left link to the admin page, see various 404 errors in the log.

I tried both the apache and nginx versions same 404 errors on both when using the base_uri.

Alternate solution (also did not work)
After many hours of battling with base_uri, I tried a second solution. I am migrating from radicale and the docker image is well documented with instructions for running it behind various reverse proxies and stripping out the trailing base url. I tried adapting it for baikal and unsetting the base_uri however this also resulted in various broken pages and the inability to login.:

RewriteEngine On
    RewriteRule ^/baikal$ /baikal/ [R,L]

    <Location "/baikal/">
        ProxyPass        http://localhost:1234/
        ProxyPassReverse http://localhost:1234/
        RequestHeader    set X-Script-Name /baikal
    </Location>

I also tried using ChatGPT and it just kept suggesting to set the base_uri and double check etc. which leads me to believe it should just work.

I learned about baikal from reddit discussions and several posters commented on spending many hours trying to get the url working so I knew I was going to have a hard time coming into this but I expected I would get it working like all the other selfhosted apps with this similar feature. Please advise on how I can get this working.

From what I can tell, there is two different ways of dealing with a base_uri and different parts of baikal are handling it differently.

The two methods are stripping the subfolder before the request goes to the HTTP server, or leaving the subfolder.

Well.. maybe three ways of dealing with the base_uri, but I don't think baikal supports X-Script-Name so I'm not going to cover it in my reply.

Here are some examples using the Caddy proxy syntax. Sorry for switching from the apache syntax in your message, but I don't remember offhand exactly how to do each thing in apache and I don't want to get the arguments wrong.

site.example.com {
        handle_path /baikal/* {
                reverse_proxy 10.7.7.7:80
        }
}

site.example.com {
        reverse_proxy /baikal/* 10.7.7.7:80
}

The first one, handle_path, is like the RewriteRule in your example. On incoming requests to site.example.com/baikal/ it removes "/baikal" and sends it on to the server. Replies from the server need to have their base_uri modified to add /baikal/ so that clients know to make requests to /baikal/file-they-were-redirected-to.php.

This one is working for me for the login.php page and the /baikal/admin/ page. The helper files are loading as well, so it appears the administrative side is setup to use this method for uri handling. "dav.php" does not work though. This is the error it shows:

Requested uri (/dav.php) is out of base uri (/baikal/dav.php/)

The second one, using reverse_proxy, does not modify the URL, it just sends it to the server as-is. The server is expected to know about the /baikal/ directory and strip it themselves. This is what the Sabre library is expecting. From what I can tell, dav.php sends PROJECT_BASEURI . 'dav.php/' into Sabre, but modifying the dav.php code to not include the PROJECT_BASEURI (just send "/dav.php/") is still broken. It tries to send URLs back to the user without the /baikal/ path, so css files and other things are missing.

I thought the best workaround would be to just use reverse proxy and ignore the broken admin portal, but this doesn't work either. nginx is expecting to serve files out of directories. It can't find /baikal/dav.php because it doesn't know about the /baikal/ directory.

So we would need to modify the nginx config to tell it about the location /baikal/, but this to me is too many steps away from the normal configuration. Maybe the developer will see a quick and easy fix for this. Or it may be that we're both doing it wrong and the actual solution is something we can do with a configuration tweak.

It's also possible this is specific to the docker configuration. I see that you made an issue there (ckulka/baikal-docker#217) so I will link it here for visibility.