Immich

Immich is a modern photo management web application which aims to be similar to Google Photo. I use it to backup my phone photos and also manage my older collection of older photos of when i was using physical cameras.

Immich is a fairly new player in the game but it's growing a lot and is gaining a lot of traction. It's heavily under development and very polished. Overall it's probably the best solution but:

  • Doesn't support folders as albums (sorry, long term solution must be stored in folders and not only in a database)

Immich now also support external libraries which is a good point for my use case, since all my older photos are already sorted in folders. When Immich will be able to autogenerate albums from those folders, it will be perfect too.

Immich, at this time, does not support base_url out of the box. A lot of discussion is going on around the topic and somebody found a nice fix using a specific NGINX setup, which i will describe in this page.

Installation

I tried to install Immich on bare-metal and give up. The total lack of documentation is regretting and the only existing guide is obsolete. Sadly, using containers is the only viable way to install Immich. The devs clearly stated they do not intend to provide any bare-metal installation instructions and this frankly sucks, even more so that the default docker images provided run as root by default. Anyway, i will show you how to fix this by running Immich using Podman (see Using Containers on Gentoo) root-less. Better than nothing.

I suggest you create a photos group on which add all users that will need to use/share/access/add photos, immich user included.

So, let's get going. Create an immich user:

groupadd photos
useradd -d /data/damons/immich -g photos immich

And download the standard immich docker-compose and env files:

su - immich
wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml
wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

(enabling hardware acceleration is optional and i will not cover it here, as it's not needed in my use-case)

Since you are going to use podman instead of docker, you need to add a specific network to the docker compose file. Also, you want to add support for your external photo libraries.

# Set the following locations to immich-server, immich-microservices;
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
      - ${EXTERNAL_PATH}:/usr/src/app/external

# Add these two lines to each one of the services (immich-server, immich-microservices, immich-machine-learning, redis, database)
    networks:
      - immich-net

# This goes at the end of the file:
networks:
  immich-net: {}

Please note that you can have more than one mount, ideally one for each folder tree that contains photos you want to add as external library to Immich.

edit the /data/daemons/immich/.env file to adapt at least your Uploads and external folder:

UPLOAD_LOCATION=/data/Media/Photos/Uploads
EXTERNAL_PATH=/path/to/your/external/photos/trees
IMMICH_VERSION=release

then fire up the containers:

su - immich
podman compose up -d

When you want to update Immich, just:

su - immich
podman compose down
podman compose pull
podman compose up -d

Be aware that Immich is bleeding edge and sometimes there are breaking updates! Always check on Immich Releases page the release notes and take actions accordingly. YOU HAVE BEEN WARNED.

NGINX reverse proxy

Immich on sub-path

If you do not want to use a specific sub-domain for Immich, the specific NGINX example here will include the base_url fix as described here:

location /immich {
                        proxy_pass http://127.0.0.1:2283;
                        rewrite /immich/(.*) /$1 break;

                        proxy_buffering        on;

                        sub_filter_once off;
                        sub_filter_types text/html;
                        sub_filter ' href="/' ' href="/immich/';
                        sub_filter ' src="/' ' src="/immich/';
                        sub_filter ' action="/' ' action="/immich/';
                        sub_filter 'import("/_app' 'import("/immich/_app';
                        sub_filter 'base: ""' 'base: "/immich"';

                        location /immich/_app/immutable/chunks {
                                proxy_pass http://127.0.0.1:2283;
                                rewrite /immich/(.*) /$1 break;

                                sub_filter_types *;
                                sub_filter '"/api/socket.io"' '"/immich/api/socket.io"';
                        }

                        location ~ /immich/_app/immutable/chunks/index\\. {
                                proxy_pass http://127.0.0.1:2283;
                                rewrite /immich/(.*) /$1 break;

                                sub_filter_types *;
                                sub_filter '"/' '"/immich/';
                        }

                        location ~ /immich/_app/immutable/chunks/api\\. {
                                proxy_pass http://127.0.0.1:2283;
                                rewrite /immich/(.*) /$1 break;

                                sub_filter_types *;
                                sub_filter '="/api"' '="/immich/api"';
                                sub_filter 'basePath:"/api"' 'basePath:"/immich/api"';
                        }

                        location ~ /immich/api {
                                proxy_pass http://127.0.0.1:2283;
                                rewrite /immich/(.*) /$1 break;

                                proxy_cache off;
                                
                                sub_filter_types *;
                                sub_filter '"redirectUri":"/' '"redirectUri":"/immich/';
                        }
                                                proxy_pass_request_headers on;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;

                proxy_set_header   X-Real-IP $remote_addr;
                proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header   X-Forwarded-Proto $scheme;
                proxy_set_header   X-Forwarded-Host $host;
                proxy_set_header   X-Forwarded-Server $host;

                proxy_cache_use_stale  error timeout invalid_header updating
                http_500 http_502 http_503 http_504;

                proxy_redirect     off;

                }
    

you need also to disable authentication, since Immich cannot work with Proxy Auth and you would end up with double-authentication.

(note: YMMV, at this time this seems broken by an Immich upgrade)

Immich on sub-domain

In case you do not care for sub_path and you want to use a dedicated subdomain, go ahead and use this much simpler NGINX configuration. I will assume your subdomain is called immich.mydomain.com:

immich.conf
    server {
        server_name immich.mydomain.com;
        listen 8443 ssl; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        client_max_body_size 50000M;
        large_client_header_buffers 4 32k;
 
        access_log /var/log/nginx/immich.mydomain.com_access_log main;
        error_log /var/log/nginx/immich.mydomain.com_error_log info;
 
        location / {
                proxy_pass http://127.0.0.1:2283/;
        }
 
        include com.mydomain/certbot.conf;
}

you need also to disable authentication, since Immich cannot work with Proxy Auth and you would end up with double-authentication.

First usage

Fire up your browser at https://yourdomain.com/immich (or https://immich.yourdomain.com) and follow instructions.

To add external libraries, it's currently (Immich 1.92.1) a bit convoluted.

First you need, as administrator, to go to each user settings (under administration panel) and add the external path as specified in the docker compose (ex: /usr/src/app/external) then, as specific user, you also need to add an external library and repeat the same path in your user settings.

It's confusing, i think this will be improved in future releases.

Command line CLI

Immich has a CLI which requires NPM:

emerge nodejs

as user immich:

npm i -g @immich/cli

The CLI might require login for upload operations:

immich login-key https://10.0.0.1/immich/api [apiKey]
immich upload --recursive directory/