Skip to content

photoserver-pro/gallery

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10,020 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


License: AGPLv3 Discord

High performance self-hosted photo and video management solution


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.

What's Different from Upstream Immich

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

Structured JSON Logging

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 to This Fork

Switching is simple — just change your Docker image names. Your existing database, configuration, and media files are fully compatible.

Step 1: Back Up Your Database

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.gz

Step 2: Update Your Docker Compose File

Set the version in your .env file:

IMMICH_VERSION=v4

Change 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}-cuda

Step 3: Restart

docker compose pull
docker compose up -d

That'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/.

Links

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

Translations

Read more about translations here.

Translation status

Docker Images

Pre-built Docker images are published to GitHub Container Registry (GHCR) under the open-noodle organization.

Available Images

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)

Tags

  • release / release-cuda — most recent published build (like upstream's release tag)
  • v4 — floats to the latest v4.x.x release (set IMMICH_VERSION=v4 to auto-update within major version)
  • v4.2.6 — pinned version using semantic versioning

Publishing

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:

  1. A maintainer triggers the workflow from the Actions tab (or via gh workflow run), optionally passing an explicit version.
  2. If no version is passed, the next semver is computed from commits since the latest tag:
    • changelog:skip PR label → no release (skips build, tag, and push entirely)
    • feat: commit or changelog:feat PR label → minor bump (e.g. v4.2.6v4.3.0)
    • BREAKING CHANGE in commit body → major bump (e.g. v4.3.0v5.0.0)
    • Everything else (fix:, docs:, chore:, etc.) → patch bump (e.g. v4.2.6v4.2.7)
  3. Three jobs run in parallel: server, ML (CPU), and ML (CUDA)
  4. Each image is tagged with the version, the major version (e.g. v4), and release
  5. Git tags are created after successful builds
  6. 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.6

Or use the GitHub Actions UI: Actions > Release Gallery > Run workflow > enter version (or leave blank for auto-bump) > Run.

Contributing

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.

Setting Up a Dev Environment

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.

  1. Fork and clone the repo

    git clone https://github.com/<your-username>/gallery.git
    cd gallery
  2. Copy the example env file

    cp docker/example.env docker/.env

    The defaults work out of the box for local development. Adjust UPLOAD_LOCATION and DB_DATA_LOCATION if you want to store data somewhere other than the repo directory.

  3. Install dependencies

    pnpm install

    This installs deps for every workspace package (server, web, cli, sdk, e2e).

  4. 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.

Running Tests and Checks Before You Push

# 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 --write

CI 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)

Opening a Pull Request

  • Branch off main and 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.

About

High performance self-hosted photo and video management solution.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 54.9%
  • Dart 27.3%
  • Svelte 11.2%
  • Kotlin 1.4%
  • Swift 1.3%
  • Python 1.1%
  • Other 2.8%