English · Deutsch
Self-hosted photo and video gallery for photographers and studios. A self-hostable alternative to Picdrop, Pixieset and Pic-Time — your data stays with you.
Three typical setups — the Quick Start below covers the first; everything else is optional.
| You are… | Setup | Docs |
|---|---|---|
| Photographer or studio | Single mode, MinIO, one domain | Quick Start — 5 minutes |
| Agency with several photographer clients (self-hosted, for your own business) | Multi mode without billing, tenants created manually via super admin | docs/MULTI_TENANT.md |
In single mode the tenant is created automatically on first start — you only need create-admin for your first user. No super admin, no Stripe.
Want to offer Lumio as a SaaS to paying third parties? That's Competing Use and not freely permitted under the license (it's the business model behind our own lumio-cloud.de). A commercial license is available on request — see License. The SaaS mode is documented in docs/SAAS_MODE.md.
- 🚀 Fast — Direct-to-S3 uploads, virtualized galleries, libvips thumbnails
- 📷 RAW support — CR2, CR3, NEF, ARW, RAF, DNG, ORF, PEF, RW2, X3F via LibRaw
- 🎬 Video streaming — HLS adaptive bitrate, scrubbing previews, poster frames
- 💬 Proofing — Likes, color tags, star ratings, comments, drawn annotations on photo and video (time-anchored), team voting
- 🎨 Whitelabel — Logo, colors, custom domains per studio or gallery
- 🔐 Secure — Signed URLs, Argon2 passwords, audit log
- ☁️ Storage-flexible — MinIO, S3, R2, B2, Wasabi, Hetzner Object Storage
- 🐳 Docker-first —
docker compose upand it runs
The studio — manage galleries, smart collections, tag filters, team proofing:
Proofing & annotation — Clients like images, assign color tags and draw annotations directly on the photo, with per-photo comments.
Video proofing — Moving images get reviewed just like a photo: clients scrub through the video via filmstrip, place annotations at a specific point in time and draw directly on the still frame — with an optional note per annotation.
Filmstrip scrubbing — dragging across the bar shows a preview of the respective frame with its timestamp:
Upload & formats — Drag & drop with parallel uploads, duplicate detection and smart sections. JPEG, PNG, WebP, RAW, HEIC/HEIF, video and PDF — up to the configurable file limit.
AI auto-tagging — Images are tagged automatically (CLIP model); suggestions can be filtered by a confidence threshold and applied. Clients can optionally filter by tags.
Gallery design — Per gallery: layout, image arrangement, slideshow transitions, hero image, event logo, colors. Whitelabel down to the detail.
Analytics — Views, most popular images, downloads and an engagement funnel from visit to order.
Print shop — Sell prints, canvases and photo books straight from the gallery. Your own providers, products, shipping, optionally with Stripe payment.
Security & GDPR — Data processing agreement under Art. 28 GDPR signable electronically, share links with expiry and password, audit log and two-factor authentication.
Webhooks & integrations — Notify external tools via HTTP POST about gallery events. Every request is signed with your webhook secret.
Light or dark mode — The studio backend in light or dark, with its own accent color and logo variants for both modes. (The other screenshots here show dark mode.)
5 minutes from zero to your first gallery. Requirements: Docker + Docker Compose v2 (amd64 or arm64). Details: docs/REQUIREMENTS.md.
git clone https://github.com/markusthiel/lumio.git
cd lumio
cp .env.example .env
# Generate and insert secure passwords
sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')|" .env
sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$(openssl rand -base64 32 | tr -d '/+=')|" .env
sed -i "s|^SESSION_SECRET=.*|SESSION_SECRET=$(openssl rand -base64 32 | tr -d '/+=')|" .env
sed -i "s|^S3_ACCESS_KEY=.*|S3_ACCESS_KEY=$(openssl rand -hex 12)|" .env
sed -i "s|^S3_SECRET_KEY=.*|S3_SECRET_KEY=$(openssl rand -base64 32 | tr -d '/+=')|" .envdocker compose up -dThis builds the containers and starts Postgres, Redis, MinIO, API, frontend, worker and Caddy. The first start takes 3–5 min (build + DB migration).
Check status:
docker compose psAll services should be running (healthy).
docker compose exec api npm run create-admin -- \
--email=you@example.com \
--password=atleast12chars \
--name="Your Studio"In your browser:
→ http://localhost (studio login)
After logging in you'll find gallery creation in the top left. Upload a photo, share the gallery link — done.
- Attach your own domain → docs/SELFHOSTING.md (15-min setup with HTTPS)
- Images disappear on container restart? → MinIO stores data in the
minio_datavolume, which persists. Just make sure you don't accidentallydocker volume rmit. - Set up backups → docs/BACKUP.md
- Something going wrong? → docs/TROUBLESHOOTING.md
┌──────────┐ ┌──────────┐ ┌────────────────┐
│ Frontend │◄──►│ API │◄──►│ Postgres/Redis │
│ Next.js │ │ Fastify │ │ + S3 Storage │
└──────────┘ └────┬─────┘ └────────────────┘
│
▼
┌─────────┐
│ Worker │ RAW decode, thumbnails,
│ Python │ video transcode, ZIP build
│ Celery │
└─────────┘
apps/frontend— Next.js 16 (App Router) + Tailwindapps/api— Fastify + Prisma (Postgres) + BullMQ (Redis)apps/worker— Python + Celery + rawpy/pyvips/ffmpegpackages/shared— Shared TypeScript types + Zod schemasinfra/— Caddy config, Postgres init
All optional. The Quick Start above is enough for a single studio.
| Scenario | Docs |
|---|---|
| Production behind your own domain with HTTPS | docs/SELFHOSTING.md |
| Multiple studios on one instance | docs/MULTI_TENANT.md |
| SaaS mode with Stripe billing | docs/SAAS_MODE.md |
| GPU acceleration (NVENC + AI tags) | docs/GPU.md |
| AI auto-tagging (CLIP) | docs/ML.md |
| Tenant subdomains via wildcard cert | docs/WILDCARD.md |
| Distribute load across multiple servers | docs/SCALING.md |
| External S3 instead of MinIO (R2, B2, Hetzner, Wasabi) | docs/STORAGE.md |
| Backups, migrations, re-queue | docs/OPERATIONS.md |
| Contributing / development | docs/DEVELOPMENT.md |
Functional Source License 1.1 (FSL-1.1-ALv2) — a source-available license (not OSI open source).
Permitted for everyone:
- Individuals, professional photographers and studios: use, self-host, modify — including commercially for your own business
- Agencies: run Lumio as part of services for your own clients
Not permitted:
- Building a competing, hosted SaaS/cloud offering that provides the same or substantially similar functionality as Lumio to third parties as a product (Competing Use)
Time-limited: Each version automatically becomes available under the Apache License 2.0 two years after its release — then without restriction.
For a hosted/competing offering, a commercial license is available on request.
Pull requests welcome. See CONTRIBUTING.md.
Issues & discussions: https://github.com/markusthiel/lumio/issues













