Docker Compose
Production-ready self-host deployment, generated secrets, images, ports, volumes, health checks, and upgrades.
The root docker-compose.yml is the supported self-host stack. It uses published GHCR images by default, so self-hosters do not need Node, pnpm, or a source build toolchain.
Prepare the environment
git clone https://github.com/lord007tn/keenpix.git
cd keenpix
cp .env.example .envSet at least:
POSTGRES_PASSWORD=replace-with-a-long-random-password
BETTER_AUTH_SECRET=replace-with-64-random-hex-characters
KEENPIX_WORKER_SECRET=replace-with-a-different-64-random-hex-value
KEENPIX_SUPER_ADMIN_EMAIL=admin@example.com
KEENPIX_SUPER_ADMIN_PASSWORD=replace-with-a-long-random-passwordGenerate secrets with openssl rand -hex 32. Never reuse the auth secret as the worker secret.
MaxIO is private to the Compose network and has internal fallback credentials so
the cache works on the first boot. Set KEENPIX_CACHE_S3_ACCESS_KEY_ID and
KEENPIX_CACHE_S3_SECRET_ACCESS_KEY when the Docker network is shared with
untrusted workloads, or set the complete S3 block to use Cloudflare R2.
Start and verify
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f app transform workerThe dashboard is available at http://localhost:3000; docs default to http://localhost:3003. Set KEENPIX_PORT and KEENPIX_DOCS_PORT to change host ports.
The app waits for Postgres and transform readiness. The worker waits for transform
and Dragonfly. The transform service waits for Dragonfly and MaxIO. Docker
restarts failed services with unless-stopped.
Images
| Variable | Default image |
|---|---|
KEENPIX_APP_IMAGE | ghcr.io/lord007tn/keenpix-app:latest |
KEENPIX_TRANSFORM_IMAGE | ghcr.io/lord007tn/keenpix-transform:latest |
KEENPIX_WORKER_IMAGE | ghcr.io/lord007tn/keenpix-worker:latest |
KEENPIX_DOCS_IMAGE | ghcr.io/lord007tn/keenpix-docs:latest |
Pin all four to the same vX.Y.Z tag for production. Do not mix application versions across one deployment.
Persistent volumes
| Volume | Data |
|---|---|
keenpix_pg | Postgres control-plane data |
keenpix_dragonfly | BullMQ jobs and Dragonfly snapshots |
keenpix_maxio | Durable S3-compatible transformed variants |
keenpix_cache | Transformed image disk cache |
Postgres must be backed up. MaxIO and the image cache can be rebuilt. Queue data
is operationally useful but is not the system of record. To replace MaxIO with
Cloudflare R2, set the five KEENPIX_CACHE_S3_* variables; no Compose topology
change is required.
Upgrade
docker compose pull
docker compose up -d --remove-orphans
docker compose psThe app entrypoint applies Prisma migrations before accepting traffic. Back up Postgres before upgrading, read release notes, and roll back by restoring both the prior image tags and a compatible database backup.