Server
The Thumbrella executable is the server. It can be downloaded directly from releases or built from source. For most users, the easiest path is to run it through a prebuilt package. The server runs on Windows, macOS, and Linux, or anywhere Rust can produce a runnable binary.
# Run with npx (Node)npx @thumbrella/server serve
# Run with uvx (Python)uvx thumbrella-server serve
# Run with Dockerdocker run -p 3114:3114 -it --rm thumbrella/server
# Run from source (Rust)git clone https://github.com/thumbrella-dev/thumbrellacd thumbrellacargo run serveCommand Line
Section titled “Command Line”The Thumbrella executable provides several subcommands beyond the standard
web server. Any subcommand accepts --help for further details.
thumbrella serveruns the primary server. It includes built-in hints and diagnostics to help with onboarding.thumbrella thumb <input> <output>Generates a single thumbnail for an input file or URL and writes the JPEG to the given output path.thumbrella result <url>...Thumbnails one or more files or URLs and prints the result metadata as JSON. Add--rawto include the full base64 thumbnail.thumbrella formatsGenerates a larger report of all the formats Thumbrella supports. Not all will be available in all environments.thumbrella checkRuns a lightweight set of diagnostics and settings for the server. This will show the primary environment variable settings or their defaults. It will also run several checks to determine if the server is ready to run with the given environment.thumbrella licenseReport license and information about dependencies.thumbrella versionShows a quick message describing the version information for the build.thumbrella helpShows a quick summary of the various subcommands available.
Configuration
Section titled “Configuration”The server is configured through several environment variables. The default values should be valid for a variety of use cases and getting started. The server can be further tuned with these.
| Environment Variable | Default Value | Description |
|---|---|---|
TBR_PORT |
3114 |
The port the server will listen on. |
TBR_LOG |
standard |
A level of stdout reporting the server makes. (standard minimal full) |
TBR_ALLOW_LOCAL |
0 |
Boolean that allows file paths or localhost URLs. (0 1 false true) |
TBR_HANDSHAKE |
Private token required as a custom HTTP header on every request. | |
TBR_TRACE |
File path to append more detailed logging output. | |
TBR_CACHE |
mem: (100 MB) |
Cache backend definition (mem:, sqlite:, none:). |
TBR_SCRATCH |
$TMP/thumbrella |
A location on disk to download temporary files into. |
TBR_TIER2 |
Connection string to a separate Thumbrella server for tier2. | |
TBR_TIER3 |
Connection string to a separate Thumbrella server for tier3. |
Be aware that some of these settings may not make sense or even break things inside the docker environment.
Handshake
Section titled “Handshake”Each server can define a secret handshake via the $TBR_HANDSHAKE environment
variable. Clients must provide this value with every request. It helps mitigate
unwanted traffic on directly exposed Thumbrella servers.
Consider a command like openssl rand -base64 24 to generate a secure
random token. Or just pick your favorite word, it’s your handshake. The server will
reject any request that does not include this value as a custom HTTP header.
Clients will need to include this handshake in their connect string to access the server. When the server starts up it will show an example value of the connect string clients should use (although most of the handshake value will be masked out).
# Start a server with a secret handshakeTBR_HANDSHAKE=wafflecones thumbrella serve
# Clients should set a connect string that includes the server url and a comma# separated handshakeTBR_CONNECT=http://localhost:3114,wafflecones npm run thumbclientThe handshake value must not look like a Thumbrella Cloud API token (i.e.
starting with tbr_). The server will reject such values at startup to avoid
confusion about where each kind of credential belongs.
Caching
Section titled “Caching”The server includes a short-term sticky cache (5 seconds) with request coalescing built in. When two identical requests arrive within 5 seconds, only one fetches the remote source, the second is served from the sticky cache. This is always active.
With default settings the server also enables a 100 MB in-memory LRU
cache. Set TBR_CACHE to customise or disable it.
Thumbrella respects upstream HTTP caching:
Cache-Control: no-storeandprivateresponses are not stored in durable backends (they still pass through the 5 s sticky cache for request deduplication).Cache-Control: max-ageands-maxageare captured and returned to clients as freshness hints.ETagandLast-Modifiedare used for conditional revalidation.
$TBR_CACHE selects a single cache backend:
| Backend | Format | Persistence | Examples |
|---|---|---|---|
| Memory | mem: |
No | mem:, mem:200mb, mem:2gb, mem:500 (entries) |
| SQLite | sqlite: |
Yes | sqlite:cache.db, sqlite:/var/cache.db#1gb |
| Cloud | cloud: |
Yes (shared) | cloud:tbr_e_3QnzBcWx7KpRmYT2000example (your cloud API token) |
| None | none: |
— | Disables all caching |
Any cache backend can be sized by appending a limit: mem:500mb, sqlite:db#2gb.
Memory cache defaults to 100 MB. SQLite evicts oldest entries when over the byte
limit and purges expired entries on write, no manual maintenance needed. See
the Cloud docs for details on the cloud cache
backend.
Every cache entry has an expiration timestamp. By default upstream
Cache-Control: max-age / s-maxage sets the TTL, capped at 7 days
(TBR_CACHE_MAX_TTL). When the upstream provides no hints, entries
default to 1 hour (TBR_CACHE_DEFAULT_TTL).
Cache String
Section titled “Cache String”A cache string is a compact encoding of cache information. An example looks like this.
6a46337d:AAAkIjE2ODcxOTc4MTcuMzY0NjkzLTEzMjA2OC01MTI5NTY2MDkiAAThe data is broken into two parts, separated by the first colon. The cache string will always have at least one colon with some characters before and after.
- The first part represents a hexadecimal timestamp (utc time) that represents when the cache freshness will expire. Any time before the expiration is considered fresh. Clients should not need to query thumbrella for a new thumbnail any time before this value.
- The second part is a simple encoding of the remaining http headers needed for the server to request a new thumbnail. This second part is not intended to be interpreted or parsed in any way. It is internal data to the server.
A few additional notes about this cache string:
- Cache string will be url safe and not require escaping in urls or command line arguments.
- There could potentially be additional colons after the first.
- Only the first one should be used to isolate the freshness expiration.
The existing client libraries will handle all this automatically. If accessing the thumbrella server directly, simply pass this opaque string back to the server on a request where your client is keeping its own results cache.
Server results store this cache value in the nested “media”, “cache” field.
It is possible for this cache value to be null when the remote server provides
no caching information.
Troubleshooting
Section titled “Troubleshooting”If the server fails to start or behaves unexpectedly, run the check
subcommand first. It evaluates the environment variables that configure the
server and reports whether each value is valid.
thumbrella checkCommon issues and solutions:
| Symptom | Likely cause | Fix |
|---|---|---|
| “address in use” | Port 3114 already bound |
Set TBR_PORT to a different port |
| Rejected requests | Missing handshake | Include handshake in client connect string |
| Missing formats | External tools not installed | Install ffmpeg, f3d, etc.; run thumbrella formats |
| Repeated rerendering | Default cache is small | Set TBR_CACHE=mem:200mb for a larger memory cache. Also consider sqlite: to make the cache persistent. |
| File paths blocked | Configuration not allowed by default | Set TBR_ALLOW_LOCAL=1 to allow file:// URLs |
A running server can be checked by testing the /health endpoint:
curl http://localhost:3114/health# {"status": "ok", "thumbrella": 1}Hybrid Cloud
Section titled “Hybrid Cloud”A standalone server can be connected to a free account on Thumbrella Cloud to expand it’s functionality.
A standalone server can use Thumbrella Cloud as its persistent caching backend.
The cached requests will be managed with quota and lifetimes the same as
the requests are handled by Thumbrella Cloud. This cache is also shared with
regular Cloud requests for the same account. Set the TBR_CACHE environment
variable to cloud: followed by a private token for your account.
A standalone server can present difficulty to get all the formats supported
when they are handled by external tools. The thumbrella server must have access
to tools like oiiotool, f3d (with a framebuffer), and more. Instead of
setting these up a standalone Thumbrella server can be configured to fallback
on Thumbrella Cloud to handle only these more complicated and optional
formats. This is done by setting the TBR_TIER3 environment variable to a
private token for your account.
export TBR_CACHE=cloud:tbr_e_3QnzBcWx7KpRmYT2000exampleexport TBR_TIER3=tbr_e_3QnzBcWx7KpRmYT2000exampleDocker troubleshooting
Section titled “Docker troubleshooting”Thumbrella’s scratch directory (TBR_SCRATCH) should be a mounted volume for
temporary file storage. If using persistent caching with the TBR_CACHE
variable, also consider keeping this stored on a local volume.
External tools like oiiotool and f3d are not included in the base Docker
image. Use the sponsor edition Docker image for a
pre-configured environment with all optional renderers.
External Formats
Section titled “External Formats”The Thumbrella executable comes with support for a wide range of image, video, and other formats. These are built in statically and will work on any system in any kind of environment.
Thumbrella also supports using sandboxed external programs to do processing. These are used for 3D renders, and even FFmpeg for some of the more advanced video formats.
To enable these formats and features the following commands must be available in the environment that runs the server. Some of these tools will require access to hardware (or software) frame buffers and graphics libraries. The server will check for the commands at startup and report which are available.
These external tools and libraries are entirely optional. The server will start
and run without them. Use the formats and check subcommands to get further
details.
| Dependency | Type | Tool | Formats |
|---|---|---|---|
| FFmpeg | CLI | ffmpeg |
Additional images and videos |
| OpenImageIO | CLI | oiiotool |
Extended image formats |
| F3D | CLI | f3d |
3D geometry formats |
| OpenUSD | Python | usd_core |
3D USD models |
Build yourself
Section titled “Build yourself”The Rust server is designed to be simple to build from source. The user will
need to either set $FFMPEG_DIR to an ffmpeg build path, or use one of the
provided ffmpeg build scripts for your platform.
git clone https://github.com/thumbrella-dev/thumbrella && cd thumbrellabash ffs/build-linux.sh (or `powershell -File ffs/build-windows.ps1` on Win)cargo run --release
thumbrella.dev