El mejor gestor de fotos autohospedado

Durante mucho tiempo he ido guardando las fotos que hacía, primero con varias cámaras digitales, posteriormente con distintos móviles en un directorio (o varios) de mi ordenador (posteriormente de alguno de los NAS que he montado). Preservar las fotos es algo que es muy importante para mi, son recuerdos enlatados que te permiten revivir los buenos (o no tan buenos) momentos del pasado y que sería traumático perder del todo.

El caso es que para poder clasificarlas, al menos por fecha, he estado usando varias opciones, google nos permitía guardar las fotos en una resolución menguante, aunque decía que así eran ilimitadas, hubo un momento en que Amazon ofreció lo mismo, pero se perdió en la bruma del tiempo, flickr y 500px se volvieron de pago y solo eran para fotos públicas. Finalmente termine utilizando el programa shotwell para ubuntu que me permitía importar las fotos nuevas y guardarlas en local… Synology también tenía su propio programa de fotografías pero era… muy malo.

Hasta que finalmente descubrí immich. Este sistema, open source completo, te permite guardar, organizar y gestionar tus fotos y videos fácilmente sin sacrificar privacidad. Te comento aquí los pasos más sencillos para tenerlo funcionando:

Básicamente tienes que tener un host o máquina virtual que tenga, al menos, 4Gb de memoria, un montón de disco duro para guardar todas las imágenes, docker y docker compose instalados.

Luego hay ciertas cosas que podrías querer hacer con IA y para las que podría venir bien tener una tarjeta gráfica… Pero eso es otra historia que no vamos a contar aquí.

Este sería el docker-compose.yml


name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    volumes:
      - ${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
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:8-bookworm@sha256:fec42f399876eb6faf9e008570597741c87ff7662a54185593e74b09ce83d177
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    restart: always

volumes:
  model-cache:

Luego hay que crear un .env con los valores personalizados para nuestra instalación:


UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
TZ=Europe/Madrid
IMMICH_VERSION=release
DB_PASSWORD=pon-aqui-un-password-para-postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Obviamente elige el directorio que quieras para la bbdd y de donde vas a guardar las fotos y… Ya estaría.

docker compose up -d

Y ya tendrías una instalación vacía de immich lista para empezar a jugar. Lo primero que tendrás que hacer es crear la primera cuenta del sistema, que será de administración conectando con http://<dir-ip>:2283. A partir de ese momento ya podrás empezar a subir fotos como si no hubiese un mañana… De hecho puedes subir directorios enteros. Eso si, el tratamiento de las fotos tarda un poco porque se dedica a recopilar los datos internos de las fotos y a reconocer caras (para que luego puedas navegar por ellas), pero una vez que ya ha cogido ritmo cada foto subida va más rápido.

¿Qué más?

Es muy recomendable usar la aplicación móvil para sincronizar las fotos del teléfono con immich automáticamente, os dejo las direcciones para Android y iphone:

Cuando arranquéis la app os pedirá que pongáis la dirección de vuestro servidor (si tenéis una ip local solo funcionará dentro de vuestra red) y luego os pedirá que os autentiqueis momento a partir del cual ya podréis hacer copia de seguridad de los albumes que queráis de vuestro móvil (yo solo subo los de la cámara, whatsapp y demás no son demasiado «preservables»).

Y con esto ya estaría todo (salvo que queráis poner un proxy inverso para acceder desde fuera de vuestra red o un tunel de cloudflare o similar)… Eso si, reservad disco suficiente porque vais a necesitarlo…

Instala tu propia perplexity ia (perplexica)

Uno de los sistemas de IA más completos para las actividades diarias es perplexity.ia un sistema que no solo responde preguntas (usando varios proveedores de IA) sino que realiza una búsqueda en internet previa de los conceptos principales por los que estamos preguntando.

El problema principal es que, además de que es un sistema de pago, que todos los datos se los estamos pasando a una empresa que, a pesar de los términos y condiciones que nadie se lee, es posible que esté usando nuestros datos para sus propios fines. Sin embargo, he descubierto que hay un sistema open source que te permite montar un sistema similar a perplexity… El nombre ya da alguna pista: preplexica.

El repositorio principal lo podéis encontar aquí: https://github.com/ItzCrazyKns/Perplexica

En este post vamos a ver cómo utilizar el montaje que hicimos en un post anterior: Como tener tu propia IA en casa donde terminamos teniendo un servidor ollama para tener instalados los modelos open source que queramos y un servidor webui para poder interrogar a los modelos. Lo primero que vamos a hacer es modificar el docker-compose.yml para compartir el puerto por el que hablar con ollama de esta manera:

    ports:
      - "11434:11434"

Esto hace que ya esté disponible desde fuera del contenedor los modelos de ollama. Lo siguiente que tenemos que hacer es bajarnos el repositorio de Perpléxica

git clone https://github.com/ItzCrazyKns/Perplexica
cd Perplexica
cp sample.config.toml config.toml

Dado que el puerto 3000 que es en el que se ejecuta el servidor ya está ocupado por nuestro servicio webui vamos a cambiarlo al 3001 en el archivo docker-compose.yml que hay dentro del directorio Perplexica y lo dejaremos así (el otro puerto que utiliza es el 4000, si ese lo tenemos ocupado podemos cambiarlo en el otro servicio):

    ports:
      - 3001:3000

Luego modificaremos el archivo config.toml que copiamos anteriormente y modificaremos esta parte:

[MODELS.OLLAMA]
API_URL = "http://192.168.1.34:11434"

Poniendo la IP de la máquina en la que se está ejecutando. Ya solo tenemos que levantar el docker… docker compose up -d y conectar con http://localhost:3001 y ya tendremos nuestro intefaz de búsqueda

En la configuración (icono de abajo a la izquierda) podemos configurar los modelos que queremos utilizar:

Y si tenemos Claves de APIs de pago podemos incluirlas igualmente:

Y, con esto ya podremos empezar a preguntar a nuestro nuevo sistema de búsqueda (lo que tarde dependerá más del modelo elegido que de las búsquedas). Lo bueno es que puedes decirle que busque imágenes y videos a la vez:

Así que, ya sabéis, si tenéis una tarjeta gráfica lo suficientemente potente para correr un modelo de AI interesante, podéis mezclarlo con las búsquedas por internet de varias fuentes de una manera muy sencilla..

Usando GPU en Proxmox

Quizá todavía no lo conceis, pero Proxmox es el software definitivo si queréis montar vuestra propia infraestructura en casa (o en vuestra empresa), es un hypervisor que os permite tener vuestra propia «nube» creando máquinas virtuales, contenedores y gestionando almacenamiento, backups y alta disponibilidad.

Yo llevo unos meses con esto, desde que me compré y quise dar uso, unas placas chinas para aprovechar los Xeon de segunda mano que ahora se encuentran tan baratos y, la verdad, es como tener un AWS particular (salvando muuuuchas diferencias). El caso es que lo único que me quedaba por probar era cómo tener una máquina virtual controlada por proxmox que me permitiese hacer AI… Pero para eso necesitaba usar una GPU y esto no es taaan sencillo. Así que partamos de un servidor que tiene una tarjeta gráfica (en mi caso una RTX 3070) y veamos cómo configurar el ordenador para meterlo en un cluster proxmox estando preparado para tener VMs que usen esa GPU.

¿cual es el problema realmente?

El problema es que un hypervisor lo que hace es ejecutar máquinas virtuales a las que ha asignado cierta parte de sus recursos (disco, memoria, etc) y permitir el uso compartido de todo lo que se puede compartir. Por desgracia la GPU no se puede compartir de la misma manera que una CPU (hay algunos modelos que tienen una tecnología que se llama VGPU que parece que si permitirán hacerlo, pero por ahora las que tengo yo no). Es por eso que lo que se hace es pasarle a la máquina virtual todo el bus PCI en cuestión para que lo gestione de manera independiente. Para que esto se pueda llevar a cabo es importante que el SO de proxmox no esté usando este bus para nada (que no tenga los drives instalados siquiera). El servidor que yo he usado tenía video integrado y configuré la bios para que usase ese como video primario (y así instalé proxmox sin utilizar la tarjeta gráfica). Pasos importantes con la BIOS:

  • Activar la tarjeta integrada (si la tiene)
  • Activar todos los modos de multihilo VT-d y cualquier referencia a IOMMU

Dejo un enlace que lo explica para varias placas base.

Lo siguiente, desde el servidor con ya proxmox instalado será editar el arranque de grub poniendo lo siguiente en el archivo /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

Y ejecuta después update-grub, tras lo cual tendrás que reiniciar la máquina.

Para comprobar que está todo activo ejecuta este comandos:

dmesg | grep -e DMAR -e IOMMU

El resultado tendría que ser algo como esto:

[    0.008366] ACPI: DMAR 0x000000007A29ED38 0000A8 (v01 INTEL  EDK2     00000002      01000013)
[    0.008390] ACPI: Reserving DMAR table memory at [mem 0x7a29ed38-0x7a29eddf]
[    0.098662] DMAR: IOMMU enabled
[    0.255710] DMAR: Host address width 39
[    0.255711] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.255721] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap 1c0000c40660462 ecap 19e2ff0505e
[    0.255723] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
[    0.255727] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008c40660462 ecap f050da
[    0.255728] DMAR: RMRR base: 0x00000079d2f000 end: 0x00000079d4efff
[    0.255731] DMAR: RMRR base: 0x0000007b800000 end: 0x0000007fffffff
[    0.255733] DMAR-IR: IOAPIC id 2 under DRHD base  0xfed91000 IOMMU 1
[    0.255734] DMAR-IR: HPET id 0 under DRHD base 0xfed91000
[    0.255735] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[    0.257485] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.600499] DMAR: No ATSR found
[    0.600500] DMAR: No SATC found
[    0.600501] DMAR: IOMMU feature fl1gp_support inconsistent
[    0.600502] DMAR: IOMMU feature pgsel_inv inconsistent
[    0.600503] DMAR: IOMMU feature nwfs inconsistent
[    0.600504] DMAR: IOMMU feature pasid inconsistent
[    0.600505] DMAR: IOMMU feature eafs inconsistent
[    0.600506] DMAR: IOMMU feature prs inconsistent
[    0.600507] DMAR: IOMMU feature nest inconsistent
[    0.600508] DMAR: IOMMU feature mts inconsistent
[    0.600509] DMAR: IOMMU feature sc_support inconsistent
[    0.600509] DMAR: IOMMU feature dev_iotlb_support inconsistent
[    0.600510] DMAR: dmar0: Using Queued invalidation
[    0.600513] DMAR: dmar1: Using Queued invalidation
[    0.600990] DMAR: Intel(R) Virtualization Technology for Directed I/O

Donde lo relevante es el IOMMU enabled y Enabled IRQ remmaping. Si todo está ok podemos ver os grupos iommu con este comando:

pvesh get /nodes/pascal/hardware/pci --pci-class-blacklist ""

Que nos debería dar una salida como la siguiente:

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? class    ? device ? id           ? iommugroup ? vendor ? device_name                                                                             ? mdev ? su
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
...
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? 0x030000 ? 0x2484 ? 0000:01:00.0 ?          2 ? 0x10de ? GA104 [GeForce RTX 3070]                                                                ?      ? 0x
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

Ahora nos falta asegurarnos de que proxmox no va a utilizar esta gpu y estaríamos casi listos para crear nuestra vm:

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf
echo "vfio" >> /etc/modules
echo "vfio_iommu_type1" >> /etc/modules
echo "vfio_pci" >> /etc/modules
update-initramfs -u -k all
systemctl reboot

Comprobaremos que se carga vfio y pondremos en lista negra los drivers de nuestra gpu

dmesg | grep -i vfio
echo "options kvm ignore_msrs=1 report_ignored_msrs=0" > /etc/modprobe.d/kvm.conf
lspci -nn | grep 'NVIDIA'

Veremos los ids de nuestro dispositivo

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)

Y los usaremos para ponerlos en lista negra para los drivers posibles:

echo "options vfio-pci ids=10de:2484,10de:228b" >> /etc/modprobe.d/vfio.conf
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidiafb" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia_drm" >> /etc/modprobe.d/blacklist.conf
systemctl reboot

Y con esto ya está listo nuestro proxmox para compartir el PCI… Os recomiendo que si vais a unirlo a un cluster lo hagáis ahora, luego si creais una vm os va a ser más complicado. En cualquier caso, lo que queda es crear una máquina virtual y añadirle el pci de la tarjeta.

Para ello simplement creamos una máquina virtual, en mi caso digo que voy a instalar un linux y antes de arrancarla vamos al apartado de hardware y añadimos estos PCI:

Una vez arrancada la máquina e instalado el sistema operativo podemos comprobar si tenemos los drivers de nvida configurados ejecutando nvidia-smi

Así que ya tenemos una máquina con GPU para poder ejecutar nuestros trabajos de AI. Para ello podéis seguir estas instrucciones para instalar ollama o stable difussion en esta máquina virtual… Con la ventaja que aporta tenerlo controlado por Proxmox para hacer backups arrancarlo o pararlo a voluntad, monitorizarlo, etc.

Monta un nodo bitcoin en 5 minutos

Bueno, cinco minutos es lo que dedicarás a configurar el software, pero luego tendrá que bajarse todo el blockchain y tardará una eternidad y se comerá todo el disco duro que tengamos disponible, pero bueno, vamos a intentar montar un nodo completo bitcoin para testnet (estamos probando) de manera que podamos hacerle consultas sin tener que llamar a otros servicios.

En un próximo post ya os contaré como hacer un explorador completo (con las mismas restricciones de tiempo que este). Por ahora vamos a preparar los materiales. Vamos a necesitar una máquina con ubuntu (o el sistema operativo de vuestra preferencia) y unos 200Gb de disco (para testnet, si queremos la blockchain de mainnet serán como 800Gb). Yo, en mi caso lo he hecho sobre un contenedor ubuntu en proxmox (ya os contaré qué tal con proxmox cuando tenga un rato).

Para crear mi contenedor he usado un script de la comunidad (aqui) pero vosotros podéis usar un ordenador de casa o una máquina virtual que pueda ejecutar docker y docker compose.

Yo la he configurado con 4 CPUs y 4Gb de memoria y me ha servido perfectamente. No os olvidéis de tener los 200Gb disponibles y montados en algún sitio de vuestra máquina. Una vez que tenemos docker y docker compose instalados y funcionando solo tenemos que crear un docker-compose.yml con este contenido:

services:
  bitcoin-testnet:
    image: bitcoin/bitcoin:28.0rc1
    container_name: bitcoin-testnet
    ports:
      - "18443:18443"
      - "18444:18444"
    command:
      - -printtoconsole
      - -testnet=1
      - -rest
      - -rpcbind=0.0.0.0
      - -rpcallowip=0.0.0.0/0
      - -rpcport=18443
      - -rpcuser=miusuario
      - -rpcpassword=mipass
      - -server
      - -txindex
    volumes:
      - /bitcoin-data:/home/bitcoin/.bitcoin
    restart: always

En este caso nos vamos a bajar una imagen preconfigurada de bitcoin (aunque si no os fiáis siempre podéis compilar la vuestra sacando el Dockerfile de github. Abriremos los puertos 18443 y 18444 para poder acceder al nodo desde fuera (recordad, si tenéis nat hacer una redirección del puerto en el router). Además, tenemos nuestro disco con 200Gb en el directorio /bitcoin-data y lo montamos en /home/bitcoin/.bitcoin en la imagen.

Las siguientes opciones son para ver el log en consola, usar testnet, activar el RPC por rest y enlazarnos con todas las IPs de la imagen. Además, configuramos que se usará un usuario miusuario con password mipass, se ejecutará como servidor y vamos a mantener índices de todo el blockchain…

Y con esto ya podemos lanzarlo:

docker compose up -d

Si todo va bien en unas cuantas (muchas) horas ya tendríamos una copia de la blockchain de testnet y podremos preguntar, por ejemplo, cual es el último bloque (suponiendo que nuestra máquina tenga la IP 192.168.1.55) usando curl, por ejemplo:

curl --user miusuario:mipass --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' http://192.168.1.55:18443

Que nos devolvería algo como esto (el número de bloque, obviamente) será distinto en vuestro caso:

{"result":3774033,"error":null,"id":"curltest"}

Y, lo dicho, intentaré que el próximo post sea de cómo hacer un explorador de testnet que podamos utilizar via web… Id preparando más disco duro.

Generar imágenes por IA en tu propio ordenador

Ya vimos en la entrada anterior como poder tener nuestro propio chat-gpt sin pagar nada a nadie usando modelos opensource y nuestra GPU, ahora le toca el turno a la posibilidad de generar imágenes por Inteligencia Artificial mediante el mismo método, en casa, de forma privada y sin tener que pagar licencias. Al lío…

La imagen anterior ha sido generada en mi ordenador, con mi tarjeta gráfica y con un prompt muy sencillito, básicamente le he pedido un robot pintando con pinceles en la pantalla del ordenador… Y me ha salido esto (hay más parámetros, pero no he tocado nada especial). Para generar estas imágenes vamos a utilizar Stable Diffussion, que es un modelo de aprendizaje automático para generar imágenes digitales de alta calidad a partir de descripciones en lenguaje natural (wikipedia). Es de código abierto y no impone restricciones a las imágenes que produce.

Como somos hombres (y mujeres) de acción os voy a dar la receta rápida para tener stable difussion y un interfaz de usuario (automatic1111) funcionando en cuestión de minutos (bueno, esto depende de vuestra conexión a internet que hay muchos gigas que descargarse). La receta original, que os recomiendo seguir si queréis experimentar un poco más con el tema, la saqué de aquí: https://github.com/AbdBarho/stable-diffusion-webui-docker pero yo he preparado una imagen que ya tiene todo lo necesario, así que lo único que tenéis que hacer es crear un archivo docker-compose.yml con este contenido:

services:
  sd-auto:
    image: yoprogramo/sd-auto:78
    ports:
      - "7860:7860"
    volumes:
      - ./data:/data
      - ./output:/output
    stop_signal: SIGKILL
    environment:
      - CLI_ARGS=--allow-code --medvram --xformers --enable-insecure-extension-access --api
      - COMMANDLINE_ARGS=--share
    restart: unless-stopped
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids:
                - "0"
              capabilities:
                - compute
                - utility

Luego, estoy suponiendo que usáis linux y tenéis la configuración de docker y de la tarjeta gráfica que ya vimos en el anterior post, solo hay que ejecutar:

docker compose up -d

Como os he dicho el proceso de descarga inicial de la imagen y del modelo van a tardar un poco (reservaos mínimo 20Gb para todo), pero si todo va bien en unos minutos podréis acceder a la url http://localhost:7860 y veréis la interfaz de AUTOMATIC1111 para stable difussion.

Inicialmente el modelo descargado es sdv1.5-pruned-emaonly que tiene sus limitaciones pero cabe en casi todas la memorias. Ya solo queda hacer la prueba, poniendo algo en el prompt y dandole a Generate.

Si no tienes demasiada memoria en tu tarjeta gráfica te saldrá algo como esto:

Pero si has sido capaz de generar una imagen, se abre todo un abanico de modelos que probar y opciones con las que trastear… El primer sitio para visitar es este:

https://civitai.com