Self-hosted photo and video management compose example.
Educational example only. Review every volume path, port, and credential before you run this. Do not copy production secrets into your wiki or git repo.
_shared/.env for non-secrets, _shared/.secret for credentialsmkdir -p /path/to/docker/stacks/immich
cd /path/to/docker/stacks/immich
# paste compose.yaml below, then:
docker compose pull
docker compose up -d
#
# WARNING: To install Immich, follow our guide: https://immich.app/docs/install/docker-compose
#
# Make sure to use the docker-compose.yml of the current release:
#
# https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
#
# The compose file on main may not be compatible with the latest release.
name: immich
services:
immich-server:
image: ghcr.io/immich-app/immich-server:release
container_name: immich_server
# Add the user line here using your host UID:GID
user: "1024:100"
env_file:
- /path/to/docker/stacks/_shared/.env
- /path/to/docker/stacks/_shared/.secret
environment:
# OAuth/OIDC with remote Keycloak (for LDAP federation):
# 1. Deploy Immich and access the admin UI at http://your-domain:2283 (create an initial admin user via local auth).
# 2. In Keycloak: Create a new OIDC client (confidential, authorization code grant) with redirect URIs like:
# - http://your-domain:2283/auth/login
# - http://your-domain:2283/user-settings
# - app.immich:///oauth-callback (for mobile apps)
# 3. In Immich Admin UI (Administration > Settings > OAuth):
# - Enable: true
# - Issuer URL: https://your-keycloak-domain/realms/your-realm (append /.well-known/openid-configuration if needed)
# - Client ID: your-client-id
# - Client Secret: your-client-secret
# - Scope: openid email profile
# - Button Text: Login with Keycloak
# - Auto Register: true (to auto-create users from LDAP-synced Keycloak users)
# - Claims: Map 'preferred_username' to Storage Label, 'immich_role' to Role (user/admin), etc., for user attributes from LDAP.
# 4. Ensure Keycloak's User Federation is configured for your remote LDAP (e.g., bind DN, users DN, sync users/groups).
# See Immich docs: https://immich.app/docs/administration/oauth/
# Keycloak LDAP guide: https://www.keycloak.org/docs/latest/server_admin/#_user_federation
# extends:
# file: hwaccel.transcoding.yml
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
- NODE_EXTRA_CA_CERTS=/certs/custom-ca.pem
logging:
driver: json-file
options:
max-file: ${DOCKERLOGGING_MAXFILE:-10} # Max number of log files
max-size: ${DOCKERLOGGING_MAXSIZE:-200k} # Max file size
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
#- /path/to/photo/upload:/usr/src/app/upload
- /path/to/photo/photos:/data
- /etc/localtime:/etc/localtime:ro
#- /etc/pki/ca-trust/source/anchors/:/certs:ro
- /path/to/docker/data/keycloak/certs/sfl-ca-001_RootCA.pem:/certs/custom-ca.pem:ro
ports:
- 32283:2283
depends_on:
- redis
- database
restart: always
healthcheck:
disable: false
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
container_name: immich_machine_learning
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
# Example tag: ${IMMICH_VERSION:-release:?err}-cuda
# 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, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
volumes:
- model-cache:/cache
env_file:
- /path/to/docker/stacks/_shared/.env
- /path/to/docker/stacks/_shared/.secret
restart: always
healthcheck:
disable: false
redis:
image: docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571
container_name: immich_redis
env_file:
- /path/to/docker/stacks/_shared/.env
- /path/to/docker/stacks/_shared/.secret
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84
container_name: immich_postgres
env_file:
- /path/to/docker/stacks/_shared/.env
- /path/to/docker/stacks/_shared/.secret
environment:
POSTGRES_DB: immich #${IM_POSTGRES_DB:?err}
POSTGRES_USER: postgres #${IM_DB_USERNAME:?err}
POSTGRES_PASSWORD: postgres #${IM_DB_PASSWORD:?err}
POSTGRES_INITDB_ARGS: '--data-checksums'
# Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
# DB_STORAGE_TYPE: 'HDD'
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
- /path/to/docker/data/immich/postgres:/var/lib/postgresql/data
shm_size: 128mb
restart: always
volumes:
model-cache:
_shared/.secret.