Immich zelf hosten: RAM-vereisten en veilige updates
Ontdek waarom Immich minimaal 6 GB RAM vereist om exit 137 fouten te voorkomen. Wij leggen uit hoe u poort 2283 beveiligt met HTTPS en wat u doet bij database-fouten in v3.
Wat u bouwt
Immich is een zelfgehoste back-upservice voor foto's en video's, een volwaardig alternatief voor Google Photos. Het beschikt over een mobiele app die uw filmrol op de achtergrond uploadt, een tijdlijn, albums, gezichtsherkenning en een zoekfunctie op basis van machine learning die "strand" of een persoon vindt zonder dat u zelf iets hoeft te taggen. U draait het op een VPS in eigen beheer, de originele bestanden blijven op uw schijf staan en niemand scant ze om u advertenties te tonen. Als u nog twijfelt tussen dit en het andere voor de hand liggende alternatief, zet onze vergelijking tussen PhotoPrism en Immich hun RAM-vereisten, mobiele apps en back-upcommando's naast elkaar.
De installatie bestaat uit vier containers op basis van het Docker Compose-bestand van het project zelf. Dat deel kost tien minuten. De rest van deze handleiding behandelt de uitdagende aspecten: de machine-learning-container is geheugenintensief op een kleine server, originelen verbruiken snel schijfruimte, de mobiele app weigert een verbinding met een server zonder TLS, en Immich brengt regelmatig ingrijpende wijzigingen uit waardoor een onvoorzichtige docker compose pull ertoe kan leiden dat uw database niet meer start. Neem deze vier punten serieus en Immich is uiterst stabiel. Negeert u ze, dan kost het u een heel weekend.
Vereisten en de eerlijke valkuilen
- RAM: de officiële documentatie vermeldt 6 GB als minimum en 8 GB als aanbevolen, beschouw 4 GB plus swap als de absolute ondergrens. De
immich-server- en Postgres-containers zijn bescheiden. Deimmich-machine-learning-container is de grootste verbruiker; deze laadt CLIP- en gezichtsherkenningsmodellen in het RAM om zoekindexen op te bouwen. Op een systeem met 2 GB beëindigt de kernel het proces. Voeg swap toe, zelfs als u 4 GB RAM heeft. - Schijfruimte: reserveer ruimte voor uw volledige bibliotheek, plus extra. Uw originelen worden volledig gekopieerd en Immich genereert daarnaast miniaturen en voorbeeldafbeeldingen (ongeveer 10–20% extra). Een fotocollectie van 200 GB vereist een volume van 300 GB. Postgres is in vergelijking hiermee klein.
- CPU: elke moderne KVM VPS volstaat, maar machine learning op de CPU is traag. Het indexeren van een grote import voor slim zoeken kan uren op de achtergrond draaien. Dit is normaal; een GPU is niet vereist.
- Een domeinnaam die naar de VPS wijst. De mobiele app werkt bij voorkeur met een HTTPS-eindpunt en u heeft een reverse proxy nodig. Dit is dezelfde opzet als een zelfgehoste Nextcloud-instantie met Docker, TLS en back-ups; Immich is de tegenhanger voor foto's van die bestandsserver.
- Docker en de Compose-plugin geïnstalleerd; Docker Engine plus de Compose v2-plugin uit de officiële apt-repository van Docker, precies zoals behandeld in onze handleiding voor Docker Compose-basisprincipes.
Stap 1: Voeg swap toe voordat u verdergaat
De meest voorkomende oorzaak van het falen van Immich op een kleine VPS is dat de ML-container wordt beëindigd door de OOM-killer (Out of Memory). Geef de kernel eerst wat ademruimte.
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 zou nu een Swap:-regel van 4.0Gi moeten tonen. Dit maakt ML niet sneller, maar het voorkomt dat de container crasht tijdens het indexeren op een machine met 4 GB RAM.
Stap 2: Haal de officiële compose en env op, gebruik die van hen, geen kopie
Immich zet zijn serviceversies en, cruciaal, zijn database-image vast in de bestanden die het meelevert. Kopieer geen compose-bestand van een blog (inclusief deze) als uw bron van waarheid. Download de release-assets:
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.envDeze zijn afkomstig van de getagde release, waardoor de image-verwijzingen overeenkomen. Het compose-bestand definieert vier services, en het is nuttig om te weten wat elk daarvan is voordat u wijzigingen aanbrengt:
immich-server(ghcr.io/immich-app/immich-server, containerimmich_server), de API en web-UI, luisterend op poort2283. Deze koppelt uw uploads aan/data.immich-machine-learning(ghcr.io/immich-app/immich-machine-learning, containerimmich_machine_learning), CLIP-zoekfunctie en gezichtsherkenning. Cacht gedownloade modellen in eenmodel-cache-volume. Dit is de service die veel geheugen verbruikt.database(containerimmich_postgres), Postgres met de VectorChord vector-extensie, die de gelijkeniszoekopdrachten aandrijft. De image-tag is vastgezet via een digest direct in het compose-bestand, bijvoorbeeldghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:.... Oudere installaties gebruiktenpgvecto.rs; ondersteuning hiervoor is verwijderd in Immich v3.0, dus alles wat u vandaag installeert is VectorChord. Pas deze tag nooit handmatig aan.redis(containerimmich_redis), een Valkey/Redis-instantie voor wachtrijen van taken.
Stap 3: Configureer .env, waar uw foto's en database zich bevinden
Open .env en stel vier zaken in. Alles onder de gemarkeerde regel blijft ongewijzigd.
# 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=immichTwee regels die u veel ellende besparen. UPLOAD_LOCATION moet naar uw grote schijf wijzen; als u later een datavolume koppelt, stel dit dan vanaf het begin in op het aankoppelpad, omdat verplaatsing achteraf betekent dat miniaturen verplaatst en asset-paden bijgewerkt moeten worden. En DB_DATA_LOCATION moet op een lokale schijf staan: Postgres op een NFS- of SMB-share raakt corrupt, en de documentatie stelt dit expliciet. Als u in DB_PASSWORD alleen letters en cijfers gebruikt, vermijdt u een categorie bugs gerelateerd aan het escapen van connection-strings.
Stap 4: Eerste uitvoering en aanmaken van de beheerder
cd /opt/immich
sudo docker compose up -d
sudo docker compose psEen correct resultaat bestaat uit vier containers, die allemaal running zijn en uiteindelijk healthy:
NAME STATUS
immich_machine_learning Up (healthy)
immich_postgres Up (healthy)
immich_redis Up (healthy)
immich_server Up (healthy)De eerste up haalt enkele gigabytes aan images op, dus geef dit de tijd. Volg de voortgang met sudo docker compose logs -f immich-server; de server logt dat deze luistert op poort 2283 zodra deze gereed is. Open nu http://YOUR_SERVER_IP:2283 in een browser. Bij het eerste bezoek verschijnt een Getting Started-wizard; het eerste account dat u aanmaakt is de beheerder. Stel een sterk wachtwoord in; dit account beheert de serverinstellingen, het gebruikersbeheer en de ML-configuratie die u later nodig zult hebben.
Stap 5: De mobiele app en achtergrondback-up
Installeer "Immich" vanuit de App Store of Play Store. Op het inlogscherm wordt gevraagd om een Server Endpoint URL. Voer de volledige URL in, inclusief het schema, bijvoorbeeld https://photos.example.com (de app voegt /api zelf toe). Log in met het account dat u zojuist heeft aangemaakt, open vervolgens het Backup-scherm van de app, selecteer de albums die u wilt beveiligen (meestal Camera en Screenshots) en schakel Background backup in. Achtergrondback-ups op iOS worden door het besturingssysteem beperkt; uploads op de voorgrond worden altijd uitgevoerd, terwijl achtergrond-uploads plaatsvinden wanneer het besturingssysteem dit toestaat.
Dit is precies het punt waar gebruikers vaak vastlopen, dus lees Stap 6 voordat u problemen met de app probeert op te lossen.
Stap 6: HTTPS via een reverse proxy en de full-URL regel
De mobiele app vereist HTTPS. Plaats een reverse proxy vóór poort 2283 en laat TLS daar termineren. Als u al meerdere containers gebruikt, is Traefik met automatische TLS voor meerdere Docker-applicaties de overzichtelijkste optie. Eén labelblok routeert photos.example.com naar de container immich-server en haalt het certificaat voor u op. Als u de voorkeur geeft aan nginx, zorgt de handleiding Let’s Encrypt met Certbot en nginx voor een certificaat en een blok proxy_pass http://127.0.0.1:2283;. Zodra die proxy beschikbaar is, voegt u de volgende service meestal toe met een nieuw subdomein. Zo kan een mediafrontend zoals Halcyon, de videotheekinterface uit de jaren 90 voor Jellyfin naast Immich op dezelfde server draaien. Hetzelfde geldt voor een zelfgehoste HarnessRouter die Codex en Claude Code achter één API plaatst. Deze service bindt bewust aan loopback en is pas bereikbaar wanneer de proxy TLS ervoor termineert. Wijzig daarom de standaardaanmeldgegevens voordat u er een subdomein aan koppelt.
Niet elke container krijgt echter een publieke hostnaam. Een beheerhulpmiddel zoals een zelfgehoste open-kritt-beveiligingsscanner laat u beter volledig buiten de proxy. U bereikt de interface alleen via een SSH-tunnel wanneer u die zelden nodig hebt. Andere services gebruiken geen proxy omdat HTTP niet hun protocol is. Een zelfgehoste RustDesk-relayserver is daarvan het duidelijkste voorbeeld. Deze luistert op enkele onbewerkte TCP- en UDP-poorten en vereist firewallregels in plaats van een subdomein.
Voor Immich is één proxy-instelling belangrijk: verhoog de limiet voor de uploadgrootte, omdat video's van telefoons groot zijn. In nginx is dat client_max_body_size 50000M; binnen het serverblok. De standaardwaarde van 1 MB weigert video-uploads met 413 Request Entity Too Large.
De regel die de app handhaaft: het eindpunt moet bereikbaar zijn en in de praktijk moet dit HTTPS zijn. http://-eindpunten, of een direct IP-adres waarbij de poort is weggelaten, zijn de oorzaak van de melding "de app kan de server niet bereiken", wat hieronder als een benoemde fout wordt behandeld.
Stap 7: Externe bibliotheken versus uploads, een bestaande fotostructuur importeren
Er zijn twee manieren waarop foto's in Immich terechtkomen, en deze zijn niet hetzelfde.
- Uploads zijn assets die eigendom zijn van Immich. De app of de web-uploader kopieert het bestand naar
UPLOAD_LOCATION. Immich kan deze bestanden hernoemen, verplaatsen en verwijderen. - Externe bibliotheken zijn alleen-lezen imports van bestanden die al in een map op uw server staan, zoals een oude
Pictures-structuur of een NAS-export. Immich indexeert deze op hun huidige locatie en toont ze in de tijdlijn, maar wijzigt of verwijdert de originelen nooit.
Om een bestaande structuur te importeren, koppelt u deze als alleen-lezen in de server-container. Bewerk docker-compose.yml onder immich-server: en voeg een volume toe:
immich-server:
volumes:
- ${UPLOAD_LOCATION}:/data
- /etc/localtime:/etc/localtime:ro
- /srv/photos:/mnt/media/photos:roDe :ro garandeert dat Immich de originelen nooit kan aanpassen. Maak de container opnieuw aan met sudo docker compose up -d, ga daarna in de web-UI naar uw avatar → Administration → External Libraries → Create Library, kies de eigenaar, klik op Add onder Folders en voer het containerpad in, /mnt/media/photos, niet het hostpad /srv/photos. Klik op Scan. Het gebruik van het hostpad in plaats van het containerpad is de meest gemaakte fout bij externe bibliotheken; de scan vindt dan niets en rapporteert nul assets.
Stap 8: De upgrade-discipline die Immich vereist
Dit is het onderdeel dat het verschil maakt tussen een goed werkende Immich-installatie en een defecte. Immich brengt snel updates uit, backport geen fixes en ondersteunt geen downgrades. Het blindelings volgen van de variabele v3-tag zal uiteindelijk uw database beschadigen. De gewoonte om eerst te pinnen en daarna de release notes te lezen, is voor elke langdurig draaiende container op de server aan te raden. Daarom wordt een zelfgehoste KiroCrew-agent vastgezet op één bekende, goede tag in plaats van deze bij elke herstart automatisch te laten bijwerken. De discipline:
- Pin een versie. Houd
IMMICH_VERSIONingesteld op een concrete tag zoalsv3.0.2, en niet op de variabelev3die altijd de nieuwste v3.x ophaalt. - Lees elke keer de release notes voordat u een upgrade uitvoert. Breaking changes, zeker met betrekking tot de database of vector-extensies, worden daar vermeld. De v3.0-release is hier het duidelijke voorbeeld: deze verwijderde pgvecto.rs volledig. Gebruikers die nog op de oude extensie zaten, moesten eerst de VectorChord-migratie (geïntroduceerd in v1.133) voltooien voordat ze konden upgraden.
- Maak eerst een back-up van de database (Stap 9). Doe dit altijd, maar wees extra alert wanneer de notes de database vermelden.
- Download ook het nieuwe compose-bestand.
IMMICH_VERSIONpint alleen de server- en ML-images. De Postgres-image wordt vastgezet op basis van een digest binnendocker-compose.yml. Een versie die een nieuwere database-extensie vereist, levert daarom een nieuw compose-bestand mee. Download beide release-assets opnieuw, pas uw.env-waarden weer toe en voer daarna de upgrade uit. - Update uw mobiele clients rond dezelfde tijd. De server communiceert alleen met de bijbehorende major-versie en de app ondersteunt de huidige en de vorige major-versie. Een server die voorloopt op de app toont
Your app major version is not compatible with the server!op de telefoon totdat u de app bijwerkt. Het is daarom het veiligst om eerst de app te updaten.
De daadwerkelijke commando's, zodra u de nieuwe bestanden op hun plek heeft staan:
cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image pruneStap 9: Back-ups, een database-dump PLUS de originelen, en test het
Een back-up van Immich bestaat uit twee onderdelen; het een zonder het ander is waardeloos. De database bevat de albumstructuur, gezichten, zoekindexen en de koppeling tussen assets en bestanden. De directory met originelen bevat de daadwerkelijke foto's. Herstelt u de een zonder de ander, dan krijgt u ofwel foto's zonder organisatie, ofwel een lege schil die naar ontbrekende bestanden verwijst. Deze tweedelige structuur is geen eigenaardigheid van Immich: een zelfgehoste Chatwoot-supportdesk vereist hetzelfde paar van een Postgres-dump en de bijbehorende uploads-directory, anders keert de herstelde inbox terug zonder bijlagen. Het kopiëren van de Postgres-datamap als een bestandssysteem lijkt een kortere weg ten opzichte van de dump-stap, maar dit is geen bruikbare back-up. Dit is een valkuil die de volledige Immich back-up en restore handleiding behandelt, naast de fout bij het herstellen waardoor u achterblijft met een lege tijdlijn.
Maak een dump van de database met pg_dump vanuit de Postgres-container, specifiek van de immich-database en niet van het hele cluster:
sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
--dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gzMaak vervolgens een back-up van UPLOAD_LOCATION, de volledige /opt/immich/library-boomstructuur, en in het bijzonder de submappen library/, upload/ en profile/, met restic, rsync of borg naar een andere machine of object storage. Welke taakplanner u ook gebruikt, een cron-entry of een systemd-timer, deze moet ergens een melding kunnen geven wanneer het mislukt. Een systemd OnFailure=-unit die verwijst naar uw eigen ntfy push-server stuurt een bericht naar uw telefoon op de avond dat een dump mislukt, in plaats van dat u daar pas achter komt tijdens een hersteloperatie. Voer eerst de database-back-up uit en daarna de bestanden, zodat de dump nooit verwijst naar een foto die nog niet door de bestandsback-up is gekopieerd. Externe bibliotheken back-upt u afzonderlijk bij de bron; Immich beheert deze niet.
Nu het onderdeel dat iedereen overslaat: test het herstel. Een herstel moet worden uitgevoerd op een schone stack waarvan de server nog nooit is gestart, op een Postgres-image waarvan de vector-extensie compatibel is met de dump. Dit is precies de reden waarom u nooit moet improviseren met de DB-image-tag. Wis op een testomgeving met dezelfde compose-configuratie en .env alle oude statusgegevens, start alleen de database en laad vervolgens de 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 -dDe sed-herschrijving van search_path is niet optioneel bij een VectorChord-database; laat u dit weg, dan wordt het herstel halverwege afgebroken. Wanneer de stack weer opkomt met uw originelen op de juiste plek, opent u de web-UI: als uw foto's en albums daar staan, werkt uw back-up. Als u dit nog nooit heeft uitgevoerd, heeft u geen back-up, maar slechts een hoop.
Foutmodi en bijbehorende meldingen
De ML-container wordt OOM-killed. sudo docker compose logs immich-machine-learning stopt abrupt, docker compose ps toont dit Restarting, en de exit-code is 137. sudo dmesg | grep -i oom bevestigt dit: Out of memory: Killed process ... (python3). Zoek- en gezichtsherkenningstaken lopen vervolgens vast. De oorzaak is onvoldoende RAM voor de modellen. Oplossingen, in volgorde: voeg swap toe (Stap 1); geef de VPS meer RAM; of, indien dit echt niet mogelijk is, schakel ML uit via Administration → Settings → Machine Learning Settings door Smart Search en Facial Recognition uit te zetten. U behoudt back-ups en albums, maar verliest de mogelijkheid om op inhoud te zoeken. Het verwijderen van de immich-machine-learning-service uit het compose-bestand heeft hetzelfde effect.
Postgres weigert te starten na een upgrade. Het serverlogboek blijft hangen in een lus met een regel zoals 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., of, bij oudere stacks, The pgvecto.rs extension is not available in this Postgres instance.. De oorzaak is een database-image waarvan de extensieversie ouder is dan de versie waarnaar uw data is bijgewerkt. Dit gebeurt bijna altijd door handmatige aanpassingen aan de image-tag of door een nieuwere dump terug te zetten op een oudere image. De oplossing is om de bijbehorende Postgres-image te gebruiken, het compose-bestand van de release te nemen die overeenkomt met uw database, niet te downgraden en alleen terug te zetten op een compatibele image.
De mobiele app kan de server niet bereiken. Het inlogscherm toont een verbindingsfout / Server is not reachable nadat u de URL heeft ingevoerd. Drie mogelijke oorzaken: u heeft http:// ingevoerd terwijl de proxy alleen https:// bedient; u heeft rechtstreeks verbinding gemaakt met de backend maar de poort weggelaten, waardoor geprobeerd werd example.com (poort 443) te gebruiken in plaats van example.com:2283; of de reverse proxy stuurt /api niet door. Los dit op door de volledige https://photos.example.com-URL in te voeren en eerst te controleren of deze in een mobiele browser laadt. Als de browser werkt maar de app niet, verwijdert de proxy het pad of is het certificaat zelfondertekend; de app weigert niet-vertrouwde certificaten.
Schijf vol tijdens import. Uploads mislukken, miniaturen worden niet weergegeven en logs tonen ENOSPC: no space left on device of, vanuit Postgres, could not extend file ... No space left on device. df -h laat zien dat het UPLOAD_LOCATION-volume voor 100% vol is. Daarom moet u de schijfruimte bepalen voordat u een grote bibliotheek importeert. Herstel dit door een groter volume te koppelen, de stack te stoppen, UPLOAD_LOCATION hiernaartoe te verplaatsen, .env bij te werken en opnieuw te starten, of breid de bestaande schijf uit als uw provider dit toestaat. Postgres kan vastlopen als de schijf vol raakt; maak dus ruimte vrij en herstart de database-container voordat u uitgaat van corruptie.
FAQ
Hoeveel RAM en schijfruimte heeft Immich nodig?
De officiële systeemeisen van Immich zijn minimaal 6 GB RAM, met 8 GB als aanbevolen hoeveelheid. 4 GB met swap is de praktische ondergrens voor een kleine bibliotheek; configureer in elk geval swap, aangezien de machine-learning-container voor pieken in het verbruik zorgt. Reken voor schijfruimte op de volledige grootte van uw bibliotheek plus ongeveer 10–20% voor gegenereerde thumbnails en previews. Gebruik hiervoor lokale opslag; plaats de Postgres-datamap nooit op een netwerkshare. Als u nog bepaalt welke andere diensten u wilt draaien, vergelijkt de gids voor zelf-gehoste software in 2026 de voetafdruk van Immich met andere services.
Kan ik Immich zonder GPU draaien?
Ja. De machine-learning-container draait prima op de CPU; een GPU versnelt enkel het indexeren voor slim zoeken en, met de juiste image-variant, het transcoderen van video. Op een CPU kan de initiële indexering van een grote bibliotheek uren op de achtergrond duren, maar dit blokkeert het maken van back-ups of het bladeren door foto's niet. Als uw systeem te beperkt is voor ML, kunt u Smart Search en Facial Recognition uitschakelen in de beheerdersinstellingen en de rest van de functionaliteit behouden.
Hoe upgrade ik Immich veilig?
Pin IMMICH_VERSION vast op een specifieke tag zoals v3.0.2, lees voor elke upgrade de release notes en maak eerst een back-up van de database. Omdat de Postgres-image binnen docker-compose.yml is vastgezet in plaats van via IMMICH_VERSION, dient u zowel het compose-bestand als example.env van de doelversie opnieuw te downloaden en uw waarden toe te passen, waarna u docker compose pull && docker compose up -d uitvoert. Laat de versie nooit onbeheerd op 'latest' staan; Immich brengt regelmatig ingrijpende wijzigingen uit en ondersteunt geen downgrades.
Wat moet ik precies back-uppen?
Twee zaken, in samenhang: een pg_dump van de immich-database en de volledige UPLOAD_LOCATION-map met originelen. De database bevat albums, gezichten en de koppeling tussen assets en bestanden; de map bevat de daadwerkelijke foto's. Een herstelactie vereist beide, plus een database-image met een compatibele vector-extensie. Maak eerst de database-dump en kopieer daarna de bestanden. Test het herstel ten minste één keer op een testsysteem; een niet-geteste back-up is geen back-up.
Hoe importeer ik mijn bestaande fotomap?
Mount de map 'read-only' in de immich-server-container als een extra volume (bijvoorbeeld - /srv/photos:/mnt/media/photos:ro), herstart de container en maak vervolgens in Administration → External Libraries een bibliotheek aan waarbij u het container-pad /mnt/media/photos opgeeft. Immich indexeert de bestanden op hun huidige locatie en wijzigt of verwijdert deze nooit. De meest gemaakte fout is het invoeren van het host-pad in plaats van het container-pad, waardoor de scan geen bestanden vindt.