Tag: Immich

Self-hosted photo backup with AI search — the self-hosted answer to Google Photos.

  • Immich vs Google Photos: Can You Actually Replace It?

    Immich vs Google Photos: Can You Actually Replace It?

    Google Photos is where most people’s pictures already live, and “what if I stopped using it” is one of the most common self-hosting motivations — usually a mix of privacy, control, and not wanting a cloud service to decide what happens to a decade of family photos. Immich is the leading self-hosted answer. This is an honest comparison of the two, including the things Immich still does not match, and what it actually takes to move off Google Photos rather than run the two side by side.

    Intermediate · 8 min · Immich

    What you get on each side

    Google Photos is a polished, finished product. Backup from your phone is automatic and invisible, search by text (“sunset at the beach”) and by object is excellent, the timeline is beautiful, and sharing is frictionless because your contacts are already there. The trade-offs are that it is a closed service, your data is on their infrastructure, it is subject to their terms and their pricing for extra storage, and the ML features and your photos are processed on their servers.

    Immich gives you the same core job — a photo library that backs up from your phone, groups by face, searches by object and by natural-language query, and stores the original files — but on your own hardware. The machine learning runs on your box, the originals are plain files in a folder you can copy anywhere, and there is no account and no service in the path. The setup is covered in the Immich Docker guide.

    Where Immich genuinely matches Google Photos

    • Automatic phone backup. The Android and iOS apps back up your camera roll to the server, and the phone keeps working offline. For the “stop losing photos if I lose my phone” job, it does it.
    • Face grouping. It detects and groups faces so you can find everyone, the way Google does.
    • Object and text search. The machine-learning side supports object detection and a natural-language query box, so “what did I shoot of the dog” works.
    • The originals are yours. Everything lands in a plain upload folder. Google Photos’ originals are accessible but tied to the service; Immich’s are literally files on your disk.

    Where Immich still does not match

    Being honest about the gap matters, because it is the difference between “replace it this weekend” and “run it alongside for a while.”

    • Polish of the web and timeline experience. Google Photos’ interface is more refined. Immich is good and improving, but a long session in the timeline and the editing tools is still a notch behind.
    • Sharing with people who are not on the system. Sharing a photo with a relative is frictionless in Google because they are there. In Immich, sharing with someone outside your server means sending them a file or a link, not a native share.
    • Search quality out of the box. Google’s search is trained on an enormous corpus and is very good immediately. Immich’s search depends on the ML models running on your hardware and takes time to index a large library.
    • Indexing time on first import. The ML side (faces, embeddings) is CPU-hungry on first import. A large library takes a while to fully index — hours on a decent desktop CPU, longer on a Raspberry Pi. The backup and browsing work from the first photo; the smart features catch up in the background.

    The migration is the real work

    Running Immich is straightforward; the hard part is getting your existing photos off Google Photos and into it, because Google does not offer a clean bulk download of the originals in a layout that Immich wants. The practical path is:

    1. Use Google Takeout to request your photos and videos as originals (not screenshots), which produces a large archive.
    2. Extract it and let Immich import the folder as a library — it scans the files and builds the timeline.
    3. Let the machine-learning indexing run in the background until faces and search catch up.

    After that, point your phone’s Immich app at the server for new photos, and you are running your own library with the old photos inside it. Plan for the Takeout export to be slow and large; it is the least glamorous step, but it is the only one that moves the history.

    Resource reality

    Immich is one of the heavier “simple” self-hosted apps, because it carries a real machine-learning pipeline. In the lab an empty-library Immich stack idled at roughly 1.3 GB of RAM across its four containers (server, database, machine-learning, and cache) on a 4-core box. A comfortable deployment wants at least 4 GB free for it, more if you are indexing a large library on CPU. That is real, but it is the same class of box that runs a media server, so for most homelabbers it fits.

    Whichever you pick

    If you…PickWhy
    Want zero effort, best-in-class search, and do not mind a closed cloudGoogle PhotosMost polished, best search, frictionless sharing
    Want your photos and the ML on your own hardware, no serviceImmichOriginals are files you own, no account, no cloud in the path
    Are on a home server already and want to reduce a dependencyImmichIt fits the same box and removes a recurring storage cost
    Mainly share photos with family who are all on GoogleGoogle PhotosNative sharing wins until your household is on Immich

    Bottom line

    Immich is a real replacement for the core job of Google Photos — automatic backup, face groups, object and text search, and originals you own — and for a home-server person it removes a recurring cloud dependency and keeps the data on hardware they control. The honest gaps are polish, out-of-the-box search quality, and the friction of sharing with people outside your system, plus a migration where the Google Takeout export is the slow part. If you are willing to do the one-time migration and accept that the smart features take time to index, Immich is the credible “I want to replace Google Photos” answer.

    Tested on:

    Immichv3.2.2 (4 containers)
    OS / runtimeDebian 12, Docker 29.7.2
    Idle RAM (empty library)~1.3 GB total (server 755 MiB, postgres 364 MiB, ML 169 MiB, cache 12 MiB)
    NoteA fresh install must use the current ghcr.io/immich-app/postgres image (see the Immich guide)

    Last tested: 21 September 2026

  • Immich in Docker: Self-Hosted Photo Library (Compose Guide)

    Immich in Docker: Self-Hosted Photo Library (Compose Guide)

    Immich is the self-hosted photo backup that finally closes the loop on Google Photos: unlimited storage, on-device ML, automatic face and object grouping, and a mobile app that behaves like the one you are replacing — while every file stays in a folder you own. It is heavier than most single-container services (three to five containers, a Postgres variant with vector search), so this guide walks through the full Docker Compose stack, the app setup, and the decisions that actually matter.

    Beginner · 10 min · Docker

    What Immich actually does

    • Unlimited backup from the Android/iOS apps: your library syncs, originals are stored on your server, and the phone app keeps working offline.
    • Machine learning — face grouping, object detection, blur search, and a natural-language query box (“sunset at the beach”) — running on your own hardware.
    • Standard files — everything lands in a plain upload/ folder. Immich’s database is metadata; the photos are just files you can copy anywhere.

    The honest caveat: the ML side (face detection, embeddings) is CPU-hungry on first import. A 50,000-photo library on a Pi 5 takes days to fully index; on a modern desktop CPU it takes hours. The backup and browsing parts work fine on a Pi from the first photo.

    Prerequisites

    • Docker + Compose plugin
    • A machine with at least 4 GB RAM for comfortable use of the ML pipeline (it starts earlier with less, but indexing will be glacial)
    • A free TCP port (this guide uses 2283 for the web UI and API)
    • Optional but recommended: a GPU (Coral TPU or NVIDIA) for the ML container — it makes indexing dramatically faster

    Step 1: The compose file

    Immich’s official stack has four containers: the server, the ML worker, Redis (queue), and a Postgres fork with vector search built in. The full file:

    services:
      immich:
        image: ghcr.io/immich-app/immich-server:release
        container_name: immich
        ports:
          - "2283:2283"
        environment:
          DB_HOSTNAME: immich-db
          DB_DATABASE_NAME: immich
          DB_USERNAME: immich
          DB_PASSWORD: CHANGE-ME-DB-PASSWORD
          TZ: Europe/London
          IMMICH_UPLOAD_LOCATION: /usr/src/app/upload
        volumes:
          - ./upload:/usr/src/app/upload
          - immich_config:/config
        depends_on:
          - immich-db
          - immich-redis
        restart: unless-stopped
    
      immich-machine-learning:
        image: ghcr.io/immich-app/immich-machine-learning:release
        container_name: immich-machine-learning
        restart: unless-stopped
        # Optional: uncomment to use the GPU (e.g. Pi 5 + Coral or NVIDIA host)
        # devices:
        #   - "/dev/dri:/dev/dri"
    
      immich-redis:
        image: docker.io/valkey/valkey:9
        container_name: immich-redis
        restart: unless-stopped
    
      immich-db:
        image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
        container_name: immich-db
        environment:
          POSTGRES_PASSWORD: CHANGE-ME-DB-PASSWORD
          POSTGRES_USER: immich
          POSTGRES_DB: immich
        volumes:
          - immich_db_data:/var/lib/postgresql/data
        restart: unless-stopped
    
    volumes:
      immich_db_data:
      immich_config:

    Notes on the non-obvious parts:

    • The database image is a Postgres build with the vector extensions compiled in — Immich needs pgvector and pgvecto.rs for blur search and the embedding store. As of Immich v3.2.x the image moved from tensorchord/vectordb (retired from Docker Hub) to ghcr.io/immich-app/postgres. Do not swap it for a plain postgres:16; the server will refuse to start without the extensions.
    • DB_HOSTNAME: immich-db — containers in the same compose network resolve each other by service name. This is why the DB container must be named exactly that (or the environment value updated to match).
    • ./upload:/usr/src/app/upload — your actual photos live here, as plain files. This is the volume you back up.
    • immich_config:/config — the ML model cache. It fills on first run (hundreds of MB of models download once). Named volume, so it survives container rebuilds.

    Step 2: Start the stack

    docker compose up -d
    docker compose logs -f immich

    First start takes a couple of minutes: the ML container downloads its models, the database initializes. Then open http://YOUR_SERVER_IP:2283.

    Step 3: Create your account

    The first user you create becomes the administrator. Enter a name, email, and a strong password. There is no separate setup wizard — the web UI is your admin panel, under Admin in the left menu once you are in.

    Step 4: Connect the mobile apps

    Immich has first-party apps on both platforms (search “Immich” in the Play Store / App Store — not the clone apps).

    1. Open the app, choose Self-Hosted, and enter http://YOUR_SERVER_IP:2283 (or your TLS URL once you have a reverse proxy).
    2. Log in with the account you created.
    3. Grant photo library access. The app uploads originals and caches locally, so it keeps working on the train.

    Android users: enable Battery Unrestricted for the app if you want background upload to be reliable. This is the single most common “why is it not syncing” fix.

    Step 5: Let it catch up

    On first import the ML queue backs up: every photo gets face detection, object tags, and embedding vectors computed. Watch progress under Admin → System → Machine Learning. Two practical settings:

    • Limit concurrent ML jobs. Default is fine on 4+ cores; on a Pi, the queue simply runs slowly — leave it, do not restart the stack, let it chew through the backlog.
    • Pause the queue if you want to copy a huge library in without the server fighting for CPU. Resume when the transfer is done.

    Step 6: The features worth turning on

    1. Face grouping — automatic, no configuration. After a while of indexing, people get clustered; name the groups and they persist across devices.
    2. Search — text search, blur search (upload a reference photo), and the natural-language box all work once embeddings exist. Blur search is the one that reliably surprises people.
    3. Sharing — share albums or individual photos by link. Public links are the way to send photos to people who do not have an Immich account.
    4. Trash & versioning — deletions go to trash first; the web UI can also keep multiple versions of an edited photo.

    Access from outside your network

    Same two honest options as every other service on this site:

    • Tailscale — install it on the server and the phones. No open ports, encrypted mesh, works on mobile data. The lowest-risk path for a photo library.
    • Cloudflare Tunnel or a reverse proxy with TLS — more setup, but gives you a stable public URL and real certificates. We cover both in the Security & Networking series.

    Do not forward port 2283 on your router with the default setup. An exposed photo server is a magnet for automated probing, and the app’s login page is public.

    Resource usage (measured)

    StateRAM
    Idle (all containers up, no import)~1.2–1.6 GiB total
    Active import, 4-core desktop CPU~2.5 GiB, ML queue at full speed
    Pi 5, indexing only~1.5 GiB, queue crawling (hours per 1k photos)

    The number to plan around is the ML container: it is the only one that grows. If your machine is tight, you can run the backup stack without the ML container entirely — photos still sync and browse, they just do not get faces or search until you add it back.

    Updating

    docker compose pull && docker compose up -d

    Immich is active-release software; expect breaking changes between major versions, and the web UI will tell you when a migration is needed. Before any major update, back up two things: the upload/ folder (your photos) and a pg_dump of immich-db:

    docker compose exec immich-db pg_dump -U immich immich > immich-db-backup.sql

    FAQ

    Will it replace Google Photos without data loss?

    Yes, in the practical sense. The apps upload originals; you can then archive or delete the cloud copies. The one behavioural difference: Immich edits (filters, crops) are stored as separate versions, not as edits to the original file.

    Can I import an existing library from a folder?

    Yes. On the server, copy your photos into ./upload/library/<your-account-email>/ (keep the folder structure you like — dates and albums come from the files), then trigger a rescan from the web UI: Admin → System has a rescan/scan trigger, or simply restart the stack and Immich will pick up the new files on start. The import is where the ML queue gets its big backlog; expect the indexing to take as long as the first sync.

    Does it work with a NAS?

    Yes. Point the upload volume at a NAS share (e.g. /mnt/nas/photos:/usr/src/app/upload) and everything else is unchanged. Just know that network storage caps your import speed and makes ML indexing slower still.

    What about backups of Immich itself?

    Two artifacts: the upload/ folder and the database. Copy upload/ to another machine or to MinIO (S3), and dump the DB with the pg_dump command above. That is a complete, restorable backup.

    Where does this fit?

    Immich is the media layer for photos and videos in the same way Jellyfin is for the movie and TV library. Run them side by side on the same machine and you have the full self-hosted media stack, with MinIO as the off-machine safety copy.

    What’s next?

    The natural next steps from this guide: