Note
This is a community fork of Immich with additional features and improvements. Currently based on Immich v2.7.5. We regularly sync with upstream to stay up to date. See What's Different below.
Tip
Noodle Gallery for iPhone is now on the App Store! Back up your photos and browse your library on the go. Download on the App Store
Tip
Already running Immich? Switching to Gallery is a three-line config change — two image names in your docker-compose.yml and IMMICH_VERSION=v4 in your .env. Your library, database, and mobile apps are fully compatible. See the install guide.
Not for you? A one-command switch-back script cleans up Gallery-specific tables and columns and puts you back on upstream Immich. Your photos and videos never move.
This fork builds on top of Immich with the following improvements:
Create collaborative photo-sharing spaces where multiple users can contribute and browse photos together. Unlike partner sharing (which shares your entire library one-way), Shared Spaces let you create focused groups — "Family", "Friends", "Vacation 2025" — with role-based access (Owner, Editor, Viewer). Photos are linked by reference with zero additional storage cost. Members can optionally merge space assets into their personal timeline. Spaces feature album-style collage cards, cover photos with drag-to-reposition, list and grid views, pinnable favorites, and shared face recognition so people detected across the space are browsable by all members. Full mobile parity — create, manage, and browse spaces from the Flutter app. Feature page · Documentation
A unified FilterPanel available on the Photos timeline, Shared Spaces, and Map view. Filter by people, location, camera, tags, rating, media type, and favorites — with a temporal picker for year/month scoping. Filters are contextual: narrowing the time range automatically refreshes suggestions so you only see cameras, locations, and people that actually appear in that period. Combine filters with CLIP-powered smart search in Spaces for natural language queries scoped to your filtered results. Collapsible section selector lets you show only the filter categories you care about. Feature page · Spaces filtering · Map filtering · Documentation
Create named, color-coded groups of users (e.g., "Family", "Close Friends") that you can select with one click when sharing albums or inviting to Spaces. Instead of picking people individually every time, click a group chip and all members are added at once. Groups are personal — each user manages their own. Feature page · Documentation
Store your photos and videos in any S3-compatible object storage — AWS S3, MinIO, Cloudflare R2, Backblaze B2, Wasabi, and more. Configure it with a few environment variables and new uploads go straight to your bucket. Choose between redirect mode (clients download directly from S3 via presigned URLs) or proxy mode (server streams the files). Both disk and S3 backends run simultaneously, so existing files on disk continue to work. A built-in Storage Migration tool lets you migrate existing files between disk and S3 in either direction, with resume, rollback, and configurable concurrency. Feature page · Documentation
Define categories like "Screenshots", "Memes", or "Receipts" with text prompts, and Gallery uses CLIP AI to automatically tag and optionally archive matching photos. Each category has a tunable similarity threshold and can either tag-only or tag-and-archive. Runs on the same CLIP pipeline as smart search — no extra processing. Scan your entire existing library in seconds or let it classify new uploads automatically. Per-user categories so everyone can define their own clutter rules. Feature page
Extends upstream's photo duplicate detection to videos. Extracts multiple frames from each video, generates CLIP embeddings for each, and averages them into a single vector. This captures the visual content of the entire video, not just a single thumbnail. Uses the same deduplication UI and configurable similarity threshold as photo duplicates. Feature page · Documentation
Automatically detect and tag pets in your photos using YOLO11 object detection. Detected animals appear in the People section alongside faces, making it easy to browse all your pet photos. Per-space toggle to show or hide pets. Choose from three model sizes (nano, small, medium) depending on your accuracy vs. speed preference. Feature page · Documentation
Import your Google Takeout archive directly from the web UI — no command-line tools needed. A guided 5-step wizard walks you through selecting your Takeout zip or folder, scanning and extracting photos, reviewing metadata, and uploading. The importer preserves original dates, GPS coordinates, descriptions, favorite and archived status, and album structure. Everything runs client-side in the browser using zip.js for extraction and the existing upload API, so no additional server configuration is required. Feature page
Non-destructive image rotation from the asset viewer toolbar or via keyboard shortcuts ([ / ]), batch rotate for multiple selected images, and automatic timeline thumbnail refresh after edits. Rotations are cumulative and full 360° rotations auto-revert to the original. Video trimming lets you cut clips in the browser with a timeline scrubber — FFmpeg stream copy means instant, lossless results. Re-trim or restore the original at any time. Feature page · Video trimming · Documentation
Added support for structured JSON log output (IMMICH_LOG_FORMAT=json), making it easy to integrate with log aggregation systems like Grafana Loki, ELK Stack, Datadog, or Splunk.
Switching is simple — just change your Docker image names. Your existing database, configuration, and media files are fully compatible.
Important
Always back up your database before switching. This allows you to revert to upstream Immich if needed.
docker exec -t immich_postgres pg_dumpall -c -U postgres | gzip > immich-db-backup-$(date +%Y%m%d).sql.gzSet the version in your .env file:
IMMICH_VERSION=v4Change the image references in your docker-compose.yml:
services:
immich-server:
- image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
+ image: ghcr.io/open-noodle/gallery-server:${IMMICH_VERSION:-release}
immich-machine-learning:
- image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
+ image: ghcr.io/open-noodle/gallery-ml:${IMMICH_VERSION:-release}For NVIDIA GPU acceleration on the ML container, use the -cuda tag variant:
image: ghcr.io/open-noodle/gallery-ml:${IMMICH_VERSION:-release}-cudadocker compose pull
docker compose up -dThat's it. To switch back to upstream Immich later, flip the two image names back and either restore your database backup or run the automated switch-back script, which drops Gallery-specific tables, columns, and migration records — shared spaces, pet detection, classifications, duplicate data — leaving a plain upstream Immich database. Your photos and videos are never touched.
Català Español Français Italiano 日本語 한국어 Deutsch Nederlands Türkçe 简体中文 正體中文 Українська Русский Português Brasileiro Svenska العربية Tiếng Việt ภาษาไทย
Warning
Always follow 3-2-1 backup plan for your precious photos and videos!
Note
You can find the full documentation at https://docs.opennoodle.de/.
- Website
- Documentation
- Installation
- API Documentation — interactive Swagger UI with all endpoints including fork-specific ones. Also available on your own instance at
/doc - Roadmap
- Features
| Features | Mobile | Web |
|---|---|---|
| Upload and view videos and photos | Yes | Yes |
| Auto backup when the app is opened | Yes | N/A |
| Prevent duplication of assets | Yes | Yes |
| Selective album(s) for backup | Yes | N/A |
| Download photos and videos to local device | Yes | Yes |
| Multi-user support | Yes | Yes |
| Album and Shared albums | Yes | Yes |
| Scrubbable/draggable scrollbar | Yes | Yes |
| Support raw formats | Yes | Yes |
| Metadata view (EXIF, map) | Yes | Yes |
| Search by metadata, objects, faces, and CLIP | Yes | Yes |
| Administrative functions (user management) | No | Yes |
| Background backup | Yes | N/A |
| Virtual scroll | Yes | Yes |
| OAuth support | Yes | Yes |
| API Keys | N/A | Yes |
| LivePhoto/MotionPhoto backup and playback | Yes | Yes |
| Support 360 degree image display | No | Yes |
| User-defined storage structure | Yes | Yes |
| Public Sharing | Yes | Yes |
| Archive and Favorites | Yes | Yes |
| Global Map | Yes | Yes |
| Partner Sharing | Yes | Yes |
| Facial recognition and clustering | Yes | Yes |
| Memories (x years ago) | Yes | Yes |
| Offline support | Yes | No |
| Read-only gallery | Yes | Yes |
| Stacked Photos | Yes | Yes |
| Tags | No | Yes |
| Folder View | Yes | Yes |
| Shared Spaces | Yes | Yes |
| Smart Search & Filters | No | Yes |
| User Groups | No | Yes |
| Auto-Classification | No | Yes |
| Video Duplicate Detection | No | Yes |
| Pet Detection | Yes | Yes |
| Google Photos Import | No | Yes |
| Image Editing & Video Trimming | No | Yes |
| S3-Compatible Storage | Yes | Yes |
Read more about translations here.
Pre-built Docker images are published to GitHub Container Registry (GHCR) under the open-noodle organization.
| Image | Description |
|---|---|
ghcr.io/open-noodle/gallery-server |
Server + web UI + CLI (all-in-one) |
ghcr.io/open-noodle/gallery-ml |
Machine learning service (CPU) |
ghcr.io/open-noodle/gallery-ml:*-cuda |
Machine learning service (NVIDIA CUDA) |
release/release-cuda— most recent published build (like upstream'sreleasetag)v4— floats to the latest v4.x.x release (setIMMICH_VERSION=v4to auto-update within major version)v4.2.6— pinned version using semantic versioning
Images are built and published by the Release Gallery GitHub Actions workflow (.github/workflows/gallery-release.yml). The workflow is manually triggered via workflow_dispatch — it does not run automatically on merges to main.
How it works:
- A maintainer triggers the workflow from the Actions tab (or via
gh workflow run), optionally passing an explicit version. - If no version is passed, the next semver is computed from commits since the latest tag:
changelog:skipPR label → no release (skips build, tag, and push entirely)feat:commit orchangelog:featPR label → minor bump (e.g.v4.2.6→v4.3.0)BREAKING CHANGEin commit body → major bump (e.g.v4.3.0→v5.0.0)- Everything else (
fix:,docs:,chore:, etc.) → patch bump (e.g.v4.2.6→v4.2.7)
- Three jobs run in parallel: server, ML (CPU), and ML (CUDA)
- Each image is tagged with the version, the major version (e.g.
v4), andrelease - Git tags are created after successful builds
- Images are pushed to GHCR using the built-in
GITHUB_TOKEN— no extra secrets needed
To publish a specific version:
gh workflow run gallery-release.yml --ref main -f version=v4.2.6Or use the GitHub Actions UI: Actions > Release Gallery > Run workflow > enter version (or leave blank for auto-bump) > Run.
Gallery is a community fork and contributions are welcome — bug fixes, features, docs, translations. Come say hi on Discord if you want to chat about an idea before diving in.
The repo is a pnpm workspace monorepo — server (NestJS), web (SvelteKit), mobile (Flutter), machine-learning (Python), and a few supporting packages. The dev stack runs in Docker Compose with live reload for the server and web.
Prerequisites: Docker, Docker Compose, Node.js 22+, and pnpm.
-
Fork and clone the repo
git clone https://github.com/<your-username>/gallery.git cd gallery
-
Copy the example env file
cp docker/example.env docker/.env
The defaults work out of the box for local development. Adjust
UPLOAD_LOCATIONandDB_DATA_LOCATIONif you want to store data somewhere other than the repo directory. -
Install dependencies
pnpm install
This installs deps for every workspace package (server, web, cli, sdk, e2e).
-
Start the dev stack
make dev
This brings up Postgres, Redis, the ML service, the server (with hot reload), and the web UI on http://localhost:2283. The first run downloads ML models and builds containers, so give it a few minutes.
# Server
cd server && pnpm test # unit tests
cd server && pnpm check # TypeScript type check
# Web
cd web && pnpm test # unit tests
cd web && pnpm check # svelte-check + tsc
# All modules from the repo root
make check-all # type checks everywhere
make format-all # prettier --writeCI runs lint, type checks, unit tests, and e2e tests on every PR. If you're touching server controllers or repositories, regenerate the OpenAPI clients and SQL query files:
make open-api # regenerates TS SDK + Dart client
make sql # regenerates SQL query docs (needs DB running)- Branch off
mainand keep PRs focused on one change. - Follow Conventional Commits for your commit messages (
feat:,fix:,docs:,chore:, etc.) — the release workflow uses them to compute version bumps. - Include a short description of what changed and why, plus screenshots or screen recordings for UI work.
- Make sure CI is green before requesting review.
See CLAUDE.md for a deeper tour of the codebase architecture and common commands.