Thumbor image loader reading blobs from zodb-pgjsonb blob_state table
Project description
zodb-pgjsonb-thumborblobloader
Thumbor 7.x image loader that reads blob data directly from the zodb-pgjsonb blob_state PostgreSQL table.
Overview
This loader enables Thumbor to serve images stored as ZODB blobs in a zodb-pgjsonb PostgreSQL database -- without requiring a running ZODB/Zope instance. It supports:
- Two-tier storage: PostgreSQL bytea (preferred) with optional S3 fallback
- Async connection pool: psycopg3
AsyncConnectionPoolfor high concurrency - Disk cache: LRU-evicted local cache with deterministic filenames
- URL-based lookup:
<zoid_hex>/<tid_hex>addressing for exact blob versions
Installation
pip install zodb-pgjsonb-thumborblobloader
# With S3 fallback support
pip install zodb-pgjsonb-thumborblobloader[s3]
Configuration
In your thumbor.conf:
LOADER = 'zodb_pgjsonb_thumborblobloader.loader'
# Required
PGTHUMBOR_DSN = 'dbname=zodb user=zodb password=zodb host=localhost port=5432'
# Connection pool (optional)
PGTHUMBOR_POOL_MIN_SIZE = 1
PGTHUMBOR_POOL_MAX_SIZE = 10
# Disk cache (optional)
PGTHUMBOR_CACHE_DIR = '/var/cache/thumbor/blobs'
PGTHUMBOR_CACHE_MAX_SIZE = 1073741824 # 1 GB
# S3 fallback (optional, requires [s3] extra)
PGTHUMBOR_S3_BUCKET = 'my-blob-bucket'
PGTHUMBOR_S3_REGION = 'eu-central-1'
PGTHUMBOR_S3_ENDPOINT = 'https://s3.example.com' # for MinIO/Ceph
URL Scheme
http://thumbor:8888/<signing>/<transforms>/<zoid_hex>/<tid_hex>
Both zoid_hex and tid_hex are required. The loader fetches the exact blob version identified by the OID/TID pair.
How It Works
Thumbor request
└-> loader.load(context, path)
├-> disk cache hit? → return cached bytes
├-> PostgreSQL query → blob_state.data (bytea)
├-> S3 fallback → blob_state.s3_key → boto3 download
└-> cache on disk → LRU eviction by atime
The blob_state table is owned and managed by zodb-pgjsonb -- this loader only reads from it.
Docker Image
A pre-built OCI image is available on GHCR:
docker pull ghcr.io/bluedynamics/zodb-pgjsonb-thumborblobloader:latest
Platforms: linux/amd64, linux/arm64
Image tags
thumbor-<THUMBOR_VERSION>_loader-<LOADER_VERSION>-- versioned (e.g.thumbor-7.7.7_loader-0.3.0)latest-- always the newest build
The image is automatically rebuilt weekly when a new Thumbor version appears on PyPI.
Environment Variables
| Variable | Default | Description |
|---|---|---|
PGTHUMBOR_DSN |
"" |
PostgreSQL connection string (required) |
THUMBOR_SECURITY_KEY |
"CHANGE-ME" |
Thumbor HMAC security key |
ALLOW_UNSAFE_URL |
"False" |
Allow unsigned URLs |
RESULT_STORAGE_PATH |
/tmp/thumbor/result_storage |
Result cache directory |
PGTHUMBOR_POOL_MIN_SIZE |
1 |
Min DB pool connections |
PGTHUMBOR_POOL_MAX_SIZE |
4 |
Max DB pool connections |
PGTHUMBOR_CACHE_DIR |
"" |
Local blob cache directory (empty = disabled) |
PGTHUMBOR_CACHE_MAX_SIZE |
0 |
Max cache size in bytes (0 = disabled) |
PGTHUMBOR_S3_BUCKET |
"" |
S3 bucket for blob fallback (empty = disabled) |
PGTHUMBOR_S3_REGION |
us-east-1 |
S3 region |
PGTHUMBOR_S3_ENDPOINT |
"" |
S3 endpoint for MinIO/Ceph (empty = AWS) |
PGTHUMBOR_PLONE_AUTH_URL |
"" |
Plone internal URL for auth (empty = disabled) |
PGTHUMBOR_AUTH_CACHE_TTL |
60 |
Auth cache TTL in seconds |
PGTHUMBOR_CACHE_CONTROL_AUTHENTICATED |
private, max-age=86400 |
Cache-Control for authenticated images (browser-only, no proxy caching) |
PGTHUMBOR_CACHE_CONTROL_PUBLIC |
"" |
Cache-Control for public images (empty = Thumbor default) |
The Plone auth handler (and Cache-Control overrides) is only loaded when PGTHUMBOR_PLONE_AUTH_URL is set.
Quick start
docker run --rm -p 8888:8888 \
-e PGTHUMBOR_DSN="dbname=zodb user=zodb password=zodb host=localhost" \
-e THUMBOR_SECURITY_KEY="my-secret" \
ghcr.io/bluedynamics/zodb-pgjsonb-thumborblobloader:latest
# Healthcheck
curl http://localhost:8888/healthcheck
Development
cd sources/zodb-pgjsonb-thumborblobloader
uv pip install -e ".[test,s3]"
# Run tests (requires PostgreSQL on localhost:5433)
pytest
Documentation
This package is documented together with plone-pgthumbor: https://bluedynamics.github.io/plone-pgthumbor/
- Architecture -- request flow, loader integration
- Configuration Reference -- all thumbor.conf settings
Source Code and Contributions
The source code is managed in a Git repository, with its main branches hosted on GitHub. Issues can be reported there too.
We'd be happy to see many forks and pull requests to make this package even better. We welcome AI-assisted contributions, but expect every contributor to fully understand and be able to explain the code they submit. Please don't send bulk auto-generated pull requests.
Maintainers are Jens Klein and the BlueDynamics Alliance developer team. We appreciate any contribution and if a release on PyPI is needed, please just contact one of us. We also offer commercial support if any training, coaching, integration or adaptations are needed.
License
ZPL-2.1 (Zope Public License)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zodb_pgjsonb_thumborblobloader-0.3.0.tar.gz.
File metadata
- Download URL: zodb_pgjsonb_thumborblobloader-0.3.0.tar.gz
- Upload date:
- Size: 21.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ca6079f9db97126c433d38dd047db00057392ac3394a138ef42218efe7229f7
|
|
| MD5 |
33e06a0487c5307cec4771e90d24fa9c
|
|
| BLAKE2b-256 |
fd03546271d595ef75be545cfddda7c11769d186aa2a4ae92b5068b68c4822f8
|
Provenance
The following attestation bundles were made for zodb_pgjsonb_thumborblobloader-0.3.0.tar.gz:
Publisher:
release.yaml on bluedynamics/zodb-pgjsonb-thumborblobloader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zodb_pgjsonb_thumborblobloader-0.3.0.tar.gz -
Subject digest:
4ca6079f9db97126c433d38dd047db00057392ac3394a138ef42218efe7229f7 - Sigstore transparency entry: 1066531892
- Sigstore integration time:
-
Permalink:
bluedynamics/zodb-pgjsonb-thumborblobloader@530ffa41287d1e86ac8f3544d34d56e01cb1cddd -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/bluedynamics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@530ffa41287d1e86ac8f3544d34d56e01cb1cddd -
Trigger Event:
release
-
Statement type:
File details
Details for the file zodb_pgjsonb_thumborblobloader-0.3.0-py3-none-any.whl.
File metadata
- Download URL: zodb_pgjsonb_thumborblobloader-0.3.0-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bf9001c4df494e6a7caf7307250d76d959b48d5c04dc28a2a699c26ab47f151
|
|
| MD5 |
a48775661eaa801b52c62387b18f7584
|
|
| BLAKE2b-256 |
1aa442807f680296184b2fdd0fbbe1350d063e924216de66d9fda5e536fb2b34
|
Provenance
The following attestation bundles were made for zodb_pgjsonb_thumborblobloader-0.3.0-py3-none-any.whl:
Publisher:
release.yaml on bluedynamics/zodb-pgjsonb-thumborblobloader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zodb_pgjsonb_thumborblobloader-0.3.0-py3-none-any.whl -
Subject digest:
2bf9001c4df494e6a7caf7307250d76d959b48d5c04dc28a2a699c26ab47f151 - Sigstore transparency entry: 1066531896
- Sigstore integration time:
-
Permalink:
bluedynamics/zodb-pgjsonb-thumborblobloader@530ffa41287d1e86ac8f3544d34d56e01cb1cddd -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/bluedynamics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@530ffa41287d1e86ac8f3544d34d56e01cb1cddd -
Trigger Event:
release
-
Statement type: