Install plone.pgthumbor#

This guide covers installing both the Plone-side package (plone.pgthumbor) and the Thumbor-side loader (zodb-pgjsonb-thumborblobloader), then verifying that everything works together.

Requirements#

  • Python 3.12+

  • Plone 6.2+ (Classic or Volto)

  • PostgreSQL 14+ (tested with 17)

  • zodb-pgjsonb >= 1.1 as the ZODB storage backend

  • Thumbor 7+

Install the Plone package#

Install plone.pgthumbor into your Plone environment:

uv pip install plone.pgthumbor
# or
pip install plone.pgthumbor

This also installs libthumbor (for HMAC URL signing) and plone.pgcatalog as dependencies.

Install the Thumbor loader#

On the machine or container running Thumbor, install the blob loader:

uv pip install zodb-pgjsonb-thumborblobloader
# or
pip install zodb-pgjsonb-thumborblobloader

This installs psycopg[binary] (async PostgreSQL driver) and boto3 (optional, for S3 fallback).

Configure ZODB storage#

Your zope.conf must use zodb-pgjsonb as the ZODB storage backend. plone.pgthumbor discovers its PostgreSQL connection from the storage layer.

%import zodb_pgjsonb

<zodb_db main>
  <pgjsonb>
    dsn dbname=zodb host=localhost port=5432 user=zodb password=zodb
    blob-temp-dir /app/var/blobstorage
  </pgjsonb>
  mount-point /
</zodb_db>

Configure Thumbor#

Create a thumbor.conf that uses the zodb-pgjsonb blob loader:

LOADER = "zodb_pgjsonb_thumborblobloader.loader"

HANDLER_LISTS = [
    "thumbor.handler_lists.healthcheck",
    "zodb_pgjsonb_thumborblobloader.auth_handler",
]

SECURITY_KEY = "your-secret-key"
ALLOW_UNSAFE_URL = False

RESULT_STORAGE = "thumbor.result_storages.file_storage"
RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = "/tmp/thumbor/result_storage"

PGTHUMBOR_DSN = "dbname=zodb host=localhost port=5432 user=zodb password=zodb"

See Configure Thumbor for plone.pgthumbor for the full list of settings.

Set Plone environment variables#

Plone needs to know where to point image URLs. Set these environment variables before starting Zope:

export PGTHUMBOR_SERVER_URL="http://localhost:8080/thumbor"
export PGTHUMBOR_SECURITY_KEY="your-secret-key"

The security key must match the SECURITY_KEY in thumbor.conf. See Configure Plone settings for all available settings.

Apply the GenericSetup profile#

Install via Plone’s Add-on installer (Site Setup > Add-ons > plone.pgthumbor), or programmatically:

setup_tool = portal.portal_setup
setup_tool.runAllImportStepsFromProfile("profile-plone.pgthumbor:default")

The profile registers the @@images override and the @thumbor-auth REST service.

plone.pgthumbor is autodiscovered via z3c.autoinclude – no %import is needed in zope.conf.

Verify installation#

Start Thumbor:

thumbor --conf=/etc/thumbor.conf

Start Zope:

runwsgi instance/etc/zope.ini

Upload an image in Plone. Right-click the displayed image and inspect the URL. It should point to your Thumbor server (the value of PGTHUMBOR_SERVER_URL) with an HMAC signature and blob coordinates:

http://localhost:8080/thumbor/<hmac>/400x300/<zoid_hex>/<tid_hex>

Open the URL in a new tab. You should see the scaled image.

If the image does not load, check:

  • Thumbor logs for connection errors to PostgreSQL

  • That the PGTHUMBOR_DSN in thumbor.conf is correct

  • That the PGTHUMBOR_SECURITY_KEY matches between Plone and Thumbor

  • That the blob_state table exists in PostgreSQL (created by zodb-pgjsonb)