Moving from no storage template to storage template - migration job leaves thousands of empty folders #3042

Closed
opened 2026-02-05 07:31:52 +03:00 by OVERLORD · 0 comments
Owner

Originally created by @chris114782 on GitHub (May 1, 2024).

The bug

I've just used a storage template for the first time, migrating from no storage template.

I added the storage template, clicked save and triggered the storage template migration job.

This has worked fine, and all of my photos now use the storage template, however the upload directory is now left with 44924 empty directories, looking like:

chris@puddin /mnt/storage/immich/library/upload $ find . -type d -empty
...
./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/10
./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/89
./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/ed
./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/bc
...
chris@puddin /mnt/storage/immich/library/upload $ find . -type d -empty | wc -l
44924

Is this expected behavior or a bug in the migration? If it is expected, can I safely clear these empty folders out?

The OS that Immich Server is running on

Ubuntu 22.04 (Docker)

Version of Immich Server

v1.103.1

Version of Immich Mobile App

not in use

Platform with the issue

  • Server
  • Web
  • Mobile

Your docker-compose.yml content

name: immich

services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.immich.entrypoints=secure"
      - "traefik.http.routers.immich.rule=Host(`photos.redacted.tld`)"
      - "traefik.http.services.immich.loadbalancer.server.port=3001"
    command: ['start.sh', 'immich']
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    depends_on:
      - redis
      - database
    restart: always
    networks:
      - photos
      - ingress

  immich-microservices:
    container_name: immich_microservices
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: quicksync
    command: ['start.sh', 'microservices']
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    depends_on:
      - redis
      - database
    restart: always
    networks:
      - photos

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-openvino
    extends:
      file: hwaccel.ml.yml
      service: openvino
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
      - photos
 
  redis:
    container_name: immich_redis
    image: registry.hub.docker.com/library/redis:6.2-alpine@sha256:84882e87b54734154586e5f8abd4dce69fe7311315e2fc6d67c29614c8de2672
    restart: always
    networks:
      - photos

  database:
    container_name: immich_postgres
    image: registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    restart: always
    networks:
      - photos

  db_backup:
    image: prodrigestivill/postgres-backup-local:14
    user: 1001:1001
    restart: always
    env_file:
      - .env
    environment:
      POSTGRES_HOST: database
      POSTGRES_CLUSTER: 'TRUE'
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      SCHEDULE: '@daily'
      POSTGRES_EXTRA_OPTS: '--clean --if-exists'
      BACKUP_DIR: /backups/immich_db_dumps
      TZ: Europe/London
    volumes:
      - backups:/backups
    depends_on:
    networks:
      - photos

volumes:
  model-cache:
  backups:
    external: true

networks:
  ingress:
    external: true
  photos:
    driver: bridge

Your .env content

# The location where your uploaded files are stored
UPLOAD_LOCATION=/mnt/storage/immich/library

# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release

DB_PASSWORD=redacted
DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
DB_DATA_LOCATION=/mnt/ssdstorage/immich/database

REDIS_HOSTNAME=immich_redis


### Reproduction steps

```bash
1. Upload a bunch of photos to immich with storage templates turned off.
2. Enable a storage template (I used `{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}`)
3. Trigger the storage migration job

Relevant log output

No response

Additional information

No response

Originally created by @chris114782 on GitHub (May 1, 2024). ### The bug I've just used a storage template for the first time, migrating from no storage template. I added the storage template, clicked save and triggered the storage template migration job. This has worked fine, and all of my photos now use the storage template, however the upload directory is now left with 44924 empty directories, looking like: ``` chris@puddin /mnt/storage/immich/library/upload $ find . -type d -empty ... ./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/10 ./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/89 ./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/ed ./1cf3d6dd-3e2e-4db3-ba35-4dbc6a726495/35/bc ... chris@puddin /mnt/storage/immich/library/upload $ find . -type d -empty | wc -l 44924 ``` Is this expected behavior or a bug in the migration? If it is expected, can I safely clear these empty folders out? ### The OS that Immich Server is running on Ubuntu 22.04 (Docker) ### Version of Immich Server v1.103.1 ### Version of Immich Mobile App not in use ### Platform with the issue - [X] Server - [ ] Web - [ ] Mobile ### Your docker-compose.yml content ```YAML name: immich services: immich-server: image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} labels: - "traefik.enable=true" - "traefik.http.routers.immich.entrypoints=secure" - "traefik.http.routers.immich.rule=Host(`photos.redacted.tld`)" - "traefik.http.services.immich.loadbalancer.server.port=3001" command: ['start.sh', 'immich'] volumes: - ${UPLOAD_LOCATION}:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro env_file: - .env depends_on: - redis - database restart: always networks: - photos - ingress immich-microservices: container_name: immich_microservices image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} extends: file: hwaccel.transcoding.yml service: quicksync command: ['start.sh', 'microservices'] volumes: - ${UPLOAD_LOCATION}:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro env_file: - .env depends_on: - redis - database restart: always networks: - photos immich-machine-learning: container_name: immich_machine_learning image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-openvino extends: file: hwaccel.ml.yml service: openvino volumes: - model-cache:/cache env_file: - .env restart: always - photos redis: container_name: immich_redis image: registry.hub.docker.com/library/redis:6.2-alpine@sha256:84882e87b54734154586e5f8abd4dce69fe7311315e2fc6d67c29614c8de2672 restart: always networks: - photos database: container_name: immich_postgres image: registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} volumes: - ${DB_DATA_LOCATION}:/var/lib/postgresql/data restart: always networks: - photos db_backup: image: prodrigestivill/postgres-backup-local:14 user: 1001:1001 restart: always env_file: - .env environment: POSTGRES_HOST: database POSTGRES_CLUSTER: 'TRUE' POSTGRES_USER: ${DB_USERNAME} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_DATABASE_NAME} SCHEDULE: '@daily' POSTGRES_EXTRA_OPTS: '--clean --if-exists' BACKUP_DIR: /backups/immich_db_dumps TZ: Europe/London volumes: - backups:/backups depends_on: networks: - photos volumes: model-cache: backups: external: true networks: ingress: external: true photos: driver: bridge ``` ### Your .env content ```Shell # The location where your uploaded files are stored UPLOAD_LOCATION=/mnt/storage/immich/library # The Immich version to use. You can pin this to a specific version like "v1.71.0" IMMICH_VERSION=release DB_PASSWORD=redacted DB_HOSTNAME=immich_postgres DB_USERNAME=postgres DB_DATABASE_NAME=immich DB_DATA_LOCATION=/mnt/ssdstorage/immich/database REDIS_HOSTNAME=immich_redis ``` ``` ### Reproduction steps ```bash 1. Upload a bunch of photos to immich with storage templates turned off. 2. Enable a storage template (I used `{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}`) 3. Trigger the storage migration job ``` ### Relevant log output _No response_ ### Additional information _No response_
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#3042