A tiny-ish thumbnailer service, designed to be used by your app backend. Give it a file and it gives you a thumbnail. Supports images, videos, music, 3D models, PDFs, ebooks, documents, spreadsheets, presentations, text, fonts, HTML, and more.
  • JavaScript 69.3%
  • Python 25.7%
  • Dockerfile 4.1%
  • Shell 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-11 15:15:21 -07:00
fallback Add more fallback icons. 2026-10-11 12:32:41 -07:00
.gitignore Initial commit. 2026-10-07 13:55:43 -07:00
docker-compose.yml Update docs for Docker Hub. 2026-10-11 15:15:21 -07:00
Dockerfile Set debconf to noninteractive and clean more things after package install. 2026-10-11 14:59:49 -07:00
entrypoint.sh Initial commit. 2026-10-07 13:55:43 -07:00
index.js Add watermark feature. 2026-10-11 13:05:50 -07:00
LICENSE Initial commit. 2026-10-07 13:55:43 -07:00
package-lock.json Add audio metadata thumbnail. Album art or render of track title, artist, and album. 2026-10-10 09:42:26 -07:00
package.json Add audio metadata thumbnail. Album art or render of track title, artist, and album. 2026-10-10 09:42:26 -07:00
README.md Update docs for Docker Hub. 2026-10-11 15:15:21 -07:00
render_thumb.py Add some more options and better set framing in 3d renders. 2026-10-10 10:38:39 -07:00
watermark.png Add watermark feature. 2026-10-11 13:05:50 -07:00
watermark.svg Add watermark feature. 2026-10-11 13:05:50 -07:00

Thumbelina

A tiny-ish thumbnailer service, designed to be used by your app backend. Give it a file and it gives you a thumbnail. Supports images, videos, music, 3D models, PDFs, ebooks, documents, spreadsheets, presentations, text, fonts, HTML, and more.

It prioritizes security, and thus any remote resources required to properly render the thumbnail will not work. In other words, if you give it a PDF that has a remote image, that image won't be in the thumbnail.

It does not prioritize speed, so you should probably cache the results. It will be fast for certain requests, but for things like Word docs, it will be slow.

Repo: https://forge.sciactive.com/sciactive/thumbelina

Docker Hub: https://hub.docker.com/r/sciactive/thumbelina

Usage

Here is an example docker-compose.yml file to bring up Thumbelina:

services:
  thumbelina:
    image: sciactive/thumbelina:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    # Needed for iptables setup to prevent data exfiltration (blocks outgoing requests).
    cap_add:
      - NET_ADMIN
    # Adding this will speed up the thumbnail generation at the expense of using more RAM.
    tmpfs:
      - /tmp
    # If you want to add a watermark, this is how you do it. The watermark will be stretched across
    # the image, no matter what resolution it is.
    # volumes:
    #   - ./watermark.png:/app/watermark.png
    # You can limit resources to protect against malformed file denial-of-service attacks.
    deploy:
      resources:
        limits:
          cpus: "4"
          memory: 8G

Now bring up the service:

docker compose up -d

Now you can make a POST request to:

http://127.0.0.1:3000/thumbnail

with a file in the body (max 200MB) and it will return a thumbnail.

You can also add .jpg, .jpeg, .png, or .webp onto the end of the URL (e.g. http://127.0.0.1:3000/thumbnail.jpg) for a specific format. It defaults to PNG.

Query Parameters

  • width - The width in pixels of the thumbnail.
  • height - The height in pixels of the thumbnail.
  • size - Sets both width and height at the same time. Default is 300.
  • fit - Can be "fill", "contain", or "cover". Default is "contain".
  • crop - For "contain" fit, this determines if the image given will be cropped to maintain its original aspect ratio (default), or will be letterboxed with "bg" to the requested size (if set to "no").
  • backdrop - For "contain" fit, when set to "yes" and "crop" set to "no", will use a blurred backdrop of the thumbnail, except for 3D models, fonts, and fallback images, where that would be weird looking.
  • backdrop-transparent - When set to "yes", backdrop will even be applied for images that might have transparency (png, webp, gif).
  • bg - Either "transparent" or an RGB color hex code. If you set "transparent" for a JPG, it'll be black. Default is "5d5e60".
  • fg - An RGB color hex code. This is used for the color of font and a music metadata renders. Default is "e4e4e4".
  • model-color - An RGB color hex code. This is used for the color of a 3d model render. Default is "61a1ff".
  • video-prefer-metadata - When set to "no", the video contents will be used instead of any thumbnail metadata.
  • video-film-strip - When set to "no", video thumbnails will not include a film strip overlay.
  • font-text - The text to use for rendered font thumbnails. Default is "AaBb%0A1234".

Thumbelina will make every attempt to give you some thumbnail. If generating one from the actual file fails, a generic fallback icon will be sized for you and returned. If that's not what you want, and you'd rather receive an error message on failure, you can mount an empty directory into the "/app/fallback" path, and Thumbelina will respond with an error message instead.

The absolute perfect settings for a 16x9 thumbnail for a website might look something like this:

http://localhost:3000/thumbnail.webp?width=256&height=144&backdrop=yes&crop=no&font-text=The%20quick%20brown%20fox%0Ajumps%20over%20the%20lazy%20dog.%0A0123456789

Return Values

If you get a 200 response back, the body is an image, otherwise it is a JSON error message.

On success, you'll also get the following return headers:

  • Content-Type - Just a normal Content Type header for the returned thumbnail. It is determined by the format you requested.
  • Content-Length - The size, in bytes, of the returned thumbnail. Thumbnails are not streamed, so this will always be set.
  • X-Original-Type - This is the Content Type the file you gave was determined to be. If you gave your own type other than "application/octet-stream", that's what you'll get here, because Thumbelina trusted you. Otherwise, Thumbelina tried to detect the type, and this is what she found.
  • X-Thumbnail-Of - This is the kind of thumbnail you're getting back. You can check if this equals "fallback" or "broken", which means there was no thumbnail generated from the file, just a fallback icon. One of:
    • "image" - A sized version of the image you gave.
    • "video" - A frame or metadata image of the video you gave.
    • "audio" - An extraction of the album artwork, or a render of the track title, artist, and album of the music/audio you gave.
    • "3d-model" - A rendering of the 3D model you gave.
    • "pdf" - A rendering of the first page of the PDF you gave.
    • "ebook" - A rendering of the first page of the ebook you gave.
    • "document" - A rendering of the first page of the document/spreadsheet/presentation/text you gave.
    • "font" - A rendering of some sample text in the font you gave.
    • "fallback" - Just a default icon depending on the content type, because that type isn't something Thumbelina can read.
    • "broken" - Same as fallback, except in this case Thumbelina did try to read it, and an error occurred.

Attribution

File icons by Icons8.

License

Copyright 2026 SciActive Inc

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.