[BUG] Can't run microservices container as non-root user #497

Closed
opened 2026-02-04 20:52:01 +03:00 by OVERLORD · 6 comments
Owner

Originally created by @virusperfect on GitHub (Dec 20, 2022).

Describe the bug
Creating the microservices container doesn't work if the container is run as a non-root user.

Task List

  • I have read thoroughly the README setup and installation instructions.
  • I have included my docker-compose file.
  • I have included my redacted .env file.
  • I have included information on my machine, and environment.

To Reproduce
Steps to reproduce the behavior:

  1. Run microservices container with user: "UID:GID"
  2. The container will keep restarting with the following error message:
Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump/'
    at Object.mkdirSync (node:fs:1349:3)
    at Object.init (/usr/src/app/node_modules/local-reverse-geocoder/index.js:659:10)
    at /usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:62:42
    at new Promise (<anonymous>)
    at geocoderInit (/usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:61:12)
    at new MetadataExtractionProcessor (/usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:83:13)
    at Injector.instantiateClass (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:330:19)
    at callback (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:48:41)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Injector.resolveConstructorParams (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:122:24) {
  errno: -13,
  syscall: 'mkdir',
  code: 'EACCES',
  path: '/usr/src/app/.reverse-geocoding-dump/'
}

Expected behavior
Microservices should run even as non-root user. I thought this issue was solved in #338.

System

  • Server Version: 1.39.0

Additional context

docker-compose

version: "3.8"

services:
  immich-server:
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-server.sh"]
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - redis
      - database
    user: "158:168"
    restart: unless-stopped

  immich-microservices:
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-microservices.sh"]
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - redis
      - database
    user: "158:168"
    restart: unless-stopped

  immich-machine-learning:
    image: altran1502/immich-machine-learning:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - database
    user: "158:168"
    restart: unless-stopped

  immich-web:
    image: altran1502/immich-web:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    env_file:
      - .env
    environment:
      - PUID=158
      - PGID=168
    restart: unless-stopped

  redis:
    container_name: immich_redis
    image: redis:6.2
    restart: unless-stopped

  database:
    container_name: immich_postgres
    image: postgres:14
    env_file:
      - .env
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      PG_DATA: /var/lib/postgresql/data
    volumes:
      - /opt/config/immich/data:/var/lib/postgresql/data
    user: "158:168"
    restart: unless-stopped

  immich-proxy:
    container_name: immich_proxy
    image: altran1502/immich-proxy:release
    ports:
      - 127.0.0.1:2283:8080
    logging:
      driver: none
    depends_on:
      - immich-server
    restart: unless-stopped

.env

DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE_NAME=immich
REDIS_HOSTNAME=immich_redis
UPLOAD_LOCATION=/mnt/nas/backup/immich/upload
LOG_LEVEL=simple
JWT_SECRET=redacted
PUBLIC_LOGIN_PAGE_MESSAGE=
Originally created by @virusperfect on GitHub (Dec 20, 2022). <!-- Note: Please search to see if an issue already exists for the bug you encountered. --> **Describe the bug** Creating the microservices container doesn't work if the container is run as a non-root user. **Task List** - [x] I have read thoroughly the README setup and installation instructions. - [x] I have included my `docker-compose` file. - [x] I have included my redacted `.env` file. - [x] I have included information on my machine, and environment. **To Reproduce** Steps to reproduce the behavior: 1. Run microservices container with `user: "UID:GID"` 2. The container will keep restarting with the following error message: ``` Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump/' at Object.mkdirSync (node:fs:1349:3) at Object.init (/usr/src/app/node_modules/local-reverse-geocoder/index.js:659:10) at /usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:62:42 at new Promise (<anonymous>) at geocoderInit (/usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:61:12) at new MetadataExtractionProcessor (/usr/src/app/dist/apps/microservices/apps/microservices/src/processors/metadata-extraction.processor.js:83:13) at Injector.instantiateClass (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:330:19) at callback (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:48:41) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async Injector.resolveConstructorParams (/usr/src/app/node_modules/@nestjs/core/injector/injector.js:122:24) { errno: -13, syscall: 'mkdir', code: 'EACCES', path: '/usr/src/app/.reverse-geocoding-dump/' } ``` **Expected behavior** Microservices should run even as non-root user. I thought this issue was solved in #338. **System** - Server Version: `1.39.0` **Additional context** ### docker-compose ``` version: "3.8" services: immich-server: image: altran1502/immich-server:release entrypoint: ["/bin/sh", "./start-server.sh"] volumes: - ${UPLOAD_LOCATION}:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - redis - database user: "158:168" restart: unless-stopped immich-microservices: image: altran1502/immich-server:release entrypoint: ["/bin/sh", "./start-microservices.sh"] volumes: - ${UPLOAD_LOCATION}:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - redis - database user: "158:168" restart: unless-stopped immich-machine-learning: image: altran1502/immich-machine-learning:release entrypoint: ["/bin/sh", "./entrypoint.sh"] volumes: - ${UPLOAD_LOCATION}:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - database user: "158:168" restart: unless-stopped immich-web: image: altran1502/immich-web:release entrypoint: ["/bin/sh", "./entrypoint.sh"] env_file: - .env environment: - PUID=158 - PGID=168 restart: unless-stopped redis: container_name: immich_redis image: redis:6.2 restart: unless-stopped database: container_name: immich_postgres image: postgres:14 env_file: - .env environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} PG_DATA: /var/lib/postgresql/data volumes: - /opt/config/immich/data:/var/lib/postgresql/data user: "158:168" restart: unless-stopped immich-proxy: container_name: immich_proxy image: altran1502/immich-proxy:release ports: - 127.0.0.1:2283:8080 logging: driver: none depends_on: - immich-server restart: unless-stopped ``` ### .env ``` DB_HOSTNAME=immich_postgres DB_USERNAME=postgres DB_PASSWORD=postgres DB_DATABASE_NAME=immich REDIS_HOSTNAME=immich_redis UPLOAD_LOCATION=/mnt/nas/backup/immich/upload LOG_LEVEL=simple JWT_SECRET=redacted PUBLIC_LOGIN_PAGE_MESSAGE= ```
Author
Owner

@alextran1502 commented on GitHub (Dec 20, 2022):

@zoodyy Am I understanding correctly that the GUID and UID only work with the mounted volume and don't apply to the auto-downloaded files for reverse geocoding?

@alextran1502 commented on GitHub (Dec 20, 2022): @zoodyy Am I understanding correctly that the GUID and UID only work with the mounted volume and don't apply to the auto-downloaded files for reverse geocoding?
Author
Owner

@fyfrey commented on GitHub (Dec 21, 2022):

@alextran1502 yes. You need to mount an external folder with the right access rights. So, running as non-root works fine. But certainly not out of the box because our images are not read-only (i.e. microservices writes to the container..) to workaround, follow my guide here: https://github.com/immich-app/immich/issues/776#issuecomment-1271459885

@fyfrey commented on GitHub (Dec 21, 2022): @alextran1502 yes. You need to mount an external folder with the right access rights. So, running as non-root works fine. But certainly not out of the box because our images are not read-only (i.e. microservices writes to the container..) to workaround, follow my guide here: https://github.com/immich-app/immich/issues/776#issuecomment-1271459885
Author
Owner

@virusperfect commented on GitHub (Dec 21, 2022):

Thank you that worked.

@virusperfect commented on GitHub (Dec 21, 2022): Thank you that worked.
Author
Owner

@bt90 commented on GitHub (Dec 30, 2022):

https://github.com/immich-app/immich/pull/1234 changes the folder to an anonymous volume which should fix this. Feel free to test 😉

@bt90 commented on GitHub (Dec 30, 2022): https://github.com/immich-app/immich/pull/1234 changes the folder to an anonymous volume which should fix this. Feel free to test 😉
Author
Owner

@bt90 commented on GitHub (Dec 30, 2022):

Changing the volumes of the microservice in your docker-compose.yml should be enough:

    volumes:
      - /usr/src/app/.reverse-geocoding-dump
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
@bt90 commented on GitHub (Dec 30, 2022): Changing the volumes of the microservice in your docker-compose.yml should be enough: ```yml volumes: - /usr/src/app/.reverse-geocoding-dump - ${UPLOAD_LOCATION}:/usr/src/app/upload ```
Author
Owner

@dpantel commented on GitHub (Nov 8, 2023):

The error still seems to be there in v1.85.0

immich_microservices     | [Nest] 7  - 11/08/2023, 4:35:14 PM   ERROR [MetadataService] Unable to initialize reverse geocoding: Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump//cities500'
immich_microservices     | Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump//cities500'
immich_microservices     |     at Object.mkdirSync (node:fs:1379:3)
immich_microservices     |     at Object._getData (/usr/src/app/node_modules/local-reverse-geocoder/index.js:163:10)
immich_microservices     |     at Object._getGeoNamesCitiesData (/usr/src/app/node_modules/local-reverse-geocoder/index.js:468:10)
immich_microservices     |     at nextTask (/usr/src/app/node_modules/async/dist/async.js:5789:13)
immich_microservices     |     at Object.waterfall (/usr/src/app/node_modules/async/dist/async.js:5800:9)
immich_microservices     |     at Object.awaitable [as waterfall] (/usr/src/app/node_modules/async/dist/async.js:211:32)
immich_microservices     |     at /usr/src/app/node_modules/local-reverse-geocoder/index.js:682:19
immich_microservices     |     at /usr/src/app/node_modules/async/dist/async.js:3674:28
immich_microservices     |     at eachOfArrayLike (/usr/src/app/node_modules/async/dist/async.js:506:13)
immich_microservices     |     at eachOf (/usr/src/app/node_modules/async/dist/async.js:626:16)
@dpantel commented on GitHub (Nov 8, 2023): The error still seems to be there in v1.85.0 ```` immich_microservices | [Nest] 7 - 11/08/2023, 4:35:14 PM ERROR [MetadataService] Unable to initialize reverse geocoding: Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump//cities500' immich_microservices | Error: EACCES: permission denied, mkdir '/usr/src/app/.reverse-geocoding-dump//cities500' immich_microservices | at Object.mkdirSync (node:fs:1379:3) immich_microservices | at Object._getData (/usr/src/app/node_modules/local-reverse-geocoder/index.js:163:10) immich_microservices | at Object._getGeoNamesCitiesData (/usr/src/app/node_modules/local-reverse-geocoder/index.js:468:10) immich_microservices | at nextTask (/usr/src/app/node_modules/async/dist/async.js:5789:13) immich_microservices | at Object.waterfall (/usr/src/app/node_modules/async/dist/async.js:5800:9) immich_microservices | at Object.awaitable [as waterfall] (/usr/src/app/node_modules/async/dist/async.js:211:32) immich_microservices | at /usr/src/app/node_modules/local-reverse-geocoder/index.js:682:19 immich_microservices | at /usr/src/app/node_modules/async/dist/async.js:3674:28 immich_microservices | at eachOfArrayLike (/usr/src/app/node_modules/async/dist/async.js:506:13) immich_microservices | at eachOf (/usr/src/app/node_modules/async/dist/async.js:626:16) ````
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#497