noted.do
@alextut

How I Set Up My Own Private Photo Cloud With Immich

I've been moving more of my data onto my own servers lately.

I've already set up file storage, password management, and a few other services, but photos are a little different.

Photos are probably some of the most important things sitting on our phones. Years of vacations, family pictures, screenshots, videos, and random memories can easily add up to hundreds of gigabytes.

I didn't really want to keep paying for more cloud storage every time I ran out of space.

That's when I started looking at Immich.

Immich is a self-hosted photo and video management platform that feels surprisingly similar to the photo apps we're already used to.

The big difference?

The server is yours.

What We're Building

The setup I'm going for looks something like this:

                 Your Phone
                     │
                     │
                     ↓
              Immich Mobile App
                     │
                     ↓
              https://photos.example.com
                     │
                     ↓
                Reverse Proxy
                     │
                     ↓
                   Immich
                  /      \
                 ↓        ↓
             Photos    Database

I'll be using:

  • Ubuntu Server

  • Docker

  • Docker Compose

  • Immich

  • A domain/subdomain

  • HTTPS

  • Local photo storage

  • Database backups

Immich currently recommends Docker Compose as the production installation method.


Step 1 — Check Your Server

Before installing anything, make sure your server has enough resources.

Immich's quick-start documentation currently lists at least 6 GB of RAM and 2 CPU cores as a baseline.

For a small personal library, that can be enough to get started.

But if you're planning to store thousands of photos and videos, perform face recognition, generate thumbnails, and use Smart Search, I'd personally give it more resources if they're available.

You also want plenty of storage.

And remember:

Your photo library is going to grow.


Step 2 — Install Docker

If Docker isn't already installed, install Docker Engine and the Docker Compose plugin.

Check your installation:

docker --version

Then:

docker compose version

One important thing I noticed while setting this up:

Use:

docker compose

not:

docker-compose

Immich currently requires the newer Docker Compose plugin syntax.


Step 3 — Create the Immich Directory

I like keeping each application separate.

Create the Immich directory:

mkdir -p /opt/immich
cd /opt/immich

This directory will contain the Docker Compose configuration and environment file.


Step 4 — Download the Immich Configuration

Immich provides the official Docker Compose file and environment template.

Run:

wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

Then download the environment file:

wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

You should now have:

/opt/immich/
├── docker-compose.yml
└── .env

I recommend downloading the files from the current release instead of copying an old Compose file from some random tutorial.

Immich is under active development, so configuration can change between versions.


Step 5 — Choose Where Your Photos Will Live

This is probably the most important decision you'll make during installation.

Open the environment file:

nano .env

You'll see:

UPLOAD_LOCATION=./library

You can leave it like that, but I prefer putting my actual photo library somewhere specifically designed for storage.

For example:

UPLOAD_LOCATION=/srv/immich/library

Then create the directory:

mkdir -p /srv/immich/library

Now your photos will live outside the application directory.

That makes it easier to manage storage and backups later.


Step 6 — Keep the Database on Local Storage

You'll also see:

DB_DATA_LOCATION=./postgres

You can leave this as the default.

The important thing is don't put the PostgreSQL database on a network share.

Immich specifically recommends local storage for the database, ideally an SSD.

For example:

DB_DATA_LOCATION=/srv/immich/postgres

Then:

mkdir -p /srv/immich/postgres

Your setup might now look like:

/srv/immich/
├── library/
└── postgres/

Step 7 — Change the Database Password

Inside .env, you'll find:

DB_PASSWORD=postgres

Don't leave it like that.

Create a random password.

For example:

DB_PASSWORD=YOUR_RANDOM_PASSWORD

Immich recommends using only letters and numbers for this value to avoid Docker parsing issues.

You don't need to expose PostgreSQL to the internet. The database is used internally by the Immich containers.


Step 8 — Set Your Time Zone

You'll also see a timezone setting.

For someone in Eastern Time, for example:

TZ=America/New_York

This isn't strictly required, but it's a good idea to configure it correctly.


Step 9 — Start Immich

Once you've finished editing .env, start Immich:

docker compose up -d

Docker will download the required images and start the services.

Check them:

docker compose ps

You should see several Immich services running.

If something doesn't look right, check the logs:

docker compose logs

Or check a specific service:

docker logs immich_server

Step 10 — Open Immich

You can initially access Immich using:

http://YOUR-SERVER-IP:2283

Port 2283 is the default web interface port in the current Compose configuration.

You should see the Immich welcome screen.

The first account registered becomes the administrator account.

Create your account and log in.

And just like that, you've got your own photo server.


Step 11 — Give Immich Its Own Domain

I don't really want to remember:

192.168.1.50:2283

I'd rather use:

photos.example.com

Create a DNS record for your domain.

For example:

Type: A

Name: photos

Value: YOUR.SERVER.IP

Now:

photos.example.com

points to your server.

If you're using Cloudflare, you can create the DNS record there.


Step 12 — Put Immich Behind HTTPS

Now we can make the setup much nicer.

Instead of:

http://192.168.1.50:2283

we want:

https://photos.example.com

I recommend putting Immich behind a reverse proxy.

For example:

Internet
    ↓
photos.example.com
    ↓
HTTPS
    ↓
Reverse Proxy
    ↓
Immich :2283

You can use something like:

  • Nginx Proxy Manager

  • Caddy

  • Nginx

  • Traefik

If you're already running a reverse proxy for your other self-hosted applications, you can simply add another proxy entry for Immich.


Step 13 — Install the Mobile App

This is where Immich really starts to become useful.

Install the Immich app on your phone.

Then enter your server address:

https://photos.example.com

Log in.

The app can then access your Immich server.


Step 14 — Turn On Automatic Photo Backup

Now comes the part I actually wanted Immich for.

Turn on automatic backup in the mobile app.

You can choose which albums or folders you want Immich to back up.

For example:

Camera
Screenshots
Videos
WhatsApp
Downloads

Once configured, your phone can automatically upload your photos to your own server.

So instead of:

Phone
  ↓
Google Photos / iCloud

you have:

Phone
  ↓
Immich
  ↓
Your Server
  ↓
Your Storage

That's pretty cool.


Step 15 — Face Recognition and Smart Search

This is one of the features that makes Immich much more than a basic file browser.

Immich can process your photos for things like:

  • Face recognition

  • Smart Search

  • Object recognition

  • Automatic thumbnails

  • Video processing

  • Photo metadata

The server does this processing itself.

That means you can search your own library without necessarily sending all of your photos to another company's cloud.


Step 16 — Hardware Acceleration

If you have a compatible GPU or integrated graphics, you can configure hardware acceleration.

Immich currently supports several acceleration methods, including:

  • NVIDIA NVENC

  • Intel Quick Sync

  • VAAPI

  • AMD

  • Rockchip

Hardware acceleration can reduce CPU usage during video transcoding.

For example, Intel Quick Sync can use:

/dev/dri

The exact configuration depends on your hardware, so I wouldn't blindly copy a GPU configuration from someone else's server.

Immich provides separate hardware-acceleration Compose configurations for supported hardware.


Step 17 — Backups

This is where I would slow down for a second.

Immich is not a backup by itself.

Your server is now holding your photos, but if the hard drive dies, you can lose everything.

Immich recommends a 3-2-1 backup strategy and specifically says you should back up both the uploaded photos/videos and the database.

I'd set it up something like this:

                 Immich
                   │
          ┌────────┴────────┐
          ↓                 ↓
      Main Storage       Backup
                            │
                     ┌──────┴──────┐
                     ↓             ↓
                 Local Copy    Off-Site Copy

Your database is especially important because Immich stores file paths and metadata there rather than simply rebuilding everything by scanning your library.


Step 18 — Test Your Backup

Don't just create a backup and forget about it.

Actually test restoring something.

For example:

Backup created
      ↓
Server fails
      ↓
New server
      ↓
Restore database
      ↓
Restore library
      ↓
Immich is back

If you've never tested the last four steps, you don't really know whether your disaster recovery plan works.


A Few Things I Would Do

If this were my own Immich server, I'd probably have:

  • HTTPS

  • A proper domain

  • Automatic mobile backups

  • SSD storage for PostgreSQL

  • Large dedicated storage for photos

  • Hardware acceleration if supported

  • Automatic database backups

  • Off-site backups

  • Monitoring

  • Firewall rules

  • Regular Immich updates

And I'd keep the database separate from the photo storage.


My Final Setup

After everything is configured, the setup looks something like this:

                         INTERNET
                             │
                             ↓
                    photos.example.com
                             │
                           HTTPS
                             │
                             ↓
                     Reverse Proxy
                             │
                             ↓
                          Immich
                       /     |     \
                      ↓      ↓      ↓
                  Photos   Search   Videos
                      │
                      ↓
                 Photo Storage
                      │
              ┌───────┴────────┐
              ↓                ↓
          Local Backup     Off-Site Backup

And my phone simply connects to:

https://photos.example.com

Whenever I take a picture, Immich can upload it to my own server.

No plugging my phone into a computer.

No manually copying folders.

No wondering where the photos ended up.

They just show up.


Was It Worth Setting Up?

For me, absolutely.

The biggest thing I like about Immich isn't just that it replaces a cloud photo service.

It's that it feels like a real photo app.

I can open it on my phone.

Browse my timeline.

Search my photos.

Create albums.

Watch videos.

And still know that the underlying storage is sitting on hardware that I control.

That's what makes self-hosting fun.

You start with:

"I just want somewhere to store my photos."

Then you end up with your own private photo cloud.

And honestly, I'm okay with that.


Useful Links

Immich Documentation:
Immich Documentation

Docker Compose Installation:
Immich Docker Compose Guide

Immich GitHub:
Immich on GitHub

Hardware Transcoding:
Immich Hardware Transcoding Guide

Backup and Restore:
Immich Backup & Restore Guide