Skip to content

Environment variables

Most Frameleaf settings live in the web app. A few are set as environment variables instead, usually in the .env file next to your docker-compose.yml. This page lists them all.

In the tables, Containers says which container reads the variable: the server, the machine learning container or the database. If you split the server into separate api and microservices workers, give each the variables it needs.

These are used by docker-compose.yml itself and don’t reach the containers directly.

Variable What it does Default
UPLOAD_LOCATION Folder on the host where your photos and videos are stored ./library in the example file
DB_DATA_LOCATION Folder on the host for the database. Network shares aren’t supported ./postgres in the example file
FRAMELEAF_VERSION Which image tag to run. Release bundles pin this to their version release

The Compose files use ${FRAMELEAF_VERSION:-${IMMICH_VERSION:-release}}, so an older .env with IMMICH_VERSION still picks the tag when FRAMELEAF_VERSION isn’t set.

Variable What it does Default Containers
TZ Time zone, for example Etc/UTC. Used for log times, scheduled jobs, and photos whose metadata has no time zone server
FRAMELEAF_ENV production or development production server, machine learning
FRAMELEAF_LOG_LEVEL verbose, debug, log, warn or error log server, machine learning
FRAMELEAF_LOG_FORMAT console or json console server
FRAMELEAF_MEDIA_LOCATION Media folder inside the container. You almost certainly shouldn’t set this /data server
FRAMELEAF_CONFIG_FILE Path to a config file inside the container server
FRAMELEAF_HELMET_FILE Path to a JSON file of security header options. true uses the built-in file, false turns it off false server
NO_COLOR Set to true to turn off coloured log output false server, machine learning
CPU_CORES Number of CPU cores available to the server detected server
FRAMELEAF_PROCESS_INVALID_IMAGES When true, make thumbnails for images that fail validation server
FRAMELEAF_TRUSTED_PROXIES Comma-separated IPs of reverse proxies to trust server
FRAMELEAF_IGNORE_MOUNT_CHECK_ERRORS Start even when the storage folder checks fail. Only for troubleshooting server
FRAMELEAF_IMPORT_ROOTS Comma-separated folders administrators may import Google Photos Takeout exports from server
FRAMELEAF_ALLOW_SETUP Set to false to turn off the admin sign-up and start-restore endpoints true server

Set UPLOAD_LOCATION, not FRAMELEAF_MEDIA_LOCATION. The second is the path inside the container, and pointing it at a host folder will break things.

Variable What it does Default Containers
FRAMELEAF_HOST Address to listen on 0.0.0.0 server, machine learning
FRAMELEAF_PORT Port to listen on 2283 (server), 3003 (machine learning) server, machine learning
Variable What it does Default Containers
DB_URL Full connection string. Replaces the separate values below server
DB_HOSTNAME Database host database server
DB_PORT Database port 5432 server
DB_USERNAME Database user postgres server, database
DB_PASSWORD Database password. Use only letters and numbers postgres server, database
DB_DATABASE_NAME Database name immich server, database
DB_SSL_MODE Database SSL mode server
DB_VECTOR_EXTENSION vectorchord or pgvector. Detected automatically when not set server
DB_SKIP_MIGRATIONS Skip database migrations at startup, for restores false server
DB_STORAGE_TYPE Set to HDD if the database isn’t on an SSD SSD database

DB_USERNAME, DB_PASSWORD and DB_DATABASE_NAME are passed to the database container as POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB. The database is still called immich by default, so existing installs keep working.

DB_URL looks like postgresql://user:password@host:port/database. Add ?sslmode=require to require SSL, or ?sslmode=require&uselibpqcompat=true to require SSL without checking the certificate. When DB_URL is set, DB_HOSTNAME, DB_PORT, DB_USERNAME, DB_PASSWORD and DB_DATABASE_NAME are ignored.

DB_STORAGE_TYPE mainly controls how many disk reads Postgres makes at once. We recommend keeping the database on an SSD where possible. All DB_ variables must be given to every server worker.

Variable What it does Default
REDIS_URL Full Redis address: ioredis:// followed by base64-encoded JSON configuration
REDIS_SOCKET Redis socket
REDIS_HOSTNAME Redis host redis
REDIS_PORT Redis port 6379
REDIS_USERNAME Redis username
REDIS_PASSWORD Redis password
REDIS_DBINDEX Redis database index 0

When REDIS_URL or REDIS_SOCKET is set, the other Redis variables are ignored. All REDIS_ variables must be given to every server worker. For Redis Sentinel, encode JSON like this as base64:

{
"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"
}
Variable What it does Default
FRAMELEAF_CLOUD_URL Set to https://api.frameleaf.cloud to use Frameleaf Cloud. Left unset, nothing is ever contacted
FRAMELEAF_PUSH_URL Set to https://push.frameleaf.cloud for push notifications to the Frameleaf apps
FRAMELEAF_IDENTITY_DIR Folder holding the server’s identity key. Must be persistent storage <media>/frameleaf/identity
FRAMELEAF_LINK_TOKEN Single-use token (fll_…) that links the server to your Frameleaf account at startup, without a browser
FRAMELEAF_SETUP_CODE Pins the setup code a new server asks for, for automated installs and tests
FRAMELEAF_EDGE_PORT Port for direct remote access 2443
FRAMELEAF_EDGE_BIND Address the direct remote access listener binds to 0.0.0.0
FRAMELEAF_ACME_DIRECTORY_URL Where certificates come from. Only for Let’s Encrypt staging or a test certificate authority Let’s Encrypt
FRAMELEAF_TRUSTED_LAN_CIDRS Extra networks, as comma-separated CIDRs, that count as home besides private ranges
FRAMELEAF_EDGE_SECRET Shared secret between the server and the remote access listener. Set it only when the listener runs in another container, to the same value in both generated each start
FRAMELEAF_LOCAL_URL The server’s address on your home network, offered to visitors on the same network

Create a link token in your Frameleaf account under Servers, then Add server. It works once and expires within an hour. Remove it from .env once the server shows as linked. A malformed token, port or network stops the server at startup. See Frameleaf Cloud account.

Variable What it does Default
FRAMELEAF_RECOVERY_ROOTS Folders Library Care may search for exact copies of missing files, as Label=/path;Label=/path. Only ever read

Each entry is an absolute path inside the container, optionally labelled. A copy found there is copied into library storage before the item is relinked to it.

These let your server offer its own signed builds of the Frameleaf apps.

Variable What it does
FRAMELEAF_ANDROID_RELEASE_URL HTTPS folder holding your signed Android APKs. {version} is replaced with the server version
FRAMELEAF_ANDROID_APP_ID Android package ID the APKs are signed as
FRAMELEAF_ANDROID_SIGNING_SHA256 SHA-256 fingerprint of the signing certificate, shown before people install
FRAMELEAF_IOS_APP_URL HTTPS App Store or TestFlight page of the iPhone app
FRAMELEAF_ANDROID_STORE_URL HTTPS store listing of the Android app, offered next to the APKs

The folder must contain app-arm64-v8a-release.apk, app-armeabi-v7a-release.apk, app-x86_64-release.apk and app-release.apk. Android downloads and Obtainium setup are only offered when all three Android variables are set, and a value that’s set but invalid stops the server at startup. Include {version} in the folder so Obtainium recognises each new release.

Variable What it does
FRAMELEAF_DOCS_URL HTTPS address of your installation’s documentation
FRAMELEAF_SUPPORT_URL HTTPS address where people get help with your installation
FRAMELEAF_BUG_FEATURE_URL HTTPS address for reporting problems and requesting features
FRAMELEAF_SOURCE_URL HTTPS address of the source code your installation runs

Help, settings and sign-in pages only show these links when they’re set. A value that isn’t an HTTPS address, or that contains a user name or password, stops the server at startup. The older IMMICH_THIRD_PARTY_DOCUMENTATION_URL, IMMICH_THIRD_PARTY_SUPPORT_URL, IMMICH_THIRD_PARTY_BUG_FEATURE_URL and IMMICH_THIRD_PARTY_SOURCE_URL still work when the Frameleaf name isn’t set, but only an HTTPS value is used.

Variable What it does
FRAMELEAF_WORKERS_INCLUDE Only run these workers
FRAMELEAF_WORKERS_EXCLUDE Don’t run these workers

See Workers and where jobs run.

Variable What it does Default
FRAMELEAF_SHUTDOWN_GRACE_SECONDS How long running jobs and requests get to finish when the server stops. Jobs still running then go back to waiting 5
FRAMELEAF_SHUTDOWN_DEADLINE_SECONDS When the server exits, whatever is still running. Must be greater than the grace period 9

Both must be positive, and the grace period must end before the deadline, or the server won’t start. Docker kills the container when its stop timeout ends, so stop_grace_period in docker-compose.yml must be longer than the deadline. The supplied Compose files and NAS packages use 10 seconds, which fits the defaults.

Variable What it does Default
MACHINE_LEARNING_MODEL_TTL Seconds of inactivity before a model is unloaded from memory. 0 or less turns this off 300
MACHINE_LEARNING_MODEL_TTL_POLL_S Seconds between checks of the model TTL 10
MACHINE_LEARNING_CACHE_FOLDER Folder models are downloaded to /cache
MACHINE_LEARNING_MODEL_SOURCE_URL Where smart search, face and text recognition models download from https://models.frameleaf.cloud
MACHINE_LEARNING_MODEL_SOURCE_TOKEN Token sent to a custom model source that needs one. Never logged
MACHINE_LEARNING_REQUEST_THREADS Threads handling requests. Start here when tuning number of CPU cores
MACHINE_LEARNING_MODEL_INTER_OP_THREADS Model operations run in parallel 1
MACHINE_LEARNING_MODEL_INTRA_OP_THREADS Threads for each model operation 2
MACHINE_LEARNING_WORKERS Worker processes. Each one loads its own copy of the models, so only raise this with plenty of memory 1
MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S HTTP keep-alive time in seconds 2
MACHINE_LEARNING_WORKER_TIMEOUT Seconds a worker may be unresponsive before it’s restarted 300 (900 with ROCm)
MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL Smart search text models to load at startup, comma-separated
MACHINE_LEARNING_PRELOAD__CLIP__VISUAL Smart search image models to load at startup
MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION Face recognition models to load at startup
MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION Face detection models to load at startup
MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION Text recognition models to load at startup
MACHINE_LEARNING_PRELOAD__OCR__DETECTION Text detection models to load at startup
MACHINE_LEARNING_DEVICE_IDS GPU IDs to use on a multi-GPU machine. Needs MACHINE_LEARNING_WORKERS above 1; each worker gets one device in turn 0
MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION Faces processed at once none (1 with OpenVINO)
MACHINE_LEARNING_MAX_BATCH_SIZE__OCR Text boxes processed at once 6
MACHINE_LEARNING_MODEL_ARENA Pre-allocates CPU memory to avoid fragmentation true
MACHINE_LEARNING_ANN Use ARM NN acceleration if supported True
MACHINE_LEARNING_ANN_FP16_TURBO Faster, less precise FP16 maths (ARM NN only) False
MACHINE_LEARNING_ANN_TUNING_LEVEL ARM NN GPU tuning: 1 rapid, 2 normal, 3 exhaustive 2
MACHINE_LEARNING_RKNN Use RKNN acceleration if supported True
MACHINE_LEARNING_RKNN_THREADS RKNN runtime threads 1
MACHINE_LEARNING_OPENVINO_PRECISION FP16 for faster, less accurate OpenVINO inference, or FP32 FP32
HF_ENDPOINT Your own model mirror. Also used for AI description and NSFW models
HF_HUB_OFFLINE Set to 1 to stop downloads once you’ve filled the model cache yourself

Only the smart search text model is needed for searching. If first searches are slow because uploads load the other models at the same moment, preload the image, face and text models as well, if you have the memory.

Smart search, face and text recognition models download from MACHINE_LEARNING_MODEL_SOURCE_URL if it’s set, otherwise from HF_ENDPOINT if that’s set, otherwise from Frameleaf’s model mirror at https://models.frameleaf.cloud. The container logs which source it uses at startup. The source uses the Hugging Face folder layout, so you can point it at your own mirror or an offline copy. If the source doesn’t have a model you choose, loading fails with an error naming the model and the source; it never falls back to another host. A Hugging Face token (HF_TOKEN) is only sent to huggingface.co.

AI description and NSFW detection models download from huggingface.co unless you set HF_ENDPOINT. To keep them off huggingface.co, point HF_ENDPOINT at your own mirror, or fill the model cache yourself and set HF_HUB_OFFLINE=1.

No usage statistics are sent to any host.

DB_HOSTNAME, DB_DATABASE_NAME, DB_USERNAME, DB_PASSWORD, DB_URL and REDIS_PASSWORD can be read from files instead, using Docker secrets or systemd credentials. Either:

  • add _FILE to the name, for example DB_PASSWORD_FILE, and set it to the path of a file that contains the value, or
  • set CREDENTIALS_DIRECTORY to a folder of files named after the variables. With Docker secrets, CREDENTIALS_DIRECTORY=/run/secrets uses every secret present.

Telemetry and metrics are permanently disabled in Frameleaf. IMMICH_TELEMETRY_INCLUDE, IMMICH_TELEMETRY_EXCLUDE, IMMICH_API_METRICS_PORT and IMMICH_MICROSERVICES_METRICS_PORT are accepted so old .env files still start, but they do nothing and open no port. OTEL_* variables can’t turn telemetry back on either.

Each old IMMICH_ variable that still does something has a FRAMELEAF_ name, and the old name keeps working as an alias. An .env written for Immich keeps working after you switch images. See Moving from Immich.

  • If both names are set to different values, the server (or machine learning container, or CLI) refuses to start and names the pair.
  • At startup, one warning lists the old names in use with their new names.
  • An empty value counts as unset.
  • The old names keep working for the whole of the current major version, and stop working in the next major release. No date is set for that release.
Old name Use instead
IMMICH_VERSION FRAMELEAF_VERSION
IMMICH_ENV FRAMELEAF_ENV
IMMICH_LOG_LEVEL FRAMELEAF_LOG_LEVEL
IMMICH_LOG_FORMAT FRAMELEAF_LOG_FORMAT
IMMICH_MEDIA_LOCATION FRAMELEAF_MEDIA_LOCATION
IMMICH_CONFIG_FILE FRAMELEAF_CONFIG_FILE
IMMICH_HELMET_FILE FRAMELEAF_HELMET_FILE
IMMICH_TRUSTED_PROXIES FRAMELEAF_TRUSTED_PROXIES
IMMICH_IGNORE_MOUNT_CHECK_ERRORS FRAMELEAF_IGNORE_MOUNT_CHECK_ERRORS
IMMICH_PROCESS_INVALID_IMAGES FRAMELEAF_PROCESS_INVALID_IMAGES
IMMICH_ALLOW_SETUP FRAMELEAF_ALLOW_SETUP
IMMICH_WORKERS_INCLUDE FRAMELEAF_WORKERS_INCLUDE
IMMICH_WORKERS_EXCLUDE FRAMELEAF_WORKERS_EXCLUDE
IMMICH_HOST FRAMELEAF_HOST
IMMICH_PORT FRAMELEAF_PORT
IMMICH_IMPORT_ROOTS FRAMELEAF_IMPORT_ROOTS
IMMICH_ALLOW_EXTERNAL_PLUGINS FRAMELEAF_ALLOW_EXTERNAL_PLUGINS
IMMICH_PLUGINS_INSTALL_FOLDER FRAMELEAF_PLUGINS_INSTALL_FOLDER
IMMICH_BUILD, IMMICH_BUILD_URL, IMMICH_BUILD_IMAGE, IMMICH_BUILD_IMAGE_URL, IMMICH_BUILD_DATA The same names starting FRAMELEAF_
IMMICH_REPOSITORY, IMMICH_REPOSITORY_URL, IMMICH_SOURCE_REF, IMMICH_SOURCE_COMMIT The same names starting FRAMELEAF_
IMMICH_SOURCE_URL FRAMELEAF_SOURCE_COMMIT_URL
IMMICH_MACHINE_LEARNING_ENABLED FRAMELEAF_MACHINE_LEARNING_ENABLED
IMMICH_MACHINE_LEARNING_URL FRAMELEAF_MACHINE_LEARNING_URL
IMMICH_MEDIA_VALIDATION_TIMEOUT_MS FRAMELEAF_MEDIA_VALIDATION_TIMEOUT_MS
IMMICH_ICLOUD_BRIDGE_URL, IMMICH_ICLOUD_BRIDGE_TOKEN_FILE, IMMICH_ICLOUD_KEY_FILE, IMMICH_ICLOUD_CA_FILE, IMMICH_ICLOUD_STAGING_PATH, IMMICH_ICLOUD_FREE_SPACE_BYTES, IMMICH_ICLOUD_MAX_CONCURRENCY, IMMICH_ICLOUD_MAX_STAGING_BYTES The same names starting FRAMELEAF_
IMMICH_ML_AUTH_TOKEN (machine learning container) FRAMELEAF_ML_AUTH_TOKEN

FRAMELEAF_SOURCE_URL isn’t the new name of IMMICH_SOURCE_URL; it’s the help link to your source code. The CLI’s old names are listed on API and CLI.