Skip to content
Jetrepo
Esc
navigateopen⌘Jpreview
On this page

Storage and Redis

Connect Postgres, Redis, object storage, and signed image delivery.

The production stack stores CMS and authentication data in Postgres, files in object storage, and operational state in Redis. The Image service reads originals and stores generated results in the same object bucket.

Access

You need deployment-secret, container-network, and volume administration.

State and consumers

Service Production behavior
Postgres Stores authoritative CMS and authentication state in pgdata
Redis Uses authentication and AOF in redis_data; persists queues, delayed jobs, and delivery cache
Object storage Stores originals and generated images in minio_data; bucket objects are anonymously downloadable
Core API Uploads through the public S3_PUBLIC_URL endpoint and queues file processing
Worker Consumes canonical Operations, cleanup, file processing, and enabled Environment work; uses PostgreSQL, Redis, the Management API, and object storage
Image service Loads objects over the internal network and stores generated results under _imagor

Core API and Worker containers must resolve and reach S3_PUBLIC_URL. Test that hairpin or split-DNS path, not only browser access. The Image service uses the internal object endpoint instead.

The Delivery process uses IMAGOR_PUBLIC_URL and IMAGOR_SECRET when generating signed Asset URLs. The production stack forwards both values to Core and Delivery and shares the signing secret with the Image service. Supply matching values when deploying the services separately. Verify the returned URL’s origin as well as its signature before accepting media delivery.

A separately deployed Preview frontend also needs shared server-side session storage when it runs more than one replica. @jetrepo/preview/redis accepts a minimal Redis-compatible client and stores only opaque, expiring Preview sessions. Give the frontend its own key prefix and least-privilege Redis access. Never fall back to process memory in production or expose the stored Preview Bearer to browser JavaScript.

When a separately deployed frontend uses Redis on the CMS stack’s private network, attach only that frontend to the required network. Keep the CMS services isolated from unrelated application networks: generic database and Redis hostnames can resolve to another application’s service on a shared network. Check the frontend’s Redis connection and HTTP readiness after every deployment.

Object setup attempts to create the bucket and anonymous-download policy, but its script can still exit 0 after a failed setup command and no application waits for it. Inspect the setup logs, then make an unauthenticated GET request for a non-sensitive test object before upload or image tests.

Check the services

docker compose -f docker-compose.prod.yaml ps -a
docker compose -f docker-compose.prod.yaml logs --tail=200

Redact credentials, signed URLs, cookies, personal data, and content before sharing logs. Compose status should show Postgres healthy, Redis healthy through its authenticated PONG check, and object setup exited 0.

Use a non-sensitive test image to verify the full path:

  1. Use the delegated agent’s Asset import workflow or the documented TUS upload endpoint; the governance console has no Media authoring screen.
  2. Wait for Worker-generated metadata to appear.
  3. Load its public original URL without credentials; anonymous download is expected.
  4. Request one named signed image transform and confirm the generated result loads.
  5. Inspect Worker and Image service logs if any stage fails.

A green database or Redis health check does not prove uploads or image transforms work.

Change and recovery limits

Changing bucket names or object credentials requires a tested, coordinated update of object storage, setup, Core API, Worker, and Image service. Changing the image signing secret requires Core API, Delivery API, and Image service to move together; reverting all three restores validation of older URLs.

Never delete named volumes to fix a credential or bucket mismatch. Redis loss can remove delayed or queued work even when content survives. Pub/Sub invalidation messages are transient and are lost across a Redis interruption or restore. Coordinated Postgres plus object backup/restore is drilled with an empty-work Redis omission. Object credential rotation, Redis AOF recovery, non-empty queue replay, public-endpoint hairpin routing, and generated-image cache restoration have not been drilled by the project.

Was this page helpful?