Tutoriales, noticias y soluciones informáticas

PiServer con Docker – Parte 21: Instalación de Immich para sustituir a iCloud ahorrando recursos de la Raspberry

Foto con el móvil

En nuestro blog hemos realizado ya un montón de tutoriales en los que hemos aprendido a usar Docker, y ya de paso hemos aprovechado para instalar aplicaciones tremendamente útiles en nuestra raspberry (os dejo el listado completo de lo que hemos hecho en este enlace). Evidentemente hay muchísimas más aplicaciones interesantes que podemos instalar usando Docker y hoy vamos a aprender a instalar una que, si la dejamos «a sus anchas» puede colgarnos por completo nuestra Raspberry, aunque…

Espera, ¿Cómo dices? A ver... ¿me estás diciendo que quieres que instale algo que va a reventar mi raspberry? ¿Pero tú sabes lo que me ha costado instalar todo lo que nos has enseñado en tu blog? ¿Qué virus pretendes que le meta a mi Raspberry? No esperaba esto de ti. No te lo perdonaré jamás.

Tranquilízate Usuario Anónimo. El programa que quiero que instaléis es algo muy similar a Google Photos o iCloud, y además es muy fácil ver que os va a ser de utilidad. Seguro que casi todos los lectores sacan fotos con el móvil en alguna ocasión. Este servicio que vamos a instalar y que se llama Immich, de forma completamente automatizada nos realizará cada noche una especie de copia de seguridad de todas las fotos que hemos realizado el día anterior. Por supuesto, como primer paso y antes de empezar a sincronizar nada, podemos pasar todas las fotos que tenga el carrete del móvil a nuestro Immich. Pero lo mejor de todo es que en cualquier momento podremos descargar o visualizar las fotos que hemos sacado usando una página web muy sencilla de usar. Fíjate, la web que nos generará el servicio viene a ser algo así.

Página de immich

Podéis incluso ver una pequeña demo de la web que genera Immich en este enlace, pinchando sobre la opción «Login as demo user».

Uy, uy, uy... pero ¡¡Lo que veo está muy bien!! Estoy pensando que si esto es lo que creo que es, me va a permitir ahorrarme la pasta que me estoy gastando para tener copia de las fotos en "iCloud". Tremendo servicio... Pero seguro que aquí hay gato encerrado. ¿Por qué dijiste antes que esto puede escacharrar nuestra raspberry?

Pues porque a pesar de ser un servicio muy útil, necesita una capacidad de proceso muy alta para funcionar tal cual quieren los desarrolladores. Si nuestro equipo tiene mucha potencia (según la documentación, los requisitos son 4 núcleos de proceso y un mínimo de 6 GB de RAM) podremos realizar el despliegue de Immich y usarlo con tranquilidad y sin problema alguno. Sin embargo, si nuestro equipo tiene poco rendimiento o poca memoria RAM, he comprobado en persona que en un principio se puede realizar la instalación sin mayores problemas, pero en cuanto le pedimos sincronizar por primera vez el carrete de nuestro móvil, al rato los procesos internos del programa saturan de trabajo al procesador y llenan la memoria (ocurren ambas cosas a la vez), lo que acaba produciendo un «Kernel Panic» y el sistema termina colgado de forma catastrófica.

Mi gozo en un pozo. Quería instalarlo en una Raspberry Pi de sólo 2 gigas de RAM, así que voy a tener que seguir pagando religiosamente iCloud. ¡No puedes jugar así con las ilusiones de la gente!

Claro que puedo, porque vamos a modificar el Docker de instalación de Immich (y luego hacer algunos ajustes en su interfaz) para poder ejecutarlo en equipos con sólo un GB de ram y poquísima potencia de proceso. Este mismo método nos va a servir para mantener atado y amordazado cualquier Docker que no queramos que consuma demasiados recursos.

Como siempre, me he liado demasiado con la introducción, así que vamos ya al turrón.

1- Creamos la estructura de la carpeta «docker».

Si recordáis, en todos los tutoriales estamos forzando a que toda la información de cada docker se almacene en las carpetas que nosotros queramos. No nos apetece que la información acabe desperdigada por la estructura de carpetas de nuestra distribución de Linux, así que es importante para nosotros tener todo bien localizado y organizado.

En los 20 tutoriales anteriores hemos hecho que todos los archivos que necesita cada Docker estén separados cada uno en su carpeta, que la hemos situado dentro de esta ruta.

/home/<tu_usuario>/docker

Evidentemente, hay que sustituir <tu_usuario> por vuestro usuario de linux. Los más expertos en estas lides sabrán que esa ruta se puede escribir también como ~/docker

Si se trata del primer docker que estáis creando con nosotros, debéis crear la carpeta «docker» con el siguiente comando.

cd ~
mkdir docker
cd docker

Si ya hemos creado la ruta porque hemos seguido alguno de los 20 tutoriales anteriores, simplemente usaremos el comando cd docker para meternos dentro de esa carpeta.

Una vez que estemos dentro de la carpeta «docker», crearemos otra carpeta específica para Immich y entraremos dentro de ella. Lo haremos con estos comandos:

mkdir immich
cd immich

Immich va a necesitar tres carpetas para almacenar todos sus datos, que se llaman "library", "model-cache" y "postgres". Vamos a crearlas con el siguiente comando:

mkdir library && mkdir model-cache && mkdir postgres

Con esto ya tenemos la estructura de carpetas lista para almacenar todos los datos de Immich.

2- Creamos el archivo de configuración de immich.

Los desarrolladores de Immich nos piden realizar el despliegue de Immich de una forma muy concreta (el manual para hacerlo está en esta página). Según sus instrucciones (os ruego que no hagáis nada aún), primero deberíamos bajarnos el archivo «docker compose» de sus servidores usando este comando…

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

y luego deberíamos bajar el archivo .env con este otro comando.

wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
Vale, ya me he bajado los dos archivos con esos comandos. ¿Ahora qué hay que hacer?

Eres de lo que no hay, Usuario Anónimo. Lo primero que debes hacer es borrar ambos archivos, porque ya te dije que no vamos a usarlos. Como siempre, modificaremos ambos archivos para obligarlos a que las cosas se instalen dónde queremos nosotros.

Para que podáis seguir el proceso de modificación (me interesa más que entendáis lo que estamos haciendo que simplemente copiar y pegar el código) vamos a ver tres versiones del archivo de docker compose: La primera es el archivo original del desarrollador. La segunda será el archivo modificado tal y cómo hemos hecho en los anteriores tutoriales. Podríamos usar esa segunda versión si instalamos Immich en un equipo lo suficientemente potente. La tercera versión estará optimizada para equipos poco potentes y será la definitiva para vuestra Raspberry y la que debéis copiar y pegar para realizar el despliegue de Immich en ella. Veamos todas las versiones.

2.1- Versión del desarrollador del archivo docker-compose.yml

Que nadie se me asuste por la longitud de este archivo. El desarrollador nos pide que usemos este archivo docker-compose.yml. Os lo pongo, pero no lo uséis todavía, que tal cual está es posible que os provoque errores (Os adelanto que la versión correcta del archivo está en el punto 3.6 del artículo. Todo lo que hay antes de ese punto son explicaciones de cómo hemos llegado a esa versión).

#
# 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:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    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
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # 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, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    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
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: >-
        pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
        Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
        --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
        echo "checksum failure count is $$Chksum";
        [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: >-
      postgres
      -c shared_preload_libraries=vectors.so
      -c 'search_path="$$user", public, vectors'
      -c logging_collector=on
      -c max_wal_size=2GB
      -c shared_buffers=512MB
      -c wal_compression=on
    restart: always

volumes:
  model-cache:
¡Virgencita de los auriculares Bluetooth! ¡Qué largo es esto! ¿Estás seguro que desplegar esto no va a ser complicado?

Para nada Usuario Anónimo. Si te fijas en la estructura de este docker-compose.yml, podrás ver que archivo despliega cuatro servicios (que son contenedores que cumplen funciones específicas para Immich):

  • immich-server: Es el propio código de Immich (maneja la API, la interfaz web y la gestión de medios, y además expone el puerto 2283, que es en el que se genera la página web del servicio)
  • immich-machine-learning: Se encarga de tareas de aprendizaje automático como reconocimiento facial y etiquetado automático de imágenes.
  • redis: Es una caché que va a acelerar la velocidad general de Immich.
  • database: Es una base de datos PostgreSQL. Como dato, podemos ver que usa pgvector, que es una extensión para manejar datos vectoriales (útil para búsqueda de imágenes similares)

Si te fijas en cada uno de estos servicios por separado seguro que te va a resultar menos intimidante entender el despliegue de Immich. Imagínate que en lugar de desplegar un único docker estamos desplegando cuatro.

2.2- Archivo de configuración modificado para usar nuestra estructura de carpetas.

En estos tutoriales lo que buscamos siempre primero son los volúmenes del docker y los modificamos para forzar la escritura de datos en las carpetas que nos interesan (queremos que todos los datos se escriban en la carpeta que hemos creado para Immich). Vamos a ir servicio por servicio para no liarnos. Pero primero vamos a ver un detalle sobre la versión del docker que estamos desplegando.

2.2.1- Definición de la versión del docker.

Si os fijáis, el docker no muestra al principio la versión de docker como muchos otros que hemos desplegado. Esto en versiones modernas de docker no debería ser problema, pero si tenéis una versión antigua de docker, no tener una línea de definición de versión puede ocasionar un error de despliegue, así que para evitar errores vamos a añadir la siguiente línea:

version: "3.8"

Tener esta línea me asegura que a todos vosotros os funcionará este despliegue sin problemas, así que vamos a añadirla. Ah, y no os preocupéis. Os recuerdo que en el punto 3.6 del artículo os pondré todo el docker-compose.yml definitivo con todos los cambios realizados.

En el comienzo del archivo también hay una línea que nos puede dar guerra dependiendo de la versión de docker que estemos usando. Es ésta.

name: immich

Esa línea la vamos a comentar (le pondremos un símbolo «#» justo delante). Así nos aseguramos que esta línea tampoco provoque ningún error durante el despliegue.

2.2.2- Servicio «immich-server».

Los volúmenes que usa este servicio son los siguientes:

      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro

Aquí tenemos dos opciones. La primera es, como siempre hemos hecho, editar esta parte del docker-compose.yml para poner la ruta que nos interesa, como hemos hecho en los anteriores tutoriales (no la pondríamos directamente, sinó que haríamos una variable que definiríamos en el archivo .env).

Eh, eh, ¿Te das cuenta de que un poco más arriba de esa línea pone esto? 

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

¿Estás seguro de lo que haces?

Sí. Pero estoy convencido de que al igual que tú habrá más gente escéptica con este cambio, así que vamos a hacerle caso al desarrollador y haremos esto en el archivo «.env» en un punto posterior.

Ah, y por cierto… nos va a interesar editar sólo la primera línea de estos volúmenes. La línea /etc/localtime:/etc/localtime:ro no debe editarse porque así garantizamos que el contenedor use la misma zona horaria que el nuestra Raspberry. Al mantenerlo así, si cambio por el motivo que sea la zona horaria de la Raspberry, ese cambio se traslada de forma automática al Docker de immich. Queremos que el contenedor siempre use la misma zona horaria del sistema, por lo que es mejor no tocar esa línea.

2.2.3- Servicio «immich-machine-learning».

Aquí de nuevo vemos un volumen que podríamos editar, que es éste.

    volumes:
      - model-cache:/cache

Me parece cuando menos curioso que los desarrolladores hayan definido los otros volúmenes en el archivo .env pero este lo hubieran dejado así. Vale… se tratan sólo de cachés, pero ¿Por qué vamos situar las cachés en sitios no controlados si podemos ponerlas en la carpeta correcta? Como no tenemos ninguna indicación en contrario en el archivo docker-compose.yml, vamos a editar esa línea para definir la ruta en el archivo .env. Vamos a dejar ese volumen tal que así.

    volumes:
      - ${MODEL_CACHE}:/cache

2.2.4- Servicio «redis».

Esto es una especie de caché para acelerar el sistema. Si os fijáis no tiene volúmenes definidos y no requiere casi ninguna configuración, así que no tocamos nada en este apartado.

2.2.5- Servicio «database».

Aquí si que hay un volumen que podemos modificar, que es éste:

- ${DB_DATA_LOCATION}:/var/lib/postgresql/data

Pero de nuevo no vamos a modificarlo. Editaremos esta ruta de nuevo desde el archivo .env.

En el servicio «database» hay también una línea conflictiva, que es ésta.

start_interval: 30s

Este comando no funciona en la versión de docker que estamos manejando, así que vamos a cambiar la línea por ésta otra (no hace exactamente lo mismo, pero es mejor poner esto que comentar la línea).

retries: 5

2.2.6- Archivo docker-compose.yml completo y modificado

Con los cambios que hemos planteado el archivo docker-compose.yml nos quedaría tal que así.

version: "3.8"
#
# 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:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    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
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # 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, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - ${MODEL_CACHE}:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    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
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: >-
        pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
        Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
        --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
        echo "checksum failure count is $$Chksum";
        [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      retries: 5
      start_period: 5m
    command: >-
      postgres
      -c shared_preload_libraries=vectors.so
      -c 'search_path="$$user", public, vectors'
      -c logging_collector=on
      -c max_wal_size=2GB
      -c shared_buffers=512MB
      -c wal_compression=on
    restart: always

volumes:
  model-cache:
Menos mal. Podías haber empezado por ahí en lugar de soltarnos todo el sermón. Lo copio... ahora lo pego y...

¡Paaaaara! No te aceleres aún. Este archivo es completamente válido si el equipo en que vais a desplegar el docker tiene bastantes recursos (bastante memoria y sobre todo bastantes núcleos de procesador). Lo normal es que nuestra raspberry tenga al menos 4 núcleos de procesador, e incluso es probable que vayáis a intentar correr esto en una con 4 u 8 gigas de RAM. Pero por experiencia, este software va a pedir muchos recursos de vuestra máquina, hasta el punto de poder llegar a colgarla por completo. De hecho la RAM mínima para correr Immich son 6 Gb, pero ya veréis como con ajustes vamos a solucionar esto más adelante.

En este artículo os hablé acerca de cómo podemos leer la carga del procesador en un equipo con Linux. Con eso en mente, debéis saber que Immich es perfectamente capaz de crear colas de procesos tremendamente largas en todos los núcleos del procesador. No es algo problemático en procesadores rápidos, (despejarán los procesos al momento y harán que desaparezcan las colas) pero las limitaciones de hardware de nuestra Raspberry pueden ocasionar que Immich produzca retardos en todo el sistema y que absolutamente todo se quede congelado si no tenemos suficiente potencia de procesamiento. Tal y como está ahora mismo el docker, y a pesar de que su despliegue sería completamente factible en una Raspberry, yo no me arriesgaría a desplegarlo en una máquina tan limitada.

¡Ahora vas y lo cascas! Pues ya me dirás qué hacemos entonces. Te recuerdo que esto es un tutorial para instalar cosas en Raspberrys. 

Por supuesto, Usuario Anónimo. Pero Docker tiene una solución muy curiosa para estos temas: Limitar el procesamiento de un servicio. Vamos a ver cómo podemos hacerlo.

2.3- Ajustamos el docker-compose.yml para que no nos ponga a mil la CPU.

Los contenedores causantes de nuestros males, los que más recursos van a consumir de nuestra CPU, van a ser el principal (immich-server) y el que se encarga de «ver cosas» dentro de las imágenes para luego poder hacer búsquedas de texto en ellas (immich-machine-learning). Si podemos restringir el consumo de recursos de esos dos contenedores esto empezaría a funcionar de forma medianamente decente. ¿Cómo podemos hacer entonces?

Creo que la mejor forma de abordar este problema es decirle al docker-compose.yml que cada uno de esos contenedores sólo pueden usar una cantidad limitada de recursos del procesador. Podemos limitarlos para que usen un único núcleo, varios núcleos (definimos nosotros el número de núcleos que pueden usar) o incluso una porcion de un núcleo. Como nosotros no estamos precisamente sobrados de recursos optaremos por esta opción. El comando que usaremos en cada uno de los contenedores será el siguiente:

deploy:
  resources:
    limits:
      cpus: '0.5'  # Limita a la mitad de un núcleo

Ese «0.5» podemos ajustarlo a voluntad, pero creo que este es un valor muy adecuado para el equipo que tenemos entre manos (he hecho numerosas pruebas y a mi al menos me sirve perfectamente). Como muestra, esto es una imagen del consumo de recursos justo después de instalar immich con este comando activado.

Top mostrando consumo de CPU

Fijaos que el porcentaje de CPU nunca sube del 50% en los procesos que tienen que ver con estos dos contenedores. Aún así el «Load Average» sube bastante justo después de la instalación (durante unos minutos después de instalar immich tendrá un consumo elevado y luego el consumo será residual). Subirá también siempre que le carguemos fotos al sistema, pero al menos no serán números tan escandalosos como los que habría si dejamos a estos dos procesos campar a sus anchas.

El docker-compose.yml ya definitivo (por fin) con todos estos cambios reflejados sería el siguiente:

version: "3.8"
#
# 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:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    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
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false
    deploy:
      resources:
        limits:
          cpus: '0.5'  # Limita a la mitad de un núcleo

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # 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, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - ${MODEL_CACHE}:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false
    deploy:
      resources:
        limits:
          cpus: '0.5'  # Limita a la mitad de un núcleo

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    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
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: >-
        pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
        Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
        --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
        echo "checksum failure count is $$Chksum";
        [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      retries: 5
      start_period: 5m
    command: >-
      postgres
      -c shared_preload_libraries=vectors.so
      -c 'search_path="$$user", public, vectors'
      -c logging_collector=on
      -c max_wal_size=2GB
      -c shared_buffers=512MB
      -c wal_compression=on
    restart: always

volumes:
  model-cache:

Este sí que podéis copiarlo y pegarlo en vuestro archivo docker-compose.yml. Lo desplegaremos dentro de un momento. Guardad los cambios con la combinación de teclas Control + O y salid de nano con Control + X.

Vale, pero oye: tengo una duda. Si hago esto de limitar la potencia a estos procesos ¿El Immich no va a ir a la velocidad de un caracol cojo? Porque tampoco es plan que esto no rule. 

En absoluto. Mira: la potencia de proceso que necesita Immich siempre la necesita por la noche, cuando se hace la sincronía de los archivos. Si durante el día quieres abrir la web de Immich para ver lo que has colgado, esas visualizaciones apenas consumen capacidad de proceso de nuestra máquina. En definitiva: la máquina va a estar ociosa todo el rato y en el único momento en que la pondremos a trabajar de verdad será al subir fotos. Como le hemos limitado la capacidad de proceso, va a tardar algo más de tiempo en generar miniaturas y procesarlas pero no debería preocuparnos en exceso, porque eso lo hará cuando no estemos usando nada y gracias a los ajustes que hemos hecho no afectará a otros dockers u otros procesos de la Raspberry.

3- Creamos el archivo de variables de entorno.

Vamos a crear el archivo de variables de entorno. Como siempre, lo creamos con el comando nano .env

Pero recordad que el desarrollador ya nos dio un archivo .env preparado, que es éste.

# You can find documentation for all the supported env variables at https://immich.app/do>

# The location where your uploaded files are stored
UPLOAD_LOCATION=./library
# The location where your database files are stored
DB_DATA_LOCATION=./postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from t>
# TZ=Etc/UTC

# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=postgres

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Si os fijáis hay un montón de líneas comentadas, así que vamos a ir por a por las que nos interesan.

3.1- Carpeta de almacenaje de fotos.

La primera variable que debemos definir es ésta.

UPLOAD_LOCATION=./library

Después del símbolo «=» debemos poner la ruta hacia la que van a ir las fotos que subamos. Si recordáis, hemos definido tres rutas en el punto 1 de este tutorial. La ruta que le corresponde es la carpeta que hemos llamado «library». Simplemente aquí debemos poner la ruta hacia esa carpeta, que es la siguiente:

/home/<tu_usuario>/docker/immich/library

Es impotante acordarse de cambiar lo de <tu_usuario> por el nombre correcto para que la ruta no falle.

La línea debería quedar similar a esto (cambiando lo de <tu_usuario> por el usuario correcto, por supuesto)

UPLOAD_LOCATION=/home/<tu_usuario>/docker/immich/library
Oye... ¿pero nosotros no definíamos una variable para poner la carpeta de nuestro usuario? Algo así es lo que hacíamos en artículos anteriores. 

Efectivamente. Pero date cuenta de que esto mismo es ya una variable. Si no queremos modificar la línea del docker-compose.yml dónde se define esta variable, estamos obligados a poner aquí la ruta completa. No queda otra.

3.2- Ubicación de la base de datos.

Lo siguiente que debemos definir es la carpeta dónde se almacenará la base de datos postgres. Siguiendo el mismo razonamiento del punto 3.1 debemos sustituir la línea…

DB_DATA_LOCATION=./postgres

… por algo así:

DB_DATA_LOCATION=/home/<tu_usuario>/docker/immich/postgres

Recuerda cambiar lo de <tu_usuario> por el usuario correcto de tu raspberry.

3.3- Definición de la zona horaria.

La siguiente línea que debemos definir es la zona horaria del docker. Debemos localizar esta línea.

# TZ=Etc/UTC

Habría que quitar el símbolo «#» y poner la zona horaria en la que está el servidor.

Vale, yo estoy en pleno centro de Calahorra. ¿Cuál es la zona horaria de los calagurritanos?

Puedes sacar la lista de las zonas horarias que te admite el sistema con el comando timedatectl list-timezones, o revisar algunas que puse de ejemplo en el artículo en el que hablo de pi-hole. Por ejemplo, Calahorra tiene la zona horaria de la España peninsular, por lo que le corresponde la zona horaria Europe/Madrid. En ese caso deberíamos poner lo siguiente:

TZ=Europe/Madrid

3.4- Contraseñas de los distintos servicios.

Si os fijáis, en la última parte del archivo .env hay que definir una contraseña, un nombre para la base de datos y un nombre para el usuario de la base de datos. Me refiero a esta zona.

characters or spaces
DB_PASSWORD=postgres

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Os recomiendo cambiar todos estos valores por valores personalizados. Toda seguridad es poca cuando hablamos de contraseñas. Cambiad en esas tres líneas la parte a la derecha del signo «=» por algo aleatorio.

3.5- Ubicación de la carpeta model-cache.

En el punto 2.2.3 hemos hecho una variable llamada «model-cache» que no existe originalmente en este .env y que debemos definir a mayores. Simplemente le damos la ruta de la carpeta que hemos creado al principio. La línea a añadir debe ser algo así.

MODEL_CACHE=/home/<tu_usuario>/docker/immich/model-cache

(Como siempre, sustituye <tu_usuario> por el usuario correcto de tu Raspberry.

3.6- Archivo .env definitivo.

El archivo .env debería quedarnos al final similar a esto (cambiando lo de <tu_usuario> por el usuario correcto y poniendo contraseñas personalizadas)

# You can find documentation for all the supported env variables at https://immich.app/do>

# The location where your uploaded files are stored
UPLOAD_LOCATION=/home/<tu_usuario>/docker/immich/library
# The location where your database files are stored
DB_DATA_LOCATION=/home/<tu_usuario>/docker/immich/postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from t>
# HABILITO LA ZONA PARA PONER LA CORRECTA
TZ=Europe/Madrid

# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=miSuperMegapassw0rd

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=usuariodeimmich
DB_DATABASE_NAME=basededatosdeimmich
###################################################################################
# A PARTIR DE AQUÍ SON COSAS QUE AÑADIMOS EN LOS TUTORIALES DE FLOPY.ES
MODEL_CACHE=/home/<tu_usuario>/docker/immich/model-cache

Guardamos los cambios del archivo, como siempre, con Control + O y salimos con Control + X.

Pero recordad que el archivo .env tiene información sensible y no queremos que nadie no autorizado pueda acceder a él, así que vamos a modificar los permisos del archivo para que no haya problemas de ningún tipo. Lo haremos con el siguiente comando:

sudo chmod 600 .env

Con esto ya tenemos el Docker casi preparado, y el resto de pasos seguro que ya los sabéis por los 20 artículos anteriores de la serie de tutoriales, pero aún así vamos a recordarlos.

4- Despliegue de Immich

Por fin, después de tanto revisar código, vamos a poder realizar el despliegue de Immich. Lo realizaremos con este comando.

sudo docker-compose -p "immich" up -d

Comparado con el resto de despliegues que hemos hecho, este tiene bastantes más servicios, así que no os desesperéis si el despliegue tarda algo más de lo que podéis estar habituados. Dadle tiempo. Además, en cuanto termine, aún se pasará un ratito activando todo lo necesario para funcionar, así que sed pacientes. Después de un rato deberíais poder acceder a la web que os genera el servicio a través de esta dirección:

http://<ip.de.tu.raspberry>:2283

Bienvenida a Immich

Sin embargo aún no vamos a configurar el servicio (Nota mental: todavía tengo que daros unas indiciaciones importantes para optimizar mucho más el rendimiento antes de empezar a usarlo de verdad). Primero debemos poner esta página disponible en internet para así poder sincronizar las fotos allá dónde estemos, no sólo en nuestra casa.

5- Creamos un proxy para acceder desde fuera de nuestra red local.

Como siempre, vamos a hacer todo lo que hemos aprendido en el tutorial número 9 de la serie de tutoriales. Si no realizamos este punto, la sincronía de fotos sólo funcionará en nuestra casa (cuando nuestro móvil esté conectado por WiFi a la misma red local dónde está nuestro servidor de Immich). Voy a suponer que tal y cómo se indica en tutorial número 9 ya tenéis instalado el Nginx Proxy Manager y que tenéis un dominio configurado para poder usar un subdominio, que es dónde vamos a alojar nuestro Immich (algo así como fotos.midominio.com).

Debemos ir al panel de control de nuestro Nginx Proxy Manager. Vamos a añadir un proxy pulsando primero el botón «hosts» y luego pulsando en «proxy Hosts».

Crear un proxy paso 1

Ahora pulsaremos el botón que hay arriba a la derecha que pone Add Proxy Host.

Crear un proxy paso 2

En la pantalla que nos sale, debemos cubrir ahora los siguientes datos:

  • Domain names: ponemos un subdominio del dominio que tenemos contratado. Yo pondría algo como «fotos.midominio.com».
  • scheme: http
  • Forward Hostname / IP: ponemos la ip local del host dónde hemos hecho la instalación de Filegator (la ip local de vuestra raspberry).
  • Forward Port: 2283
Crear un proxy paso 3

Con esto ya podremos acceder a la instalación de Immich usando una dirección sin certificado (algo del tipo http://fotos.midominio.com). Sin embargo, ya sabéis que en esta web somos muy estrictos con la seguridad, así que vamos a habilitar el acceso mediante una dirección https. Para ello vamos a pulsar sobre los tres puntitos que podéis ver al final de la línea del proxy que acabamos de configurar. En el desplegable que nos sale, pulsaremos sobre Edit.

Crear un proxy paso 4

Ahora pulsamos en el desplegable de la zona «SSL Certificate» y seleccionamos la opción «Request a new SSL Certificate». Marcamos las opciones «Force SSL» y «HTTP/2 Support» y terminamos pulsando el botón «Save».

Crear un proxy paso 5

Ahora ya podremos acceder a nuestra instalación de Immich desde el subdominio que hemos creado (en el ejemplo sería https://fotos.midominio.com). Sin embargo hay aún algo más que optimizar si habéis realizado el despliegue de Immich en una Raspberry o un equipo con recursos limitados.

6- Configuración de Immich: Optimizando la instalación para equipos con pocos recursos.

Entremos ahora en la web de nuestro recién instalado Immich. Después de la pantalla de prestentación, se nos invita a crear una cuenta. Simplemente ponemos nuestros datos.

Registrar administrador
Ya te lo he dicho más veces. Tú creas cuentas a gente muy rara. ¿No conoces a alguien con un nombre normal?

¡Pero si Alex es un nombre completamente normal! En fin… Ahora veremos una pantalla de bienvenida de nuestra aplicación.

Después seleccionamos la apariencia que más nos guste.

Tema claro u oscuro

En la pantalla de privacidad, dejamos las opciones por defecto.

Configuración de privacidad

Al igual que hicimos en las opciones anteriores, no tocamos la opción de la plantilla de almacenamiento y pulsamos en «hecho».

Plantilla de almacenamiento

6.1- Ajustes de nuestro usuario.

A estas alturas ya podemos ver la interfaz de Immich. Lo primero que debemos hacer es forzar el idioma español (o el que veamos conveniente) en nuestro interfaz de usuario. Pulsamos en la inicial de nuestro nombre arriba a la derecha y luego pulsamos en «Ajustes de la cuenta».

Ajustes del usuario

Veremos un montón de opciones que podemos configurar, pero nos interesa entrar en «Ajustes de aplicación» y en «Idioma» asegurarnos que tenemos puesto el que nos interesa. El resto de opciones podemos dejarlas como están.

Ajustes de la aplicación

6.2- Ajustes generales de Immich

Ahora volvemos a pulsar en la inicial de nuestro usuario, pero esta vez nos vamos a la zona de administración. Como veréis, ahí podemos crear más usuarios para que guarden también sus fotos en nuestro sistema (pareja, hijos, padres, hermanos, amantes, amigos, amigos con derecho a roce…).

Pero lo que nos interesa de verdad ahora mismo es realizar ajustes generales para todos los usuarios. En la barra que tenemos en la parte izquierda de la pantalla, seleccionamos la opcion «Ajustes».

Menú lateral

Veremos de nuevo un montón de opciones (Sí: immich es tremendamente configurable). Lo que queremos es que este sistema no deje la Raspberry frita cada vez que se haga una subida de fotos, así que lo que haremos es buscar la zona de «Configuración de tareas» y decirle a Immich que sólo haga una cosa a la vez. Si se pone a procesar varias cosas a la vez puede que el resto de cosas que tengamos instaladas en la Raspberry se queden sin potencia de proceso, así que este ajuste nos garantiza que el sistema no se sature.

Configuración de tareas

Dentro de la zona de «Ajustes» os aconsejo también que hagáis una cosa (Aunque seguro que esto levanta polémica en los comentarios). Yo lo que haría sería desactivar el aprendizaje automático, aunque reconozco que es una pena porque es una opción que mola mucho. Con esta opción activada, puedes decirle al interfaz de Immich que busque por ejemplo bicicletas y nos mostrará todas las fotos que hemos sacado en las que haya bicicletas. Pero esta funcionalidad requiere bastante potencia de proceso al subir cada foto (Porque tiene que hacer un análisis profundo de lo que se ve en la foto). Valoradlo, pero yo os aconsejo desactivar esta opción si instaláis Immich en una raspberry (Si lo hacéis en un equipo con más potencia de proceso entonces podéis dejarlo activado).

Configuración de aprendizaje automático
Pero macho: ¿No te estás pasando un poco? Has forzado al docker a usar sólo medio núcleo, has desabilitado que se procesen varias cosas a la vez y ahora nos recortas esta función. ¿Pero tan grave es este problema del rendimiento?

A ver… he llegado a ver un equipo con dos núcleos de proceso y mega y medio de RAM colgarse por subir una carpeta grande de fotos. En los momentos previos al cuelgue, la carga de la CPU (El «load average» del comando «top») era de 14 (vamos, que había unas colas de procesos enormemente largas) y el cuelgue sucedió por no haber suficiente memoria disponible. Con estas medidas he logrado resolver el problema, así que, pese a que la raspberry tiene más núcleos (y posiblemente más memoria), prefiero aconsejaros estas opciones. No creo conveniente tener en una simple Raspberry un proceso que cargue tantísimo el procesador. Las opciones que os he recomendado evitan esta carga y permitirán hacer otras cosas mientras subís fotos.

Mira… para documentar lo que pasa en una raspberry real mientras subes fotos con estas opciones, esta es la carga que puedo ver en su CPU.

Otra vista del consumo de recursos

Como verás, es algo completamente asumible. Cuando termine la carga, la CPU volverá a valores mínimos (rozando el 0.0 de «load average»).

6.3- Ajustes de correo.

Para que Immich pueda enviarnos notificaciones de correo, debemos ir, dentro de los Ajustes generales, a la carpeta «Configuración de las notificaciones».

Configuración de las notificaciones.

Ahí debemos poner los datos de una cuenta de correo (Servidor smtp, contraseña, etc…) para que Immich pueda enviar mails a través de ella.

7- Configuración del cliente de Immich en nuestro dispositivo móvil.

Voy a daros también un par de consejos sobre la instalación de la aplicación móvil de Immich.

Lo primero que puede daros guerra es, durante la configuración, poner el nombre del servidor. Debe ser el de nuestro dominio, pero terminado en «/api«. Debéis poner algo similar a esto (cambiado el dominio por el vuestro).

https://fotos.midominio.com/api

Servidor de immich en el móvil

Ni que decir tiene que vais a tener que otorgar a Immich privilegios para acceder a toda vuestra fototeca. Pulsad al dibujo de la nube que tenéis arriba a la derecha y luego dadle acceso a todas las fotos del móvil para que pueda subir todas a vuestro servidor.

Permisos de immich en el móvil

Ahora activad la opción de «sincronizar álbumes» y seleccionad, uno a uno, todos los álbumes de fotos de vuestro dispositivo.

Seleccionar Álbumes

Si volvemos a la pantalla anterior, ahora, debajo de todo, podremos ver un botón que pone «Iniciar copia de seguridad«. Pulsamos sobre él y empezará a hacerse nuestra primera sincronía. Debemos esperar a que termine esa primera sincronía. Si no tocáis nada más, se hará una sincronía todos los días a las 12 de la noche.

Hacer copia de seguridad

Con esto tenemos por fin todo correctamente configurado y ya tenemos el servicio listo para usar. Recordad que podemos crear todos los usuarios que necesitemos para así dar servicio a nuestra familia o amigos.

8- Actualización de nuestra instalación de Immich.

Hemos realizado el despliegue de Immich, pero de vez en cuando tocará actualizar la instalación para solucionar posibles bugs del sistema o añadir funcionalidades adicionales. La forma más sencilla para actualizar únicamente Immich es crear un pequeño script con este contenido y ejecutarlo de vez en cuando.

cd /home/<tu_usuario>/docker/immich
sudo docker-compose pull
sudo docker-compose up -d --remove-orphans
sudo docker image prune -f

(Como siempre, recuerda sustituir <tu_usuario> por la carpeta correcta)

Sin embargo, si habéis sido ordenados y habéis aprovechado a instalar más dockers en la carpeta «docker«, podemos usar un script muy sencillo que recorrerá todas las subcarpetas dentro de «docker» e irá actualizando cada despliegue, uno por uno. Es muy sencillo. En la carpeta «home» de nuestro usuario tecleamos el comando «nano actualizar.sh» y pegaríamos este contenido en el archivo:

#!/bin/bash

# Actualizo el sistema operativo
sudo apt-get update -y
sudo apt-get dist-upgrade -y
sudo apt-get autoremove -y
sudo apt-get autoclean -y


# Definimos el directorio base
BASE_DIR="/home/<tu_usuario>/docker"

# Recorro todas las subcarpetas dentro del directorio base
for dir in $BASE_DIR/*; do
  if [ -d "$dir" ]; then
    echo "Procesando $dir ..."
    cd "$dir"
    sudo docker-compose pull
    sudo docker-compose up -d --remove-orphans
    sudo docker image prune -f
  fi
done

# Ya he actualizado todo. Ahora reinicio el sistema. 
sudo shutdown -r now

Luego, guardamos cambios con Control + O y salimos del editor con Control + X. Por último hacemos el script ejecutable con el comando…

sudo chmod +x actualizar.sh

Ahora, cada vez que queramos actualizar todo lo que hay en la Raspberry (Dockers incluídos), sólo tendremos que ir a la carpeta dónde hemos dejado el script y hacer un sudo ./actualizar.sh y tanto el sistema operativo como todos los dockers se actualizarán por si sólos (y al final se reiniciará el sistema).

Con esto ya tenéis los conocimientos necesarios para hacer un despliegue de Immich, tanto en máquinas potentes como en máquinas más limitadas de hardware.

Y la de pasta que me ahorraré en iCloud y similares. 

Efectivamente Usuario Anónimo. Eso es algo a tener muy en cuenta. Al fin y al cabo, es hacer una vez este despliegue y después disfrutar del servicio durante años.

Ha sido un tutorial largo, pero en el fondo, como siempre, es poco más que copiar y pegar los archivos de docker-compose.yml y .env correctos, hacerle alguna modificación al .env para personalizarlo para vuestra instalación y poco más. ¿Habéis tenido dificultades en algún punto? ¿Queréis aportar alguna nota a mayores? Espero ansioso vuestros comentarios.

Share

1 comentario

  1. Rafa

    Esto es volver por la puerta grande.
    Con las limitaciones de espacio que estamos sufriendo con servicios como Google Drive, tener un servidor de este tipo puede ser una solución maravillosa.
    Habrá que masticar esta entrada con traquilidad para entender todo lo que has puesto, que no es poco.

    En cualquier caso se agradece tu vuelta. Nos tenías mal acostumbrados a una entrada semanal y este parón no presagiaba nada bueno. Espero que haya sido por motivos de trabajo o por desconectar (que tambien es necesario).
    Bienvenido de nuevo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

© 2025 Flopy.es

Tema por Anders NorenArriba ↑

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.

ACEPTAR
Aviso de cookies