STORAGE_TYPE=local_secure URLs still reference .../public rather than .../storage/uploads... #5472

Closed
opened 2026-02-05 10:05:35 +03:00 by OVERLORD · 5 comments
Owner

Originally created by @shadowimmage on GitHub (Oct 30, 2025).

Describe the Bug

Trying to upload any images for things like in-book images or covers for shelves, etc. successfully places the files on the server filesystem, so the server can write and save the uploaded files, but then the application fails to serve them back.

Steps to Reproduce

  1. Edit shelf
  2. Change cover photo
  3. Upload jpg
  4. Server has files on disk under /var/www/bookstack/storage/uploads/images/cover_bookshelf/2025-10/filename.jpg as well as in ../scaled-1680-/ ../thumbs-150-150/ and ../thumbs-440-250/
  5. Reload Shelves (https://wiki.server.tld/shelves)
  6. no image - Browser console shows HTTP 404 for filename.jpg loaded from https://wiki.server.tld/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG

Expected Behaviour

Images appear in shelves, books, etc. The application should be serving the files from the storage location, but it's like it expects there to be files at /uploads, even though there aren't.

Screenshots or Additional Context

Using .env setting STORAGE_TYPE=local_secure.

Also added STORAGE_IMAGE_TYPE=local_secure -- no change.

Toggled public access on/off -- no change

Checked and re-checked filesystem permissions, nginx user/group owns all files and directories necessary - the web server has no trouble saving the uploaded images

When loading the bookstack shelves page:
Nginx error shows
2025/10/29 17:30:25 [error] 120076#120076: *362 open() "/var/www/bookstack/public/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG" failed (2: No such file or directory), client: 10.158.231.57, server: wiki.server.tld, request: "GET /uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG HTTP/1.1", host: "wiki.server.tld", referrer: "https://wiki.server.tld/shelves"

Trying to load the image URL directly, or where it looks like the image should be:
Trying to load https://wiki.server.tld/storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG directly also doesn't work, and yields a 404 Not Found Nginx error:
2025/10/29 17:40:11 [error] 120076#120076: *3367 open() "/var/www/bookstack/public/storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG" failed (2: No such file or directory), client: 10.158.231.57, server: wiki.server.tld, request: "GET /storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG HTTP/1.1", host: "wiki.server.tld"

Why does it keep trying to load from /public when I have the .env STORAGE_TYPE set to local_secure?

Browser Details

Firefox 144.0; MS Edge Version 141.0.3537.99 (Official build) (64-bit); nginx 1.20.1; Rocky Linux 9

Exact BookStack Version

BookStack v25.07.3

Originally created by @shadowimmage on GitHub (Oct 30, 2025). ### Describe the Bug Trying to upload any images for things like in-book images or covers for shelves, etc. successfully places the files on the server filesystem, so the server can write and save the uploaded files, but then the application fails to serve them back. ### Steps to Reproduce 1. Edit shelf 2. Change cover photo 3. Upload jpg 4. Server has files on disk under /var/www/bookstack/storage/uploads/images/cover_bookshelf/2025-10/filename.jpg as well as in ../scaled-1680-/ ../thumbs-150-150/ and ../thumbs-440-250/ 5. Reload Shelves (https://wiki.server.tld/shelves) 6. no image - Browser console shows HTTP 404 for filename.jpg loaded from https://wiki.server.tld/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG ### Expected Behaviour Images appear in shelves, books, etc. The application should be serving the files from the storage location, but it's like it expects there to be files at /uploads, even though there aren't. ### Screenshots or Additional Context Using .env setting STORAGE_TYPE=local_secure. Also added STORAGE_IMAGE_TYPE=local_secure -- no change. Toggled public access on/off -- no change Checked and re-checked filesystem permissions, nginx user/group owns all files and directories necessary - the web server has no trouble saving the uploaded images **When loading the bookstack shelves page:** Nginx error shows `2025/10/29 17:30:25 [error] 120076#120076: *362 open() "/var/www/bookstack/public/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG" failed (2: No such file or directory), client: 10.158.231.57, server: wiki.server.tld, request: "GET /uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG HTTP/1.1", host: "wiki.server.tld", referrer: "https://wiki.server.tld/shelves"` **Trying to load the image URL directly, or where it looks like the image should be:** Trying to load https://wiki.server.tld/storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG directly also doesn't work, and yields a 404 Not Found Nginx error: `2025/10/29 17:40:11 [error] 120076#120076: *3367 open() "/var/www/bookstack/public/storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG" failed (2: No such file or directory), client: 10.158.231.57, server: wiki.server.tld, request: "GET /storage/uploads/images/cover_bookshelf/2025-10/thumbs-440-250/mg-1310.JPG HTTP/1.1", host: "wiki.server.tld"` Why does it keep trying to load from /public when I have the .env STORAGE_TYPE set to local_secure? ### Browser Details Firefox 144.0; MS Edge Version 141.0.3537.99 (Official build) (64-bit); nginx 1.20.1; Rocky Linux 9 ### Exact BookStack Version BookStack v25.07.3
OVERLORD added the 🐕 Support Question labels 2026-02-05 10:05:35 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Oct 31, 2025):

Hi @shadowimmage,

The image URLs do not change when using the local_secure option.
When an image path is requested, generally the web-server will provide the image directly if in public space, but if there's no file there it'll defer back to the application to serve the image, where is where we're set to handle standard uploads/images/* paths via the local secure system, using the storage path.

To me this sounds like the nginx configuration is not allowing images (or specific paths where images are located) to be served via PHP. Feel free to share your nginx configuration for BookStack and I can look deeper into what might be happening in your environment.

@ssddanbrown commented on GitHub (Oct 31, 2025): Hi @shadowimmage, The image URLs do not change when using the `local_secure` option. When an image path is requested, generally the web-server will provide the image directly if in public space, but if there's no file there it'll defer back to the application to serve the image, where is where we're set to handle standard `uploads/images/*` paths via the local secure system, using the storage path. To me this sounds like the nginx configuration is not allowing images (or specific paths where images are located) to be served via PHP. Feel free to share your nginx configuration for BookStack and I can look deeper into what might be happening in your environment.
Author
Owner

@shadowimmage commented on GitHub (Nov 1, 2025):

Hi, Thanks, I think I see how that's working. I didn't understand that it was falling back to the application to server the images and so I was confused thinking that the URL should have been different because of the different storage location. I'm not really that familiar with the inner workings of PHP.

I'll also admit, I'm not the best with nginx, but find it more approachable than whatever arcane madness is going on in apache.

For reference, I pulled most of this config out of the script here : https://github.com/blogmotion/bm-bookstack-install/blob/master/bookstack-install-RHEL9.sh Which I followed from https://www.bookstackapp.com/docs/admin/installation/#community Which does successfully get the pages loading and content stored, but isn't working with images from the server to the client(s) - so I'm sure there's something wrong with my location{} blocks, but I'm not sure what.

Thanks for all the help.

# /etc/nginx/conf.d/bookstack.conf
server {
  # HTTP -> HTTPS REDIRECT
  listen 80;
  listen [::]:80;
  server_name wiki.domain.tld;
  return 301 https://$server_name$request_uri;
}

server {
  # HTTPS
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name wiki.domain.tld;

  ssl_certificate /etc/letsencrypt/live/wiki/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/wiki/privkey.pem;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers HIGH:!aNULL:!MD5;

  root /var/www/bookstack/public;

  access_log /var/log/nginx/bookstack_access.log;
  error_log /var/log/nginx/bookstack_error.log;

  client_max_body_size 1G;
  client_body_timeout 120s;
  fastcgi_buffers 64 4K;

  index index.php index.html;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README) {
    deny all;
  }

  location ~ \.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass unix:/run//php-fpm/www.sock;
  }

  location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
    expires 30d;
    access_log off;
  }
}
@shadowimmage commented on GitHub (Nov 1, 2025): Hi, Thanks, I think I see how that's working. I didn't understand that it was falling back to the application to server the images and so I was confused thinking that the URL should have been different because of the different storage location. I'm not really that familiar with the inner workings of PHP. I'll also admit, I'm not the best with nginx, but find it more approachable than whatever arcane madness is going on in apache. For reference, I pulled most of this config out of the script here : https://github.com/blogmotion/bm-bookstack-install/blob/master/bookstack-install-RHEL9.sh Which I followed from https://www.bookstackapp.com/docs/admin/installation/#community Which does successfully get the pages loading and content stored, but isn't working with images from the server to the client(s) - so I'm sure there's something wrong with my location{} blocks, but I'm not sure what. Thanks for all the help. ```nginx # /etc/nginx/conf.d/bookstack.conf server { # HTTP -> HTTPS REDIRECT listen 80; listen [::]:80; server_name wiki.domain.tld; return 301 https://$server_name$request_uri; } server { # HTTPS listen 443 ssl; listen [::]:443 ssl; server_name wiki.domain.tld; ssl_certificate /etc/letsencrypt/live/wiki/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/wiki/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/bookstack/public; access_log /var/log/nginx/bookstack_access.log; error_log /var/log/nginx/bookstack_error.log; client_max_body_size 1G; client_body_timeout 120s; fastcgi_buffers 64 4K; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README) { deny all; } location ~ \.php(?:$|/) { fastcgi_split_path_info ^(.+\.php)(/.+)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_pass unix:/run//php-fpm/www.sock; } location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ { expires 30d; access_log off; } } ```
Author
Owner

@ssddanbrown commented on GitHub (Nov 2, 2025):

Thanks for providing the details @shadowimmage.

Can you try adding try_files $uri $uri/ /index.php?$query_string; as a line within the last location block, so it looks like this?:

  location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
    try_files $uri $uri/ /index.php?$query_string;
    expires 30d;
    access_log off;
  }

Edit: Remember to reload/restart nginx after making config changes!

@ssddanbrown commented on GitHub (Nov 2, 2025): Thanks for providing the details @shadowimmage. Can you try adding `try_files $uri $uri/ /index.php?$query_string;` as a line within the last location block, so it looks like this?: ```nginx location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ { try_files $uri $uri/ /index.php?$query_string; expires 30d; access_log off; } ``` Edit: Remember to reload/restart nginx after making config changes!
Author
Owner

@shadowimmage commented on GitHub (Nov 4, 2025):

Hello,
Sorry for the delay in getting back to you. This addition worked!
At first I thought that that wasn't the case, as I was still getting HTTP 404 errors when the images should have loaded, but after I re-uploaded the images to their respective pages/book cover images, they are successfully being loaded!

@shadowimmage commented on GitHub (Nov 4, 2025): Hello, Sorry for the delay in getting back to you. **This addition worked!** At first I thought that that wasn't the case, as I was still getting HTTP 404 errors when the images should have loaded, but _after_ I re-uploaded the images to their respective pages/book cover images, they are successfully being loaded!
Author
Owner

@ssddanbrown commented on GitHub (Nov 13, 2025):

Awesome! There generally shouldn't be any need to re-upload images on storage type change, apart from maybe the icons in the settings, but since this sounds like it's sorted for you I'll go ahead and close this off.

@ssddanbrown commented on GitHub (Nov 13, 2025): Awesome! There generally shouldn't be any need to re-upload images on storage type change, apart from maybe the icons in the settings, but since this sounds like it's sorted for you I'll go ahead and close this off.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5472