Immich is a self-hosted photo and video backup service — a private alternative to cloud photo libraries, with mobile apps that upload your camera roll automatically.

Prerequisites

  • Docker Engine + Compose plugin (see the Compose guide)
  • Storage headroom: photos grow. Budget several times your current library size.

1. Download the official Compose template

Immich maintains its compose file and example environment file on GitHub. On the server:

sudo mkdir -p /opt/immich
cd /opt/immich
sudo curl -fsSL \
  https://raw.githubusercontent.com/immich-app/immich/main/docker/docker-compose.yml \
  -o compose.yml
sudo curl -fsSL \
  https://raw.githubusercontent.com/immich-app/immich/main/docker/example.env \
  -o .env

Pinning to the template from the main branch keeps you aligned with the current documentation; the project publishes stable release tags for those who prefer to pin an exact version — see the project's docs.

2. Set the secrets and paths in .env

Edit /opt/immich/.env and set at least:

  • UPLOAD_LOCATION — where photos are stored (an absolute path on the server, e.g. /srv/photos)
  • DB_PASSWORD — a long random password for the internal Postgres database (openssl rand -base64 24 gives you one)
  • IMMICH_VERSION — the image tag to run. Use a release tag like v2.x.x from the project's releases page rather than release if you want updates to be a deliberate choice.
sudo nano .env   # or your editor of choice

3. Start it and create the admin account

sudo docker compose up -d
sudo docker compose ps

Keep the web UI private while you set up — bind to localhost and tunnel in (on your own computer):

ssh -L 2283:localhost:2283 your-user@your-server-ip
# then open http://localhost:2283

The first account you register becomes the server administrator; there's no default login. When you're ready for mobile access from outside, put Immich behind a reverse proxy with HTTPS (the Nginx Proxy Manager guide shows the pattern) — don't expose port 2283 raw to the internet.

4. Mobile backup

Install the Immich app (iOS/Android), point it at your server URL, sign in, and enable automatic background backup. Start with one small album and confirm photos appear on the server before trusting it with your whole library.

5. Updates and backups

Updates: bump IMMICH_VERSION in .env, then:

sudo docker compose pull && sudo docker compose up -d
Read the release notes before jumping versions. Immich runs database migrations automatically on container start. They're reliable within supported upgrade paths, but skipping many major versions at once is exactly the scenario the project warns against. Back up first.

Backups: your irreplaceable data lives in UPLOAD_LOCATION plus the Postgres database. A complete backup needs both: archive the photo directory, and take a database dump (docker compose exec database pg_dump -U postgres immich > immich-db.sql) — or schedule both with the routine from the backups guide. The database dump is what makes a restore app-consistent; copying files alone while Postgres is mid-write can leave the index inconsistent.

Troubleshooting

  • Containers restart-looping: almost always .env — a missing DB_PASSWORD or UPLOAD_LOCATION. sudo docker compose logs shows which variable it wants.
  • Photos don't appear after upload: check library jobs (Admin → Jobs) — thumbnail and metadata workers may still be catching up on a large first import.
  • Disk filling up: check UPLOAD_LOCATION and Docker's own storage (docker system df). Set a library quota in server settings if you share the server with other apps.

Official documentation: Immich docs · Repository: immich-app/immich