Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APP_URL with subdirectories does not work. #261

Closed
1 task done
jhfry opened this issue Jan 24, 2025 · 7 comments
Closed
1 task done

APP_URL with subdirectories does not work. #261

jhfry opened this issue Jan 24, 2025 · 7 comments

Comments

@jhfry
Copy link

jhfry commented Jan 24, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When using an APP_URL that includes subdirectories, all requests get a 404 (not found). The "Page Not Found" page loads with no CSS (giant icons).

This is caused by a lack of a location block in the nginx configuration to handle the subdirectory redirection as described in https://www.bookstackapp.com/docs/admin/subdirectory-setup/#nginx-setup

Expected Behavior

At startup, subdirectory is extracted from the APP_URL provided and a location block is populated with it; allowing the application to work properly when using a reverse proxy with subdirectory.

Steps To Reproduce

  1. deploy the container with APP_URL=http://hostname:6875/bookstack
  2. connect to http://hostname:6875/bookstack
  3. observe that a page not found message is presented with no css applied.
  4. edit the container /config/nginx/site-confs/default.conf to include the following lines location block inside of the server block:
    location /bookstack/ {
        proxy_pass http://localhost:80/;
       proxy_redirect off;
    }
  1. restart the container
  2. connect to http://hostname:6875/bookstack
  3. observe that the login page is now displayed.

Environment

Debian Bookworm
Docker version 26.1.4, build 5650f9b
Docker Compose version v2.27.1

CPU architecture

x86-64

Docker creation

bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    depends_on:
      - mariadb
    environment:
      - PUID=1001 #dockeruser
      - PGID=1001 #dockeruser
      - TZ=America/New_York
      - APP_URL=http://myserver:6875/bookstack
      - APP_KEY=<32bitrandomstring>
      - DB_HOST=mariadb
      - DB_PORT=3306
      - DB_USERNAME=bookstack
      - DB_PASSWORD=bookstack
      - DB_DATABASE=bookstack
#      - QUEUE_CONNECTION= #optional
    volumes:
      - /opt/appdata/bookstack:/config
    ports:
      - 6875:80
    restart: unless-stopped

Container logs

✔ Container mariadb    Running                                                                                                                                                         0.0s
 ✔ Container bookstack  Created                                                                                                                                                         0.0s
Attaching to bookstack
bookstack  | [migrations] started
bookstack  | [migrations] 01-nginx-site-confs-default: skipped
bookstack  | [migrations] 02-default-location: skipped
bookstack  | [migrations] done
bookstack  | usermod: no changes
bookstack  | ───────────────────────────────────────
bookstack  |
bookstack  |       ██╗     ███████╗██╗ ██████╗
bookstack  |       ██║     ██╔════╝██║██╔═══██╗
bookstack  |       ██║     ███████╗██║██║   ██║
bookstack  |       ██║     ╚════██║██║██║   ██║
bookstack  |       ███████╗███████║██║╚██████╔╝
bookstack  |       ╚══════╝╚══════╝╚═╝ ╚═════╝
bookstack  |
bookstack  |    Brought to you by linuxserver.io
bookstack  | ───────────────────────────────────────
bookstack  |
bookstack  | To support LSIO projects visit:
bookstack  | https://www.linuxserver.io/donate/
bookstack  |
bookstack  | ───────────────────────────────────────
bookstack  | GID/UID
bookstack  | ───────────────────────────────────────
bookstack  |
bookstack  | User UID:    1001
bookstack  | User GID:    1001
bookstack  | ───────────────────────────────────────
bookstack  | Linuxserver.io version: v24.12.1-ls190
bookstack  | Build-date: 2025-01-22T00:21:32+00:00
bookstack  | ───────────────────────────────────────
bookstack  |
bookstack  | using keys found in /config/keys
bookstack  | Waiting for DB to be available
bookstack  |
bookstack  |    INFO  Nothing to migrate.
bookstack  |
bookstack  | [custom-init] No custom files found, skipping...
bookstack  | [ls.io-init] done.
Copy link

Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.

@jhfry jhfry changed the title APP_URL with subdirectories does not work. nginx config does not include a redirection. APP_URL with subdirectories does not work. Jan 24, 2025
@thespad
Copy link
Member

thespad commented Jan 24, 2025

Unproxied subfolder isn't really a use case we want to support because it's a very niche requirement and parsing strings and inserting them into configs on anything other than first run risks breaking otherwise functional setups.

Out of interest why do you need to run it under a subfolder when you're not proxying the connection?

@jhfry
Copy link
Author

jhfry commented Jan 24, 2025

I am reverse proxying the connection. I just didn't think it was necessary to add all that complexity when I can demonstrate the problem without having to describe the proxy configuration.

I identified this as a solution after hours of trying to get this container to run behind nginx or caddy. Perhaps I am just misunderstanding how I am supposed to reverse proxy this app. I have several others working fine with a simple:

    redir /bookstack /bookstack/
    reverse_proxy /bookstack/* {
            to bookstack:80
    }

but that didn't work for bookstack until I added the location to bookstack's nginx config.

After sleeping on it, I can see that the location block should NOT be unnecessary. But I am at a loss as to why it's not working without it. I am still seeing the /bookstack/ path in the request that hits nginx in the container.

here is a log snippet from the container's config/log/nginx/access.log when I hit http://myserver/bookstack/ with the above reverse proxy in place:

172.21.0.7 - - [24/Jan/2025:09:27:21 -0500] "GET /bookstack/ HTTP/1.1" 404 7753 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
192.168.15.187 - - [24/Jan/2025:09:27:21 -0500] "GET /bookstack/dist/app.js?version=v24.12.1 HTTP/1.1" 404 7772 "http://myserver/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
192.168.15.187 - - [24/Jan/2025:09:27:21 -0500] "GET /bookstack/logo.png HTTP/1.1" 404 7769 "http://myserver/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
192.168.15.187 - - [24/Jan/2025:09:27:21 -0500] "GET /bookstack/dist/styles.css?version=v24.12.1 HTTP/1.1" 404 7776 "http://myserver/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"

Somehow, the /bookstack/ is coming through from the reverse proxy. Surely I don't need to rewrite every request?

@thespad
Copy link
Member

thespad commented Jan 24, 2025

https://www.bookstackapp.com/docs/admin/subdirectory-setup/ suggests that is the case. It's weird, it's like the APP_URL doesn't actually do anything for the main content serving.

For comparison, I just setup a test using Traefik to reverse proxy it and I had to do traefik.http.middlewares.bookstack-stripprefix.stripprefix.prefixes=/bookstack to strip the /bookstack before sending it to the backend and then it started working, even with - APP_URL=https://books.example.com/bookstack set. Otherwise all the scripts, style sheets, etc. were 404ing.

@ssddanbrown can you provide any insight - are we missing something obvious?

@ssddanbrown
Copy link
Contributor

@thespad APP_URL will be used for all internal URL references generated by the application. It just needs to match the external URL (base URL used in browser). Don't think it does much for incoming requests.

To just confirm, I wouldn't expect anything to be done for this within the responsibility of this project.
Should just be able to proxy the path to the container, as long at the path is handled correctly.
Our subdirectory guidance is only really intended for when hosting as a sub-path of something else on the same machine.

I'm not super familiar with caddy, but going by my own video here, I'm guessing this could work for the proxy:

handle /bookstack/* {
  reverse_proxy bookstack:80
}

Not tested though. Might need to try without the latter slash and/or remove the redir statement.

@thespad
Copy link
Member

thespad commented Jan 24, 2025

Subfolder is wonky at the best of times and we try and steer people away from it, in part because different services handle it in different ways. Some will actually serve their content at whatever the base URL is, some will rewrite requests to keep everything internally consistent and some expect the user to do the heavy lifting if they're subfolder proxying.

And of course some things just won't work at all on a subfolder.

@jhfry
Copy link
Author

jhfry commented Jan 25, 2025

Thanks all I got it figured out.

I have run into a bit of wonkiness with subhfolders in the past, but 9-10 times it was resolved from within the app/container.

I tried "handling" the /bookstack/* path as you describe @ssddanbrown. The nginx logs show that it drops the /bookstack/ in the http referrer, and as a result my browser now reports that the content is "blocked by ORB", and other cross site warnings.

But I think you put me on the right path. Reading up on handle it made reference to handle_path which was the key. Here is the caddy configuration that appears to be working for bookstack:

        redir /bookstack /bookstack/
        handle_path /bookstack/* {
                reverse_proxy bookstack:80
        }

The handle_path directive actually strips the prefix off then hands it over to the reverse_proxy assertion. The funny thing is, the nginx logs inside the container still show that /bookstack/ is in the http referrer (which likely is what fixed the cross site stuff), but it appears that stripping the path was what was required.

And here is my docker config for anyone who comes along wondering what worked:

    bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    depends_on:
      - mariadb
    environment:
      - PUID=1001
      - PGID=1001
      - TZ=America/New_York
      - APP_URL=http://myserver/bookstack
      - APP_KEY=<secret 32 characters>
      - DB_HOST=mariadb
      - DB_PORT=3306
      - DB_USERNAME=bookstack
      - DB_PASSWORD=bookstack
      - DB_DATABASE=bookstack
#      - QUEUE_CONNECTION= #optional
    volumes:
      - /opt/appdata/bookstack:/config
#    ports:
#      - 6875:80
    restart: unless-stopped

@jhfry jhfry closed this as completed Jan 25, 2025
@LinuxServer-CI LinuxServer-CI moved this from Issues to Done in Issue & PR Tracker Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

3 participants