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
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.
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
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:
File icons by Icons8.
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.
Content type
Image
Digest
sha256:d02058a5a…
Size
902 MB
Last updated
about 12 hours ago
docker pull sciactive/thumbelina