I wanted to test out some changes to my Immich library without taking my current one down or risking breaking anything, so I wanted to deploy a dev instance to play around with.
This is a bit easier said than done because the Immich docker-compose has several containers in it that reference each other for healthchecks so you have to update those. But the Immich codebase itself uses container names to communicate, so once you change the names it causes that to break.
I was able to get it working with minimal effort though.
⚠️
Immich is being actively developed and they regularly change container names and other details. This article is current as of 2025-12-03 (Immich v2.3.1) with one exception: I have excluded the telemetry containers and volumes (prometheus & grafana). Metrics are disabled by default, but also I don't use them. The configs below are tested and verified working.
Before you start
This post assumes you already have a working instance of Immich that was deployed via docker-compose. It doesn’t walk through all the details of getting it working in the first place.
Make sure to create a separate .env file for your second instance and update things like your UPLOAD_LOCATION and DB_DATA_LOCATION so you don’t overwrite your prod instance.
Having a backup of your existing instance and pictures would be smart in case you forget to update something and you corrupt your current install
Prod Immich docker-compose
The standard Immich docker-compose.yml should look like this (again, excluding telemetry containers):
name:immichservices:immich-server:container_name:immich_serverimage:ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}# extends:# file: hwaccel.transcoding.yml# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcodingvolumes:# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file- ${UPLOAD_LOCATION}:/usr/src/app/upload- /etc/localtime:/etc/localtime:roenv_file:- .envports:- '2283:2283'depends_on:- redis- databaserestart:alwayshealthcheck:disable:falsedevices:- /dev/dri:/dev/driimmich-machine-learning:container_name:immich_machine_learning# For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.# Example tag: ${IMMICH_VERSION:-release}-cudaimage:ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}# extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration# file: hwaccel.ml.yml# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicablevolumes:- model-cache:/cacheenv_file:- .envrestart:alwayshealthcheck:disable:falseredis:container_name:immich_redisimage:docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8healthcheck:test:redis-cli ping || exit 1restart:alwaysdatabase:container_name:immich_postgresimage:ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84environment:POSTGRES_PASSWORD:${DB_PASSWORD}POSTGRES_USER:${DB_USERNAME}POSTGRES_DB:${DB_DATABASE_NAME}POSTGRES_INITDB_ARGS:'--data-checksums'volumes:# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file- ${DB_DATA_LOCATION}:/var/lib/postgresql/datarestart:alwaysshm_size:128mbvolumes:model-cache:
Second docker-compose
In order to setup a second instance of Immich in docker on the same server, there are 2 main things that need done in the second/new docker-compose:
Update the container names, volume name, and any references to those old names. You will also need to add some container links to get the networking between containers to work correctly
Change what port the container is listening on
For this example we’re going to call our second instance dev, and we’ll rename the containers to reflect that.
diff
This is a diff between the two compose files (initial immich deploy vs second immich deploy) to highlight the changes between them:
--- docker-compose.yml (original -- from first Immich instance)
+++ docker-compose.dev.yml (new -- for second/dev Immich instance)
- name: immich
+ name: immich-dev
services:
- immich-server:
- container_name: immich_server
+ immich-server-dev:
+ container_name: immich_server_dev
+ links:
+ - redis-dev:redis
+ - database-dev:database
+ - immich-machine-learning-dev:immich-machine-learning
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
# extends:
# file: hwaccel.transcoding.yml
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
volumes:
# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
ports:
- - '2283:2283'
+ - '2284:2283' # The new Immich instance will be listening on port 2284. Change to something else if you need to, but leave the container port on 2283.
depends_on:
- - redis
- - database
+ - redis-dev
+ - database-dev
restart: always
healthcheck:
disable: false
devices:
- /dev/dri:/dev/dri
- immich-machine-learning:
- container_name: immich_machine_learning
+ immich-machine-learning-dev:
+ container_name: immich_machine_learning_dev
# For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
# Example tag: ${IMMICH_VERSION:-release}-cuda
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
# extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
# file: hwaccel.ml.yml
# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
volumes:
- - model-cache:/cache
+ - model-cache-dev:/cache
env_file:
- .env
restart: always
healthcheck:
disable: false
- redis:
- container_name: immich_redis
+ redis-dev:
+ container_name: immich_redis_dev
image: docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8
healthcheck:
test: redis-cli ping || exit 1
restart: always
- database:
- container_name: immich_postgres
+ database-dev:
+ container_name: immich_postgres_dev
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
restart: always
shm_size: 128mb
volumes:
- model-cache:
+ model-cache-dev:
Completed dev instance docker-compose
And here is the completed docker-compose.yml for the second instance, without the visible edits in it.
name:immich-devservices:immich-server-dev:container_name:immich_server_devlinks:- redis-dev:redis- database-dev:database- immich-machine-learning-dev:immich-machine-learningimage:ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}# extends:# file: hwaccel.transcoding.yml# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcodingvolumes:# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file- ${UPLOAD_LOCATION}:/usr/src/app/upload- /etc/localtime:/etc/localtime:roenv_file:- .envports:- '2284:2283'depends_on:- redis-dev- database-devrestart:alwayshealthcheck:disable:falsedevices:- /dev/dri:/dev/driimmich-machine-learning-dev:container_name:immich_machine_learning_dev# For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.# Example tag: ${IMMICH_VERSION:-release}-cudaimage:ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}# extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration# file: hwaccel.ml.yml# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicablevolumes:- model-cache-dev:/cacheenv_file:- .envrestart:alwayshealthcheck:disable:falseredis-dev:container_name:immich_redis_devimage:docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8healthcheck:test:redis-cli ping || exit 1restart:alwaysdatabase-dev:container_name:immich_postgres_devimage:ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84environment:POSTGRES_PASSWORD:${DB_PASSWORD}POSTGRES_USER:${DB_USERNAME}POSTGRES_DB:${DB_DATABASE_NAME}POSTGRES_INITDB_ARGS:'--data-checksums'volumes:# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file- ${DB_DATA_LOCATION}:/var/lib/postgresql/datarestart:alwaysshm_size:128mbvolumes:model-cache-dev: