immich-app / immich

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

[BUG] `immich-admin` commands all throw error `"DB_USERNAME" is required. "DB_PASSWORD" is required` #3397

Closed mark-monteiro closed 1 year ago

mark-monteiro commented 1 year ago

The bug

All the immich-admin CLI commands throw the following error:

Error: Config validation error: "DB_USERNAME" is required. "DB_PASSWORD" is required

Presumably this is because I am using the Docker secrets support for these variables so I have values set for DB_USERNAME_FILE and DB_PASSWORD_FILE set instead of the normal "DB_USERNAME" and "DB_PASSWORD" values.

The OS that Immich Server is running on

Docker (Ubuntu host)

Version of Immich Server

v1.68.0

Version of Immich Mobile App

N/A

Platform with the issue

Your docker-compose.yml content

version: "3.8"

secrets:
  POSTGRES_USER:
    file: ./secrets/POSTGRES_USER
  POSTGRES_PASSWORD:
    file: ./secrets/POSTGRES_PASSWORD
  REDIS_PASSWORD:
    file: ./secrets/REDIS_PASSWORD

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:v1.68.0
    command: ["start.sh", "immich"]
    user: "${PUID}:${PGID}"
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
    secrets:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - REDIS_PASSWORD
    env_file:
      - .env
      - typesense-credentials.env
    depends_on:
      - redis
      - database
      - typesense
    restart: always

  immich-microservices:
    container_name: immich_microservices
    image: ghcr.io/immich-app/immich-server:v1.68.0
    command: ["start.sh", "microservices"]
    user: "${PUID}:${PGID}"
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      # NOTE: This additional volume mount is required for running as a non-root user
      # See: https://immich.app/docs/FAQ#how-can-i-run-immich-as-a-non-root-user
      - <redacted>:/usr/src/app/.reverse-geocoding-dump
    secrets:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - REDIS_PASSWORD
    env_file:
      - .env
      - typesense-credentials.env
    depends_on:
      - redis
      - database
      - typesense
    restart: always

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:v1.68.0
    user: "${PUID}:${PGID}"
    volumes:
      #- ${UPLOAD_LOCATION}:/usr/src/app/upload
      - <redacted>:/cache
    env_file:
      - .env
    restart: always

  immich-web:
    container_name: immich_web
    image: ghcr.io/immich-app/immich-web:v1.68.0
    user: "${PUID}:${PGID}"
    env_file:
      - .env
    restart: always

  typesense:
    container_name: immich_typesense
    image: typesense/typesense:0.24.1@sha256:9bcff2b829f12074426ca044b56160ca9d777a0c488303469143dd9f8259d4dd
    env_file:
      - typesense-credentials.env
    environment:
      - TYPESENSE_DATA_DIR=/data
    volumes:
      - <redacted>:/data
    restart: always

  redis:
    container_name: immich_redis
    image: redis:6.2.12-alpine
    # Workaround to support Docker secret for Redis password
    # See: https://github.com/docker-library/redis/issues/46#issuecomment-651382298
    command: ["sh", "-c", "redis-server --requirepass \"$$(cat /run/secrets/REDIS_PASSWORD)\""]
    secrets:
      - REDIS_PASSWORD
    restart: always

  database:
    container_name: immich_postgres
    image: postgres:14.8-alpine
    secrets:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
    env_file:
      - .env
    environment:
      POSTGRES_USER_FILE: /run/secrets/POSTGRES_USER
      POSTGRES_PASSWORD_FILE: /run/secrets/POSTGRES_PASSWORD
      POSTGRES_DB: ${DB_DATABASE_NAME}
    volumes:
      - <redacted>:/var/lib/postgresql/data
    restart: always

  immich-proxy:
    container_name: immich_proxy
    image: ghcr.io/immich-app/immich-proxy:v1.68.0
    environment:
      # Make sure these values get passed through from the env file
      - IMMICH_SERVER_URL
      - IMMICH_WEB_URL
    ports:
      - 127.0.0.1:2283:8080
    depends_on:
      - immich-server
      - immich-web
    restart: always

Your .env content

###################################################################################
# Run as non-root user
# See: https://immich.app/docs/FAQ#how-can-i-run-immich-as-a-non-root-user
###################################################################################
PUID=xxxx
PGID=xxxx

###################################################################################
# Database
###################################################################################

DB_HOSTNAME=immich_postgres
DB_USERNAME_FILE="/run/secrets/POSTGRES_USER"
DB_PASSWORD_FILE="/run/secrets/POSTGRES_PASSWORD"
DB_DATABASE_NAME=immich

# Optional Database settings:
# DB_PORT=5432

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

REDIS_HOSTNAME=immich_redis

# REDIS_URL will be used to pass custom options to ioredis.
# Example for Sentinel
# {"sentinels":[{"host":"redis-sentinel-node-0","port":26379},{"host":"redis-sentinel-node-1","port":26379},{"host":"redis-sentinel-node-2","port":26379}],"name":"redis-sentinel"}
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJyZWRpcy1zZW50aW5lbDEiLCJwb3J0IjoyNjM3OX0seyJob3N0IjoicmVkaXMtc2VudGluZWwyIiwicG9ydCI6MjYzNzl9XSwibmFtZSI6Im15bWFzdGVyIn0=

# Optional Redis settings:

# Note: these parameters are not automatically passed to the Redis Container
# to do so, please edit the docker-compose.yml file as well. Redis is not configured
# via environment variables, only redis.conf or the command line

# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_USERNAME=
# REDIS_PASSWORD=
REDIS_PASSWORD_FILE=/run/secrets/REDIS_PASSWORD
# REDIS_SOCKET=

###################################################################################
# Upload File Location
#
# This is the location where uploaded files are stored.
###################################################################################

UPLOAD_LOCATION=xxxx

###################################################################################
# Typesense
###################################################################################
# NOTE: TYPESENSE_API_KEY is included in secrets.env which is not committed to the repo
# TYPESENSE_API_KEY=some-random-text

# TYPESENSE_ENABLED=false
# TYPESENSE_URL uses base64 encoding for the nodes json.
# Example JSON that was used:
# [
#      { 'host': 'typesense-1.example.net', 'port': '443', 'protocol': 'https' },
#      { 'host': 'typesense-2.example.net', 'port': '443', 'protocol': 'https' },
#      { 'host': 'typesense-3.example.net', 'port': '443', 'protocol': 'https' },
#  ]
# TYPESENSE_URL=ha://WwogICAgeyAnaG9zdCc6ICd0eXBlc2Vuc2UtMS5leGFtcGxlLm5ldCcsICdwb3J0JzogJzQ0MycsICdwcm90b2NvbCc6ICdodHRwcycgfSwKICAgIHsgJ2hvc3QnOiAndHlwZXNlbnNlLTIuZXhhbXBsZS5uZXQnLCAncG9ydCc6ICc0NDMnLCAncHJvdG9jb2wnOiAnaHR0cHMnIH0sCiAgICB7ICdob3N0JzogJ3R5cGVzZW5zZS0zLmV4YW1wbGUubmV0JywgJ3BvcnQnOiAnNDQzJywgJ3Byb3RvY29sJzogJ2h0dHBzJyB9LApd

###################################################################################
# Reverse Geocoding
#
# 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=0

####################################################################################
# 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

####################################################################################
# Alternative API's External Address - Optional
#
# This is an advanced feature used to control the public server endpoint returned to clients during Well-known discovery.
# You should only use this if you want mobile apps to access the immich API over a custom URL. Do not include trailing slash.
# NOTE: At this time, the web app will not be affected by this setting and will continue to use the relative path: /api
# Examples: http://localhost:3001, http://immich-api.example.com, etc
####################################################################################

#IMMICH_API_URL_EXTERNAL=http://localhost:3001

Reproduction steps

1. Set up Immich using _FILE environment variables for the database
2. Connect to `immich_server` container
3. Attempt to run any `immich-admin` command
4. See error

Additional information

I've included a more complete console log below:

/usr/src/app $ immich-admin help
/usr/src/app/node_modules/@nestjs/config/dist/config.module.js:75
                throw new Error(`Config validation error: ${error.message}`);
                ^

Error: Config validation error: "DB_USERNAME" is required. "DB_PASSWORD" is required
    at ConfigModule.forRoot (/usr/src/app/node_modules/@nestjs/config/dist/config.module.js:75:23)
    at Object.<anonymous> (/usr/src/app/dist/infra/infra.module.js:49:35)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/usr/src/app/dist/infra/index.js:19:14)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)

Node.js v18.16.0
jrasm91 commented 1 year ago

The implementation for reading env files is in a script file I believe. We should make sure that is true for the admin CLI process as well.