Chapter 13 of Be Your Own Cloud explains Immich’s four containers and why the library lives on bulk storage. This page is the deploy in order, the proxy settings large uploads need, and how to handle Immich’s fast release pace without losing photos.
Folders and the password
mkdir -p /opt/stacks/immich
sudo mkdir -p /mnt/media/photos
cd /opt/stacks/immich
The .env from the book:
# /opt/stacks/immich/.env
IMMICH_VERSION=v3.2.4
UPLOAD_LOCATION=/mnt/media/photos # your photo library (Chapter 7)
DB_PASSWORD=a_long_random_password # letters and numbers only
DB_USERNAME=postgres
DB_DATABASE_NAME=immich Immich’s database password must be letters and numbers only. Chapter 9’s openssl rand -base64 48 can produce +, / and =, so for this one password use hex instead — it’s only ever 0–9 and a–f:
openssl rand -hex 32
Put that value after DB_PASSWORD=, then chmod 600 .env.
Deploy it
The compose file, exactly as printed:
services:
immich-server:
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION}
container_name: immich_server
restart: unless-stopped
volumes:
- ${UPLOAD_LOCATION}:/data # your photo library -- set in .env
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
depends_on:
- redis
- database
ports:
- '2283:2283'
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION}
container_name: immich_machine_learning
restart: unless-stopped
volumes:
- model-cache:/cache
env_file:
- .env
redis:
image: docker.io/valkey/valkey:9
container_name: immich_redis
restart: unless-stopped
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
container_name: immich_postgres
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_DB=${DB_DATABASE_NAME}
- POSTGRES_INITDB_ARGS=--data-checksums
volumes:
- ./pgdata:/var/lib/postgresql/data
shm_size: 128mb
volumes:
model-cache: docker compose up -d
docker compose logs -f immich-server
The first start downloads the images and sets up the database; give it a minute. Then open http://192.168.1.50:2283. The first account you create is the administrator — do it now, before anyone else on your network finds the page.
The proxy host
In Nginx Proxy Manager:
| Tab | Setting | Value |
|---|---|---|
| Details | Domain Names | immich.home.yourdomain.com |
| Details | Scheme | http |
| Details | Forward Hostname / IP | 192.168.1.50 |
| Details | Forward Port | 2283 |
| Details | Websockets Support | on — the web app uses it for live updates |
| SSL | SSL Certificate | your DNS-challenge certificate from Chapter 8 |
| SSL | Force SSL, HTTP/2 Support | on |
Then add a local DNS record for immich.home.yourdomain.com in Pi-hole (or use the wildcard from the Pi-hole tutorial).
Chapter 13’s troubleshooting box warns about proxy timeouts on large uploads. The fix goes in the proxy host’s Advanced tab — in Nginx Proxy Manager 2.16 that’s the gear icon at the right-hand end of the tabs. These values are from Immich’s reverse-proxy documentation:
client_max_body_size 50000M;
proxy_request_buffering off;
client_body_buffer_size 1024k;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
Finally, tell Immich its own address, so shared links point at the right place: Administration → Settings → Server Settings → External domain, https://immich.home.yourdomain.com.
The phone app
Install the Immich app, and for the server URL enter https://immich.home.yourdomain.com. Log in, choose which albums on the phone to back up, and turn on background backup. The first run uploads your whole camera roll, and the server’s machine-learning container will be busy for a while afterwards — Chapter 13 explains why that’s normal.
Moving between versions
Immich releases often, and some releases change the compose file or the database image. That’s why the book pins IMMICH_VERSION=v3.2.4 in .env and says to treat Immich’s own compose file as the source of truth when you deploy.
When you want a newer version:
- Read the release notes for every version between yours and the new one. Breaking changes are called out at the top.
- Compare the book’s compose file with the
docker-compose.ymlattached to the new release — especially thedatabaseimage line. If it changed, change yours to match. - Make sure last night’s backup ran (Chapter 18), then change
IMMICH_VERSIONin.env,docker compose pull,docker compose up -d.
Server and machine-learning always run the same version, because both read IMMICH_VERSION.
Backups
Chapter 18’s script takes a fresh pg_dump of Immich’s database before every backup and backs up the library in /mnt/media/photos. Immich also keeps its own nightly database dumps in a backups folder inside the library. Chapter 19’s database drill proves the dump restores — and it only works with the same database image that made the dump, which is one more reason to change versions deliberately.
Official documentation
- Immich documentation — including reverse proxy, backup and restore and hardware transcoding
- Immich releases
Stuck on a step? Get in touch.