A modern, self-hosted photo album system built for photography enthusiasts.
Pilbum is a lightweight, self-hosted photo management platform. Keep full control of your photos with original quality, complete EXIF data, and Live Photo support — no compression, no ads, no third-party dependencies.
Perfect for: Photography portfolios, family albums, client deliveries, and anyone who values data privacy.
- Live Photo Support - Auto-pairs iOS Live Photos, hover to play animations
- EXIF Display - Camera model, lens, aperture, shutter speed, ISO, GPS location
- Masonry Gallery - Responsive layout with infinite scroll
- Dark Mode - System-aware automatic theme switching
- Multi-language - English and Chinese support
- Admin Dashboard - Photo upload, batch management, user permissions
- Auto-Update Detection - Check for new versions from GitHub releases
| Category | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| Database | SQLite (local) / PostgreSQL (cloud) |
| ORM | Drizzle |
| Styling | Tailwind CSS |
| Auth | Iron Session |
| Image Processing | Sharp |
| Maps | Leaflet + OpenStreetMap |
- Click the Deploy with Vercel button above
- Follow the setup wizard to configure database and storage
- Visit
/adminto manage your photos
git clone https://github.com/cailurus/Pilbum.git
cd Pilbum
cp .env.example .env
npm install
npm run devVisit http://localhost:3000/admin (default password: admin)
Pilbum needs two services: a database and object storage.
| Service | Local (Default) | Cloud (Recommended) |
|---|---|---|
| Database | SQLite | Supabase (free 500MB) |
| Storage | Local filesystem | Cloudflare R2 (free 10GB) |
Local SQLite (no config needed):
DATABASE_PROVIDER=localSupabase PostgreSQL:
DATABASE_PROVIDER=postgres
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgresGet your connection string: Supabase Dashboard → Settings → Database → Connection string (URI)
Other database options
- Neon - Serverless PostgreSQL
- Railway - Easy PostgreSQL hosting
- Vercel Postgres - Integrated with Vercel
Local filesystem (no config needed):
STORAGE_PROVIDER=localCloudflare R2:
STORAGE_PROVIDER=s3
S3_ENDPOINT=https://[account-id].r2.cloudflarestorage.com
S3_BUCKET=pilbum-photos
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_REGION=auto
NEXT_PUBLIC_STORAGE_BASE_URL=https://pub-[hash].r2.devSetup: R2 Dashboard → Create bucket → Manage API Tokens → Create token with Object Read & Write
Other storage options
- AWS S3 - Industry standard
- Supabase Storage - Unified with Supabase DB
- Azure Blob - Microsoft cloud
# Database
DATABASE_PROVIDER=postgres
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres
# Storage
STORAGE_PROVIDER=s3
S3_ENDPOINT=https://[account-id].r2.cloudflarestorage.com
S3_BUCKET=pilbum-photos
S3_ACCESS_KEY_ID=your-key
S3_SECRET_ACCESS_KEY=your-secret
S3_REGION=auto
NEXT_PUBLIC_STORAGE_BASE_URL=https://your-domain.com
# Auth
ADMIN_DEFAULT_PASSWORD=change-this-passwordFor detailed configuration guides, see docs/storage-configuration.md
When deploying via Vercel, a fork of this repository is created in your GitHub account. To get updates:
- Go to your forked repository on GitHub
- You'll see "This branch is X commits behind cailurus/Pilbum:main"
- Click Sync fork → Update branch
- Vercel will automatically redeploy
# Add upstream (one-time)
git remote add upstream https://github.com/cailurus/Pilbum.git
# Sync updates
git fetch upstream
git merge upstream/main
git push origin maindocker build -t pilbum .
docker run -p 3000:3000 --env-file .env pilbumnpm install
npm run build
npm startMIT