How I Migrated 14000 Photos to the ZimaCube 2 With Zero Data Loss — An Immich Migration Guide

Eva Wong is the Technical Writer and resident tinkerer at ZimaSpace. A lifelong geek with a passion for homelabs and open-source software, she specializes in translating complex technical concepts into accessible, hands-on guides. Eva believes that self-hosting should be fun, not intimidating. Through her tutorials, she empowers the community to demystify hardware setups, from building their first NAS to mastering Docker containers.

💡 Community Spotlight: u/Ambitious_Shallot_79, r/minilab

You have a photo library. Years of memories. Albums you carefully organized. Faces you tagged. Shared links you sent to family.

Then you upgrade your NAS — and realize moving the files is not enough. Without the database, you lose every album, every face tag, every memory you curated. The photos are there, but the organization is gone.

I just moved 14,505 photos and 925 videos — 134 GiB total — from a DIY ZimaOS server to the ZimaCube 2. Every album survived. Every face tag came through. Every shared link still works.

Here is exactly how I did it, what almost went wrong, and what the ZimaCube 2 brought to the table that my old setup could not.

Why Immich, Why Now

Immich has become the go-to self-hosted photo solution for a reason. It gives you Google Photos-level features — facial recognition, semantic search, automatic backups from your phone, shared albums — without sending your photos to someone else's server.

But Immich stores its soul in PostgreSQL. The database holds albums, face vectors, people clusters, CLIP embeddings for smart search, and every piece of metadata that makes the library feel like yours. Move the files without the database, and you get a folder full of photos and a blank Immich instance.

This migration had one rule: zero data loss. The old server would not be wiped until the new one was verified.

What Immich Actually Stores (and Why It Matters)

Before touching any files, I mapped out exactly what needed to move:

Component Location Contents Must Migrate?
pgdata /DATA/AppData/immich/pgdata Full PostgreSQL — albums, faces, people, metadata ✅ Critical
model-cache /DATA/AppData/immich/model-cache Downloaded CLIP/facial recognition models ✅ Saves re-download
Photo library /DATA/Gallery/immich 14,505 photos + 925 videos + thumbnails (134 GiB) ✅ Actual media
Auto-backups /DATA/Gallery/immich/backups Last 14 daily database snapshots 💡 Already present
🎁 Moving only photo files — without the pgdata directory — gives you all your photos but none of your albums, face tags, people, memories, or shared links. Immich treats PostgreSQL as the source of truth. Both must move together.

Immich also creates automatic database backups daily at 2:00 AM, keeping the last 14 in the backups directory. Before running a manual dump, check if a recent auto-backup is already sitting there.

The Method: ZimaOS Files App (LAN Copy)

Both machines run ZimaOS on the same LAN. That meant I could use the built-in Files app for a direct LAN transfer — no external drives, no SCP commands, no intermediate storage.

Step 1: Mount the Source Machine

On the ZimaCube 2, open the Files app → + Add Storage → LAN Storage → enter the source machine local IP and authenticate. The source machine filesystem now appears as browsable storage on the ZimaCube 2.

Step 2: Stop Immich on the Source

This is the step people skip and regret. Stop Immich before copying. A running PostgreSQL instance is constantly writing — you need the database in a consistent, flushed state. On the source machine: ZimaOS App Store → Immich → Stop.

Step 3: Copy Both Directories

From the ZimaCube 2 Files app, navigate to the mounted source and select:

Source Path Destination Path on ZimaCube 2
/DATA/AppData/immich /DATA/AppData/immich
/DATA/Gallery/immich /DATA/Gallery/immich

Select both locations, hit Migrate. Choose: Overwrite at destination and Retain originals on source — do not delete the source until verified.

Over the ZimaCube 2 2.5GbE connection, 134 GiB transfers in approximately 10–15 minutes. My old DIY server was stuck on 1GbE — the same transfer would have taken 30–40 minutes. This is the kind of real-world difference that does not show up on a spec sheet but matters every time you move data.

Step 4: Install Immich on the ZimaCube 2

Open the ZimaOS App Store and search for Immich. Critical warning: the App Store may show multiple Immich variants. You must install the exact same variant your source machine uses:

Immich (official ZimaOS/CasaOS app) — use this if that is what you had before

BigBearCasaOS Immich — different docker-compose variables, different postgres credentials, different database name — incompatible with a direct pgdata copy from the official app

🔑 The docker-compose variables — postgres username, password, database name, network mode — are baked into the app definition. Any mismatch between source and destination app variants will prevent Immich from connecting to the restored database. This is the single most common failure point in Immich migrations.

After installation, do not start the app immediately. Immich will detect the existing pgdata directory on first launch and connect to it rather than initializing a new empty database.

Searching for 'immich' application in the ZimaOS / CasaOS App Store during NAS setup

Step 5: Log In With Existing Credentials

Open Immich at http://192.168.x.x:2283 and log in with the same username and password from the source instance. Your full library — albums, faces, people, settings — will be exactly as they were.

Immich application welcome splash screen and getting started button after successful database migration

Step 6: Verify Job Queues

Navigate to Profile → Administration → Job Queues. After a pgdata migration, the database already contains all previously processed results, so most queues should show Active: 0 / Waiting: 0.

If any queue shows a count under Missing, click the Missing button to process only unprocessed assets:

Queue When to Run Missing
Generate Thumbnails If any photos show blank previews
Extract Metadata If assets are missing GPS/location/date
Smart Search If semantic search returns no results
Face Detection If face data appears incomplete

The Migration Stats

Metric Value
Photos migrated 14,505
Videos migrated 925
Total data 134 GiB
Transfer time (2.5GbE) ~12 minutes
Albums preserved All
Face tags preserved All
Shared links preserved All
Data loss Zero

Why the ZimaCube 2 Made This Worth Doing

I did not migrate just to land on the same experience. The ZimaCube 2 brings three upgrades that my old DIY ZimaOS box could not match:

2.5GbE transfers. Photo libraries grow. Every full backup, every large import, every migration benefits from the 2.5× bandwidth over standard gigabit. The ZimaCube 2 dual 2.5GbE means I can saturate a backup while the rest of the network stays responsive.

NVMe storage for the database. Immich PostgreSQL database performs dramatically better on NVMe than spinning rust. Thumbnail generation, smart search queries, face recognition — all of it reads from pgdata. On the ZimaCube 2 NVMe pool, database operations that previously stuttered on HDD are now instant.

6-bay expandability. 134 GiB today. What about next year? The ZimaCube 2 has six SATA bays plus four M.2 slots in the 7th Bay, meaning this photo library can grow for years without hitting a storage wall.

IceWhale ZimaCube 2 6-bay NAS showing front hot-swap drive bays for high-performance self-hosted storage

Migrate your photo library to ZimaCube 2 →

Building your self-hosted photo setup? Read our Personal Cloud Storage Device guide, our Docker & CI/CD on ZimaCube 2 deep dive, and our ZimaCube 2 Pro Unboxing.

Frequently Asked Questions

Can I migrate Immich to the ZimaCube 2 without losing my albums and face tags?

Yes — but you must copy both the photo files and the pgdata directory (PostgreSQL database). The database stores all albums, face vectors, people clusters, and metadata. Moving photos alone gives you files without organization. Copy both directories together, and your library survives intact.

What is the fastest way to transfer Immich data to the ZimaCube 2?

If both machines are on the same LAN and run ZimaOS, use the built-in Files app with LAN Storage mounting. Over the ZimaCube 2 2.5GbE connection, 134 GiB transfers in about 10–15 minutes. For larger libraries or machines on different networks, an external USB drive is the next best option.

Does the Immich App Store version matter when migrating?

Yes — critically. The ZimaOS App Store may show multiple Immich variants (official vs BigBearCasaOS). They use different docker-compose variables — postgres credentials, database names, and network configs are incompatible. Install the exact same variant your source machine uses, or the restored database will not connect.

Do I need to stop Immich on the source before copying?

Yes. A running PostgreSQL instance writes continuously. Copying a live database risks an inconsistent state. Stop Immich on the source machine, copy the folders, then start it on the destination. The source machine can remain off or stay on as a backup until you have verified the migration.

How much storage does Immich need on the ZimaCube 2?

Plan for your photo library size plus room for the PostgreSQL database (which grows with your library), thumbnail cache, and transcoded video versions. A 134 GiB library with 14,500 photos uses roughly 150–160 GiB total with overhead. The ZimaCube 2's six SATA bays give you room to grow.

Zima Campaign Hub

More to Read

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.