immich-app / immich

High performance self-hosted photo and video management solution.
https://immich.app
GNU Affero General Public License v3.0
46.39k stars 2.3k forks source link

[BUG] Facial recognition does not work - incorrect file path #2512

Closed Maulwurf16 closed 1 year ago

Maulwurf16 commented 1 year ago

The bug

Hello together,

I installed immich on my Synology NAS 920+ with Portainer based on this tutorial: Link

It is a quite standard Docker installation with the standard immich env. File.

Everything works absolutely fine -except for the image recognition.

immich-microservices throws the following output:

[Nest] 1  - 05/22/2023, 8:35:52 AM   ERROR [FacialRecognitionService] Unable run facial recognition pipeline: 62dd6c44-6f5d-4b3a-8c94-17ecf419c238
Error: Request failed with status code 500
    at createError (/usr/src/app/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/usr/src/app/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/usr/src/app/node_modules/axios/lib/adapters/http.js:322:11)
    at IncomingMessage.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

immich-learning throws the following output:

ValueError: Incorrect path or url, URLs must start with `http://` or `https://`, and upload/thumbs/61ec5320-1d8a-4421-a0d8-cc4f0e70d5e5/62dd6c44-6f5d-4b3a-8c94-17ecf419c238.jpeg is not a valid path
[ WARN:6@5301.043] global loadsave.cpp:244 findDecoder imread_('upload/thumbs/61ec5320-1d8a-4421-a0d8-cc4f0e70d5e5/62dd6c44-6f5d-4b3a-8c94-17ecf419c238.jpeg'): can't open/read file: check file path/integrity
INFO:     [172.29.0.7:50792](http://172.29.0.7:50792/) - "POST /facial-recognition/detect-faces HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await [self.app](http://self.app/)(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/fastapi/applications.py", line 276, in __call__
    await super().__call__(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/opt/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await [self.app](http://self.app/)(scope, receive, _send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/opt/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await [self.app](http://self.app/)(scope, receive, sender)
  File "/opt/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/opt/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await [self.app](http://self.app/)(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
    await [self.app](http://self.app/)(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
  File "/opt/venv/lib/python3.10/site-packages/fastapi/routing.py", line 237, in app
    raw_response = await run_endpoint_function(
  File "/opt/venv/lib/python3.10/site-packages/fastapi/routing.py", line 165, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
  File "/opt/venv/lib/python3.10/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
    return await [anyio.to](http://anyio.to/)_[thread.run](http://thread.run/)_sync(func, *args)
  File "/opt/venv/lib/python3.10/site-packages/anyio/to_thread.py", line 31, in run_sync
    return await get_asynclib().run_sync_in_worker_thread(
  File "/opt/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
    return await future
  File "/opt/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 867, in run
    result = [context.run](http://context.run/)(func, *args)
  File "/usr/src/app/src/[main.py](http://main.py/)", line 92, in facial_recognition
    height, width, _ = img.shape
AttributeError: 'NoneType' object has no attribute 'shape'

The thing is: the file: upload/thumbs/61ec5320-1d8a-4421-a0d8-cc4f0e70d5e5/62dd6c44-6f5d-4b3a-8c94-17ecf419c238.jpeg exists - I can navigate to it in my folder path and everything else on the immich installation works just absolutely fine (including tagging, uploading, deleting, etc...)

The OS that Immich Server is running on

DSM 7.1.1-42962 Update 5

Version of Immich Server

v1.56.2

Version of Immich Mobile App

v1.56.0 build.96

Platform with the issue

Your docker-compose.yml content

version: "3.9"
services:
  immich-redis:
    image: redis
    container_name: Immich-redis
    hostname: immich-redis
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping || exit 1"]
    user: 1026:100
    environment:
      - TZ=Europe/Berlin
    volumes:
      - /volume1/docker/immich/redis:/data
    restart: always

  immich-db:
    image: postgres
    container_name: Immich-db
    hostname: immich-db
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "immich", "-U", "immichuser"]
      interval: 10s
      timeout: 5s
      retries: 5
    user: 1026:100
    volumes:
      - /volume1/docker/immich/db:/var/lib/postgresql/data
    environment:
      - TZ=Europe/Berlin
      - POSTGRES_DB=immich
      - POSTGRES_USER=immichuser
      - POSTGRES_PASSWORD=immichpw
    restart: always

  immich-server:
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-server.sh"]
    container_name: Immich-server
    hostname: immich-server
    user: 1026:100
    security_opt:
      - no-new-privileges:true
    env_file:
      - stack.env
    volumes:
      - /volume1/docker/immich/upload:/usr/src/app/upload
    restart: always
    depends_on:
      immich-redis:
        condition: service_healthy
      immich-db:
        condition: service_started
      typesense:
        condition: service_started

  immich-microservices:
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-microservices.sh"]
    container_name: Immich-microservices
    hostname: immich-microservices
    user: 1026:100
    security_opt:
      - no-new-privileges:true
    env_file:
      - stack.env
    volumes:
      - /volume1/docker/immich/upload:/usr/src/app/upload
      - /volume1/docker/immich/micro:/usr/src/app/.reverse-geocoding-dump
    restart: always
    depends_on:
      immich-redis:
        condition: service_healthy
      immich-db:
        condition: service_started
      typesense:
        condition: service_started

  immich-machine-learning:
    image: altran1502/immich-machine-learning:release
    container_name: Immich-learning
    hostname: immich-machine-learning
    user: 1026:100
    security_opt:
      - no-new-privileges:true
    env_file:
      - stack.env
    volumes:
      - /volume1/docker/immich/data:/usr/src/app/upload
      - /volume1/docker/immich/cache:/cache
    restart: always
    depends_on:
      immich-db:
        condition: service_started

  immich-web:
    image: altran1502/immich-web:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    container_name: Immich-web
    hostname: immich-web
    user: 1026:100
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
    env_file:
      - stack.env
    restart: always
    depends_on:
      - immich-server

  immich-proxy:
    image: altran1502/immich-proxy:release
    logging:
      driver: none
    container_name: Immich-proxy
    hostname: immich-proxy
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: curl -f http://localhost:8080/ || exit 1
    environment:
      - IMMICH_SERVER_URL=http://immich-server:3001
      - IMMICH_WEB_URL=http://immich-web:3000
    ports:
      - 8212:8080
    restart: always
    depends_on:
      - immich-server

  typesense:
    container_name: immich_typesense
    image: typesense/typesense:0.24.0
    environment:
      - TYPESENSE_API_KEY=MariushostingMariushostingMari13
      - TYPESENSE_DATA_DIR=/data
    logging:
      driver: none
    volumes:
      - /volume1/docker/immich/typesense:/data
    restart: always

Your .env content

NODE_ENV=production
TZ=Europe/Berlin
TYPESENSE_API_KEY=MariushostingMariushostingMari13
###################################################################################
# Database
###################################################################################

DB_HOSTNAME=immich-db
DB_USERNAME=immichuser
DB_PASSWORD=immichpw
DB_DATABASE_NAME=immich

# Optional Database settings:
# DB_PORT=5432

###################################################################################
# Redis
###################################################################################

REDIS_HOSTNAME=immich-redis

# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=

###################################################################################
# Log message level - [simple|verbose]
###################################################################################

LOG_LEVEL=simple

###################################################################################
# JWT SECRET
###################################################################################

# This JWT_SECRET is used to sign the authentication keys for user login
# You should set it to a long randomly generated value
# You can use this command to generate one: openssl rand -base64 128
JWT_SECRET=xia7jNMRT50PgcShC0BTuFxTLPamoYnQO8OKH8jUff4iD0AdtbC8HTZp/Rv4LSdpV7kXbYTvxNrw24NzJJiag2nisYbUmEV8XbJEEboag98z+6KR5djhPPC4/oztoSJHOB2rpPXjv4VNwCAT0PvTKUo3gSY8rDja85DGugYqJ0c=

###################################################################################
# Reverse Geocoding
####################################################################################

# DISABLE_REVERSE_GEOCODING=false

# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
# 3 - Cities > 500 population: ~200MB RAM
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM

DISABLE_REVERSE_GEOCODING=false
REVERSE_GEOCODING_PRECISION=3

####################################################################################
# WEB - Optional
####################################################################################

# Custom message on the login page, should be written in HTML form.
# For example PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"

PUBLIC_LOGIN_PAGE_MESSAGE=

####################################################################################
# Alternative Service Addresses - Optional
#
# This is an advanced feature for users who may be running their immich services on different hosts.
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
# Note: immich-microservices is bound to 3002, but no references are made
####################################################################################

IMMICH_WEB_URL=http://immich-web:3000
IMMICH_SERVER_URL=http://immich-server:3001
IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003

####################################################################################
# OAuth Setting - Optional
#
# These setting will enable OAuth login for your instance of Immich
# Folow the instructions in the page https://immich.app/docs/usage/oauth to set up your OAuth provider
####################################################################################

# OAUTH_ENABLED=false
# OAUTH_ISSUER_URL=
# OAUTH_CLIENT_ID=
# OAUTH_CLIENT_SECRET=
# OAUTH_BUTTON_TEXT=Login with OAuth
# OAUTH_AUTO_REGISTER=true
# OAUTH_SCOPE="openid profile email"

Reproduction steps

1. Use Synology 920+ with DSM 7.1.1-42962 Update 5 
2. Install Immich via Portainer and Docker [Link](https://mariushosting.com/how-to-install-immich-on-your-synology-nas/)
3. Try to use facial recognition
...

Additional information

No response

bo0tzz commented 1 year ago

You have the wrong path mounted for the upload folder of the machine learning container.

Maulwurf16 commented 1 year ago

oh my.... Thank you so much.

In German there is a saying: "Sometimes you don't see the forest due to all of the trees."

For anyone reading this. I corrected the part of the "immich-machine-learning" and now it works like a charm:

changed: