Nextcloud 24 introduced support for handing off the generation of image preview thumbnails to an external service, Imaginary.

Imaginary is a small HTTP server written in Go which receives images over a REST API. Imaginary can then perform a number of operations on these images (upscaling, downscaling, cropping, resizing) and returns the manipulated image to the client.

The idea behind this new integration in Nextcloud 24 is that, for image-heavy sites, processing of image previews can be handed off to a separate microservice, allowing for better scalability.

I chose to go down the Docker route to deploy Imaginary. It turned out to be fairly straightforward to set up - my docker-compose.yml is below:

version: '3'
services:
  imaginary:
    image: ghcr.io/italypaleale/imaginary:master
    container_name: imaginary
    restart: always
    ports:
      - '<internal-ip>:9000:9000'
    command: -enable-url-source

Note that I'm pulling a third party Docker image - the official images are more than a year out of date. The -enable-url-source argument is needed to allow Nextcloud to POST images over Imaginary's REST API.

And finally, the config.php entry in Nextcloud:

  'enabledPreviewProviders' => 
  array (
   ...
    17 => 'OC\\Preview\\Imaginary',
  ),
  'preview_imaginary_url' => 'http://<internal-ip>:9000',

I have not set up authentication on my Imaginary instance since it is bound to a local IP only accessible from within my Virtual Private Cloud. Your Imaginary endpoint should not be publicly accessible - Nextcloud will proxy all client traffic to it.

 

Notes

  • Imaginary isn't a silver bullet to solving Nextcloud's preview generation woes. If your server is already struggling to generate previews with PHP-FPM, adding yet another service on top isn't going to help. Ideally, Imaginary should be deployed onto a dedicated server.
  • Imaginary uses a lot of CPU and memory when processing large images. When opening a folder containing full quality iPhone images, I saw Imaginary spike up to 2+GB of RAM usage. Even PHP seemed to use more memory - I assume this is down to Nextcloud needing to load the full image into memory to POST them to Imaginary.
  • This can be used in conjunction with the Preview Generator app. When Nextcloud has been configured to use Imaginary, all previews created with the preview:generate-all command will be done using Imaginary. This helps reduce the load on your webserver if preview generation is being handled via a cronjob.

 

Submitted by admin on