SparkBox/Guides/Immich library on wrong disk

Immich Is Saving Your Library to the System Disk Instead of Your Data Pool

You set up Immich, pointed it at a big data drive, and yet your operating-system disk keeps filling up as photos come in. The system partition creeps toward full while the roomy pool you bought for photos stays nearly empty. The cause is almost always the same: the folder Immich actually writes to is decided by a single volume mapping in its Docker Compose file — and that mapping is pointing at a config folder on the system disk, not the data location your installer thinks it configured.

Immich — your own private Google Photos, on your box
Immich — your own private Google Photos, on your box

Rather not hand-edit YAML? SparkBox puts every app's storage on your data pool by design and ships fixes like this in its update stream. See the walkthrough →

The 10-second version: Immich writes its library to whatever host folder is bound to /usr/src/app/upload in the immich-server container. Change that bind mount to a folder on your large data disk, move the existing files, and restart. A PHOTOS_PATH or data-directory variable elsewhere is ignored unless the volume actually references it.

What "the library" means in Immich

Immich stores several kinds of data under one host folder that it mounts at /usr/src/app/upload inside the immich-server and immich-microservices containers. Inside that folder you'll normally see subdirectories like library (your originals), upload (files still being processed), thumbs (thumbnails), encoded-video, and profile. When people say "my Immich library is on the wrong disk," they mean this whole folder tree landed on the system partition.

Jellyfin home screen on a SparkBox server
Jellyfin home screen on a SparkBox server

A quick vocabulary note, because it matters here:

Why this happens: the volume points at a config folder

This is a genuine wiring bug, and it's worth understanding because the fix follows directly from it. In an affected setup, the Immich compose file hardcodes the upload bind mount to a config directory that lives on the system disk — something structurally like:

${SB_ROOT:-/opt/sparkbox}/modules/immich/config/upload:/usr/src/app/upload

Meanwhile the installer seeded a perfectly good data-pool variable — PHOTOS_PATH=${SB_DATA_DIR}/photos — and even added it to the config allowlist. But nothing in the compose file ever references that variable. So Immich dutifully writes to the config folder on the system disk, and the data-pool path just sits there unused.

If that sounds familiar, it's the exact same class of mistake as the Nextcloud-on-system-disk bug that was fixed in SparkBox v1.6.135: an app was configured to store bulk data, the correct destination existed, but the container's volume never pointed to it. On SparkBox this specific Immich mapping fix is in progress with the lead dev — until it ships, the manual fix below works on any Immich install, SparkBox or not.

Gotcha: Changing PHOTOS_PATH, UPLOAD_LOCATION, or any environment variable does nothing on its own if the compose volume line has a hardcoded path. The volume line is authoritative. Always verify it directly.

Fix 1 — Point the upload volume at your data pool

This is the core fix. You're redirecting the one mapping that decides where the library lives.

FileBrowser — your files on your own box, from any browser
FileBrowser — your files on your own box, from any browser
  1. Confirm the current path. Open your Immich docker-compose.yml and find the line ending in :/usr/src/app/upload under the immich-server service (and the same line under immich-microservices if present). The part before the colon is where your photos are going right now.
  2. Stop the stack so nothing is writing while you move data:
    docker compose down
  3. Move the existing library to the data pool. Copy the entire folder — with all subdirectories intact — to a location on your large disk. Copy first, verify, then delete the old copy; don't move-and-hope:
    cp -a /old/config/upload/. /data/photos/
    Use whatever your real old and new paths are. The -a flag preserves permissions and the folder structure, which Immich depends on.
  4. Update both volume lines to the new host path:
    /data/photos:/usr/src/app/upload
    Make sure the immich-server and immich-microservices services use the same host path — they share the library.
  5. Start the stack again:
    docker compose up -d
  6. Verify it took. Upload a test photo, then check that the new file appears under the data-pool folder and that the system disk is no longer growing:
    du -sh /data/photos

Because Immich stores paths relative to the upload root, moving the folder with its structure intact means your existing photos, thumbnails, and encoded videos are all found again — no re-upload, no re-processing from your phone.

Fix 2 — Keep the change from being overwritten by updates

If an app manager regenerates docker-compose.yml on update, your edited line can be reverted, silently sending new photos back to the system disk. Two durable options:

SparkBox Updates page with one-button updating
SparkBox Updates page with one-button updating
  1. Use a compose override. Create a docker-compose.override.yml next to the main file that redefines only the upload volume for the two Immich services. Overrides are merged on top and usually survive regeneration of the base file.
  2. Re-check after every major upgrade. Make "confirm the /usr/src/app/upload mapping still points at the data pool" part of your post-update checklist. A five-second grep saves a full disk later:
    grep upload docker-compose.yml

If the system disk already filled up: a full system partition can stop containers from starting cleanly. Free space first — move the upload folder off the disk as in Fix 1 — before trying to bring the stack back up.

Related bugs fixed in the same batch

The Immich hardware-acceleration toggle and this storage wiring were part of a broader bugfix batch. A few neighbours you may run into on the same box:

Frequently asked

Why is Immich storing my photos on the system disk?

Because the host folder bound to /usr/src/app/upload in the immich-server container lives on your system disk. Immich writes everything there. Any separate "photos path" variable is irrelevant unless that exact volume line uses it.

Where does Immich actually keep the library?

Whatever the host side of the /usr/src/app/upload mapping is. Point it at a folder on your large data disk and that's where the library lives — originals, thumbnails, encoded video and all.

Can I move an existing Immich library without losing photos?

Yes. Stop the stack, copy the whole upload folder with its subfolders to the new disk, update the volume mapping to the new host path, and start again. Immich uses relative paths internally, so it reindexes in place without re-uploading anything.

Will this happen again after an update?

It can if an upgrade regenerates the compose file with the hardcoded path. Use a docker-compose.override.yml for the upload volume, or re-check the mapping after each major update.

Skip the volume-mapping detective work

SparkBox puts Immich's photo library on your data pool by default and ships wiring fixes like this one through its update stream — no YAML archaeology required.

Get SparkBox → Or read the media-server walkthrough →

About this guide: Written and tested by the SparkBox team on a UGREEN DXP4800 Plus and a $7/month Hostinger VPS, both running SparkBox 1.6.380. The causes above are the real ones we've diagnosed in d/sparkbox. If something doesn't match, tell us on YouTube.