Self-hosting
Deploy
Deploy Keenpix with Docker in about a minute.
Keenpix runs as a single Node container (sharp needs Node, not an edge runtime). Put a
CDN in front of /img/*, then configure that CDN to cache the endpoint's immutable
image responses.
The 60-second deploy
git clone <your-fork> keenpix && cd keenpix
cp .env.example .env
# set a strong secret:
# BETTER_AUTH_SECRET=$(openssl rand -hex 32)
# set POSTGRES_PASSWORD, KEENPIX_SUPER_ADMIN_EMAIL, and KEENPIX_SUPER_ADMIN_PASSWORD
docker compose up -d --build
# → http://localhost:3000docker-compose.yml ships the app plus Postgres. On boot the container runs
prisma migrate deploy, seeds the default org and super admin user, then serves
the dashboard and the transform endpoint as a non-root user.
After deploy
- Sign in as
KEENPIX_SUPER_ADMIN_EMAILwithKEENPIX_SUPER_ADMIN_PASSWORD. - Create a project pointed at your image origin.
- Add your source host under Settings → Security → Allowed hosts.
- Invite any staff from Settings → Staff. Copy the invitation link, or send it by email after SMTP is configured in Settings → Email. Env SMTP values are only used as a fallback when Settings SMTP is disabled or incomplete.
- Request
/img/https://your-origin.example/photo.jpg?project=ID&w=1200&fmt=webp— no API key required for transform URLs.
Architecture
Browser/CDN ──▶ Keenpix container (Node + sharp) ──▶ your image origin
│
└── disk cache (volume) + Postgres (projects, request logs)Scale horizontally behind a load balancer; the disk cache is per-instance, and CDN cache
rules plus immutable responses keep origin traffic low. See
CDN setup for Cloudflare, Nginx, and Caddy caching rules,
Deployment presets for ready-made .env files, and
Configuration for every environment variable.