immich self-hosting ram e aggiornamenti
Guida all'uso di Immich con 6 GB di RAM. Soluzioni per errore exit 137, configurazione HTTPS sulla porta 2283 e fix per pgvecto.rs su versione v3.
What you are building
Immich is a self-hosted photo and video backup service — a real replacement for Google Photos. It has a phone app that uploads your camera roll in the background, a timeline, albums, face recognition and machine-learning search that finds "beach" or a person without you ever tagging anything. You run it on a VPS you own, the original files stay on your disk, and nobody scans them to sell you things.
The install is four containers from the project's own Docker Compose file. That part takes ten minutes. The rest of this guide is where the pain lives: the machine-learning container is memory-hungry on a small box, originals eat disk fast, the mobile app refuses a plain-HTTP server, and Immich ships breaking changes often enough that a careless docker compose pull can leave your database unable to start. Treat those four things seriously and Immich is rock-solid. Ignore them and you will lose a weekend.
Prerequisites, and the honest gotchas
- RAM: la documentazione ufficiale indica 6 GB minimi e 8 GB raccomandati — considera 4 GB più swap come il limite minimo assoluto. I container
immich-servere Postgres hanno un consumo contenuto. Il containerimmich-machine-learningè quello che consuma più risorse — carica i modelli CLIP e di face-recognition nella RAM per creare gli indici di ricerca; su una macchina con 2 GB il kernel termina il processo. Aggiungi lo swap anche se hai 4 GB. - Disk: dimensiona lo spazio per l'intera libreria, più un margine extra. Gli originali vengono copiati integralmente; inoltre Immich genera miniature e immagini di anteprima (circa un 10–20% in più). Una collezione di 200 GB richiede un volume da 300 GB. Postgres è piccolo in confronto.
- CPU: qualsiasi moderno VPS KVM è adatto, ma il Machine Learning su CPU è lento. L'indicizzazione dello smart-search per un import massivo può richiedere ore in background. È un comportamento normale; non è necessaria una GPU.
- Un nome di dominio puntato verso il VPS. L'app mobile richiede preferibilmente un endpoint HTTPS; è consigliato l'uso di un reverse proxy. La configurazione è identica a quella di una istanza self-hosted di Nextcloud con Docker, TLS e backup — Immich è l'equivalente per le foto di quel server file.
- Docker e il plugin Compose installati — Docker Engine più il plugin Compose v2 dal repository apt ufficiale di Docker, come descritto in la nostra guida ai concetti base di Docker Compose.
Step 1: Aggiungere lo swap prima di qualsiasi altra operazione
L'errore più comune di Immich su un VPS con risorse limitate è l'OOM-kill del container ML. Fornisci al kernel dello spazio aggiuntivo per gestire i picchi di memoria.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -hfree -h dovrebbe ora mostrare una riga Swap: di 4.0Gi. Questo non velocizzerà il processo ML, ma impedirà al container di interrompersi durante l'indicizzazione su una macchina da 4 GB.
Step 2: Scarica il compose e l'env ufficiali — usa i loro, non una copia
Immich blocca le versioni dei servizi e, cosa fondamentale, l'immagine del database all'interno dei file forniti. Non utilizzare un file compose copiato da un blog (incluso questo) come fonte di verità. Scarica gli asset della release:
sudo mkdir -p /opt/immich && cd /opt/immich
sudo wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
sudo wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.envQuesti file provengono dalla release taggata, quindi i riferimenti alle immagini sono corretti. Il file compose definisce quattro servizi; è utile conoscere ogni componente prima di procedere:
immich-server(ghcr.io/immich-app/immich-server, containerimmich_server) — l'API e la web UI, in ascolto sulla porta2283. Monta i caricamenti in/data.immich-machine-learning(ghcr.io/immich-app/immich-machine-learning, containerimmich_machine_learning) — ricerca CLIP e riconoscimento facciale. Memorizza i modelli scaricati in un volumemodel-cache. Questo servizio richiede molta memoria.database(containerimmich_postgres) — Postgres con l'estensione vettoriale VectorChord, che gestisce la ricerca per similarità. Il tag dell'immagine è bloccato tramite digest direttamente nel file compose, ad esempioghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:.... Le configurazioni precedenti utilizzavanopgvecto.rs; il supporto è stato rimosso in Immich v3.0, quindi qualsiasi installazione attuale utilizza VectorChord. Non modificare mai manualmente questo tag.redis(containerimmich_redis) — un'istanza Valkey/Redis per le code di job.
Step 3: Configurare .env — dove risiedono le foto e il database
Apri .env e imposta quattro parametri. Tutto ciò che si trova sotto la linea marcata deve rimanere invariato.
# Where original uploads are stored on the host
UPLOAD_LOCATION=/opt/immich/library
# Where the Postgres data lives. NEVER put this on an NFS/network share.
DB_DATA_LOCATION=/opt/immich/postgres
# "v3" is a floating tag that tracks the latest v3.x. Pin a full tag like
# v3.0.2 instead — then you upgrade on purpose, not by surprise.
IMMICH_VERSION=v3.0.2
# Change this to a long random string. Letters and digits only.
DB_PASSWORD=REPLACE_WITH_A_LONG_RANDOM_STRING
# Set your timezone so timestamps and "on this day" line up
TZ=Europe/London
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immichDue regole per evitare problemi. UPLOAD_LOCATION deve puntare al disco di grandi dimensioni: se aggiungerai un volume dati in seguito, imposta fin dall'inizio il percorso di mount di tale volume, poiché spostarlo in un secondo momento comporterebbe lo spostamento delle miniature e l'aggiornamento dei percorsi degli asset. DB_DATA_LOCATION deve trovarsi su disco locale: l'installazione di Postgres su una share NFS o SMB causa corruzione dei dati, come indicato esplicitamente nella documentazione. Se utilizzi solo lettere e cifre in DB_PASSWORD eviterai una serie di bug relativi all'escaping delle connection-string.
Step 4: Primo avvio e creazione dell'utente admin
cd /opt/immich
sudo docker compose up -d
sudo docker compose psIl risultato corretto consiste in quattro container, tutti running e infine healthy:
NAME STATUS
immich_machine_learning Up (healthy)
immich_postgres Up (healthy)
immich_redis Up (healthy)
immich_server Up (healthy)Il primo up scarica diversi gigabyte di immagini; attendere il completamento. Monitorare il progresso con sudo docker compose logs -f immich-server; il server logga l'ascolto sulla porta 2283 una volta pronto. Aprire ora http://YOUR_SERVER_IP:2283 in un browser. La prima visita mostra la procedura guidata Getting Started — il primo account creato sarà l'admin. Impostare una password sicura; questo account gestisce le impostazioni del server, la gestione utenti e la configurazione ML necessaria in seguito.
Step 5: L'app mobile e il backup in background
Installa "Immich" dall'App Store o dal Play Store. Nella schermata di login viene richiesto il Server Endpoint URL. Inserisci l'URL completo includendo lo schema, ad esempio https://photos.example.com (l'app aggiunge automaticamente /api). Accedi con l'account appena creato, quindi apri la schermata Backup dell'app, seleziona gli album da proteggere (solitamente Camera e Screenshots) e attiva il Background backup. Su iOS, il backup in background è limitato dal sistema operativo: i caricamenti in foreground sono sempre attivi, quelli in background avvengono quando il sistema lo consente.
Questo è il punto in cui si verificano i problemi, quindi leggi lo Step 6 prima di tentare soluzioni manuali sull'app.
Step 6: HTTPS tramite un reverse proxy — e la regola del full-URL
L'app mobile richiede HTTPS. Posiziona un reverse proxy davanti alla porta 2283 per gestire la terminazione TLS. Se utilizzi già diversi container, Traefik con TLS automatico per più app Docker è l'opzione più ordinata: un blocco di label instrada photos.example.com verso il container immich-server e gestisce il certificato automaticamente. Se preferisci nginx, la guida Let's Encrypt con Certbot e nginx fornisce il certificato e un blocco proxy_pass http://127.0.0.1:2283;. Una configurazione del proxy è fondamentale per Immich: aumenta il limite della dimensione massima di upload, poiché i video degli smartphone sono grandi. In nginx, questo parametro è client_max_body_size 50000M; all'interno del server block; il valore predefinito di 1 MB causa l'errore 413 Request Entity Too Large durante l'upload dei video.
La regola applicata dall'app: l'endpoint deve essere raggiungibile e, nella pratica, deve utilizzare HTTPS. Gli endpoint http://, o un indirizzo IP diretto senza porta, causano l'errore "the app cannot reach the server" — descritto sotto come errore specifico.
Step 7: External libraries vs uploads — importazione di un albero di foto esistente
Esistono due modalità per inserire le foto in Immich, che sono differenti tra loro.
- Uploads sono asset gestiti da Immich. L'app o il caricatore web copia il file in
UPLOAD_LOCATION. Immich può rinominare, spostare e eliminare questi file. - External libraries sono importazioni in sola lettura di file già presenti in una cartella sul server — ad esempio un vecchio albero
Pictureso un export da NAS. Immich indicizza i file nella posizione originale e li mostra nella timeline, ma non modifica né elimina mai gli originali.
Per importare un albero esistente, montalo in sola lettura nel container del server. Modifica docker-compose.yml sotto immich-server: e aggiungi un volume:
immich-server:
volumes:
- ${UPLOAD_LOCATION}:/data
- /etc/localtime:/etc/localtime:ro
- /srv/photos:/mnt/media/photos:roIl flag :ro garantisce che Immich non possa mai toccare gli originali. Ricrea il container con sudo docker compose up -d, quindi nell'interfaccia web vai sul tuo avatar → Administration → External Libraries → Create Library, seleziona l'utente proprietario, clicca su Add sotto Folders e inserisci il percorso del container — /mnt/media/photos, non il percorso host /srv/photos. Clicca su Scan. L'errore più comune con le external libraries è usare il percorso host invece del percorso del container; in questo caso la scansione non trova nulla e riporta zero asset.
Step 8: La disciplina di aggiornamento richiesta da Immich
Questa fase distingue un'installazione Immich funzionante da una corrotta. Immich rilascia aggiornamenti rapidamente e non applica correzioni retroattive (backport) né supporta il downgrade. Seguire ciecamente il tag mobile v3 causerà inevitabilmente errori nel database. La disciplina consiste nel:
- Fissare una versione. Mantenere
IMMICH_VERSIONimpostato su un tag specifico comev3.0.2, evitando il tag mobilev3che scarica sempre l'ultima versione v3.x. - Leggere le release notes ogni volta prima di aggiornare. Le modifiche che rompono la compatibilità (breaking changes) — specialmente quelle relative al database o alle estensioni vector — sono indicate nelle note. L'esempio è il rilascio v3.0: ha rimosso completamente pgvecto.rs, quindi chi utilizzava la vecchia estensione doveva completare la migrazione a VectorChord (introdotta con la v1.133) prima di procedere.
- Effettuare prima il backup del database (Step 9). Sempre, ma con maggiore attenzione se le note menzionano il database.
- Scaricare anche il nuovo file compose.
IMMICH_VERSIONfissa solo le immagini server e ML. L'immagine Postgres è fissata tramite digest all'interno didocker-compose.yml; pertanto, una versione che richiede un'estensione del database più recente include un nuovo file compose. Scarica entrambi i file di rilascio, riapplica i tuoi valori.enve poi aggiorna. - Aggiornare i client mobile nello stesso periodo. Il server comunica solo con la sua stessa versione major; l'app supporta la versione major corrente e quella precedente. Un server con una versione superiore all'app mostra l'errore
Your app major version is not compatible with the server!sul telefono finché non viene aggiornata l'app; per sicurezza, è preferibile aggiornare prima l'app.
I comandi effettivi, una volta ottenuti i nuovi file:
cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image pruneStep 9: Backups — un dump del database PIÙ gli originali, e testalo
Il backup di Immich è composto da due elementi; uno senza l'altro è inutile. Il database contiene la struttura degli album, i volti, gli indici di ricerca e la mappatura dagli asset ai file. La directory originals contiene le foto reali. Ripristinare un elemento senza l'altro produce foto senza organizzazione o un guscio vuoto che punta a file mancanti.
Esegui il dump del database con pg_dump dall'interno del container Postgres — specificamente il database immich, non l'intero cluster:
sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
--dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gzSuccessivamente esegui il backup di UPLOAD_LOCATION — l'intero albero /opt/immich/library, in particolare le sottocartelle library/, upload/ e profile/ — utilizzando restic, rsync o borg su un'altra macchina o su un object storage. Esegui prima il database e poi i file, in modo che il dump non faccia riferimento a una foto che il backup dei file non ha ancora copiato. Le librerie esterne vanno salvate separatamente alla loro sorgente originale; Immich non ne è proprietaria.
Ora la parte che tutti saltano: testa il ripristino. Un ripristino deve essere eseguito su uno stack nuovo il cui server non sia mai stato avviato, su un'immagine Postgres la cui estensione vector sia compatibile con il dump — questo è il motivo per cui non bisogna mai improvvisare il tag dell'immagine del DB. Su una macchina di prova con lo stesso compose e .env, elimina ogni stato precedente, avvia solo il database, quindi carica il dump:
cd /opt/immich
sudo docker compose down -v
sudo docker compose pull
sudo docker compose create
sudo docker start immich_postgres
sleep 10
gunzip --stdout immich-db-2026-07-15.sql.gz |
sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" |
sudo docker exec -i immich_postgres psql --dbname=immich --username=postgres --single-transaction --set ON_ERROR_STOP=on
sudo docker compose up -dLa riscrittura sed di search_path non è opzionale su un database VectorChord — se la ometti, il ripristino si interrompe a metà. Quando lo stack è attivo con gli originali al loro posto, apri la web UI: se le foto e gli album sono presenti, il backup funziona. Se non hai mai eseguito questa operazione, non hai un backup — hai solo una speranza.
Modalità di errore e stringhe visualizzate
Il container ML viene terminato per OOM-kill. sudo docker compose logs immich-machine-learning termina bruscamente, docker compose ps indica che Restarting, e il codice di uscita è 137. sudo dmesg | grep -i oom lo conferma: Out of memory: Killed process ... (python3). I processi di ricerca e riconoscimento facciale si bloccano. La causa è la RAM insufficiente per i modelli. Soluzioni, in ordine: aggiungere swap (Step 1); aumentare la RAM del VPS; oppure, se non è possibile, disabilitare il ML in Administration → Settings → Machine Learning Settings disattivando Smart Search e Facial Recognition — i backup e gli album rimangono, ma si perde la ricerca per contenuto. Rimuovere il servizio immich-machine-learning dal file compose produce lo stesso effetto.
Postgres non si avvia dopo un upgrade. Il log del server riporta un ciclo con una riga simile a The database currently has VectorChord 0.5.3 activated, but the Postgres instance only has 0.4.2 available. This most likely means the extension was downgraded. — o, su stack datati, The pgvecto.rs extension is not available in this Postgres instance.. La causa è un'immagine del database con una versione dell'estensione inferiore rispetto ai dati aggiornati; accade quasi sempre modificando manualmente il tag dell'immagine o ripristinando un dump recente su un'immagine vecchia. La soluzione è utilizzare l'immagine Postgres corrispondente — utilizzare il file compose della release compatibile con il database, non effettuare il downgrade, e ripristinare solo su un'immagine compatibile.
L'app mobile non raggiunge il server. La schermata di login mostra un errore di connessione / Server is not reachable dopo l'inserimento dell'URL. Tre cause possibili: è stato digitato http:// dove il proxy serve solo https://; ci si è connessi direttamente al backend omettendo la porta, tentando così la example.com (porta 443) invece della example.com:2283; oppure il reverse proxy non sta inoltrando /api. Risolvere inserendo l'URL completo di https://photos.example.com e verificando che sia caricabile sul browser di uno smartphone. Se il browser funziona ma l'app no, il proxy sta rimuovendo il path o il certificato è self-signed — l'app rifiuta certificati non attendibili.
Disco esaurito durante l'importazione. I caricamenti falliscono, le miniature diventano bianche e i log mostrano ENOSPC: no space left on device o, da Postgres, could not extend file ... No space left on device. df -h mostra il volume UPLOAD_LOCATION al 100%. Per questo è necessario dimensionare il disco prima di importare una libreria ampia. Recuperare collegando un volume più grande, arrestando lo stack, spostando UPLOAD_LOCATION su di esso, aggiornando .env e riavviando — oppure espandere il disco esistente se il provider lo consente. Postgres può bloccarsi se il disco è pieno; liberare spazio e riavviare il container del database prima di ipotizzare una corruzione dei dati.
FAQ
Di quanta RAM e disco ha bisogno Immich?
I requisiti ufficiali di Immich sono 6 GB di RAM minimi e 8 GB raccomandati. Il limite pratico per una piccola libreria è di 4 GB con swap; si consiglia di configurare sempre lo swap perché il container machine-learning causa picchi di utilizzo. Per il disco, prevedi lo spazio per l'intera libreria più circa il 10–20% per le miniature e le anteprime generate su storage locale. Non installare mai la directory dei dati di Postgres su una share di rete. Se stai valutando altri servizi, la guida a cosa auto-ospitare nel 2026 confronta l'impatto di Immich con altri servizi.
Posso eseguire Immich senza una GPU?
Sì. Il container machine-learning funziona correttamente su CPU. Una GPU accelera solo l'indicizzazione dello smart-search e, con l'immagine corretta, il transcoding video. Su CPU, l'indicizzazione iniziale di una libreria numerosa può richiedere ore in background, ma non blocca i backup o la navigazione. Se il sistema è troppo limitato per il ML, è possibile disabilitare Smart Search e Facial Recognition nelle impostazioni di amministrazione mantenendo tutte le altre funzioni.
Come posso aggiornare Immich in sicurezza?
Fissa IMMICH_VERSION a un tag specifico come v3.0.2, leggi le release notes prima di ogni aggiornamento e esegui prima il backup del database. Poiché l'immagine Postgres è fissata all'interno di docker-compose.yml invece che tramite IMMICH_VERSION, scarica nuovamente sia il file compose che example.env dalla versione desiderata e riapplica i tuoi valori, quindi esegui docker compose pull && docker compose up -d. Non lasciare mai che la versione sia variabile: Immich include modifiche che rompono la compatibilità e non supporta il downgrade.
Cosa devo esattamente backuppare?
Due elementi insieme: un pg_dump del database immich e l'intera directory UPLOAD_LOCATION degli originals. Il database contiene album, volti e la mappatura tra asset e file; la directory contiene le foto reali. Il ripristino richiede entrambi, oltre a un'immagine del database con un'estensione vettoriale compatibile. Esegui prima il dump del database e successivamente la copia dei file; testa il ripristino su un sistema di prova almeno una volta. Un backup non testato non è un backup.
Come posso importare la mia cartella foto esistente?
Monta la cartella in modalità sola lettura nel container immich-server come volume extra (ad esempio - /srv/photos:/mnt/media/photos:ro), ricrea il container e poi, in Administration → External Libraries, crea una libreria e aggiungi il percorso del container /mnt/media/photos. Immich indicizza i file sul posto e non li modifica né li elimina mai. L'errore più comune è inserire il percorso dell'host invece del percorso del container, rendendo la scansione inefficace.