Skip to content

[BUG] production.ERROR: Error when attempting image upload:Unable to create a directory at /app/www/public/uploads/images /user/2023-10 #191

Closed
@HC-Pinky

Description

@HC-Pinky

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

No upload of images possible (avatar, attachments to books, inplace images in books etc.)

Expected Behavior

Uploading images should work as expected

Steps To Reproduce

Installed Bookstack via docker compose
opened Browser, logged in, went to Edit Profile and upload a new avatar image. --> Error message pops up that no sufficient write permissions exist (same for uploading images in books)

Here the Message from the logs:

[2023-10-02 21:54:43] production.ERROR: Error when attempting image upload:Unable to create a directory at /app/www/public/uploads/images
/user/2023-10.
[2023-10-02 21:54:43] production.ERROR: File path /uploads/images/user/2023-10/rick-256.png could not be uploaded to. Ensure it is writab
le to the server. {"userId":1,"exception":"[object] (BookStack\Exceptions\ImageUploadException(code: 0): File path /uploads/images/user
/2023-10/rick-256.png could not be uploaded to. Ensure it is writable to the server. at /app/www/app/Uploads/ImageService.php:174)
[stacktrace]
#0 /app/www/app/Uploads/ImageService.php(128): BookStack\Uploads\ImageService->saveNew()
#1 /app/www/app/Uploads/ImageRepo.php(119): BookStack\Uploads\ImageService->saveNewFromUpload()
#2 /app/www/app/Users/Controllers/UserController.php(159): BookStack\Uploads\ImageRepo->saveNew()
#3 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\Users\Controllers\UserController->update()
#4 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction()
#5 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(259): Illuminate\Routing\ControllerDispatcher->dispatch()
#6 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\Routing\Route->runController()
#7 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\Routing\Route->run()
#8 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closur
e}()
#9 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#10 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\Authenticate->handle()
#11 /app/www/app/Http/Middleware/Localization.php(45): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#12 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\Localization->handle()
#13 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#14 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\RunThemeActions->handle()
#15 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#16 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\CheckEmailConfirmed->handle
()
#17 /app/www/app/Http/Middleware/PreventAuthenticatedResponseCaching.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{clos
ure}()
#18 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\PreventAuthenticatedRespons
eCaching->handle()
#19 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->
Illuminate\Pipeline\{closure}()
#20 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\VerifyCsrfToke
n->handle()
#21 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illu
minate\Pipeline\{closure}()
#22 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->ha
ndle()
#23 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate
\Pipeline\{closure}()
#24 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSessi
on->handleStatefulRequest()
#25 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle()
#26 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline
->Illuminate\Pipeline\{closure}()
#27 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToRespon
se->handle()
#28 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate
\Pipeline\{closure}()
#29 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#30 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#31 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\ApplyCspRules->handle()
#32 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{c
losure}()
#33 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(797): Illuminate\Pipeline\Pipeline->then()
#34 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): Illuminate\Routing\Router->runRouteWithinStack()
#35 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(740): Illuminate\Routing\Router->runRoute()
#36 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(729): Illuminate\Routing\Router->dispatchToRoute()
#37 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\Routing\Router->dispatch()
#38 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Founda
tion\Http\{closure}()
#39 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pi
peline\{closure}()
#40 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\Http\Middleware\TrustProxies->handle()
#41 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\TrustProxies->handle()
#42 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline
->Illuminate\Pipeline\{closure}()
#43 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middle
ware\TransformsRequest->handle()

Environment

- OS: ubuntu 
uname -r -> Linux brix 6.2.0-33-generic #33-Ubuntu SMP PREEMPT_DYNAMIC Tue Sep  5 14:49:19 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

- How docker service was installed:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER

CPU architecture

x86-64

Docker creation

version: "2"
services:
  wiki:
    image: lscr.io/linuxserver/bookstack
    container_name: wiki
    networks:
      - wiki_net
    environment:
      - PUID=1000
      - PGID=1000
      - APP_URL=http://192.168.178.100:6875
      - DB_HOST=wiki_db
      - DB_PORT=3306
      - DB_USER=bookstack
      - DB_PASS=xxx
      - DB_DATABASE=bookstackapp
    volumes:
      - wiki_data:/config
    ports:
      - 6875:80
    restart: unless-stopped
    depends_on:
      - wiki_db
  wiki_db:
    image: lscr.io/linuxserver/mariadb
    container_name: wiki_db
    networks:
      - wiki_net
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=xxx
      - TZ=Europe/Berlin
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=xxx
    volumes:
      - wiki_db_data:/config
    restart: unless-stopped

volumes:
  wiki_data:
  wiki_db_data:

networks:
  wiki_net:

Container logs

nothing special in the logs (error shown before)

Maybe a hint how I got this working:
I did a 
chown abc:users .
in
/app/www/public/uploads
since this folder belongs to root


after this I could upload stuff. But there was a new file structure created (new folder 'images')

root@a36cf9efd6bf:/app/www/public/uploads# ll
total 12
drwxrwxr-x 1 abc  users  6 Oct  2 22:59 .
drwxrwxr-x 1 root root   3 Oct  2 18:23 ..
drwxr-xr-x 4 abc  users  4 Oct  2 23:01 images
lrwxrwxrwx 1 root root  19 Oct  2 22:22 uploads -> /config/www/uploads

For me it looks like that the symlink 'uploads -> /config/www/uploads' is one level to deep

If I follow the link I land at:
root@a36cf9efd6bf:/app/www/public/uploads/uploads# 

I'll try to remove the symlink and set it directly in /app/www/public/ (without the filter uploads present)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions