Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Immich Ubuntu
GUIDEInstall Guides

How to Install Immich on Ubuntu 24.04 — Self-Host Your Photo Library

28 min read

How to Install Immich on Ubuntu 24.04 — Self-Host Your Photo Library

Cloud photo services are convenient until they stop being convenient. Prices climb, features disappear behind new tiers, your account gets auto-scanned, and one day Google decides your medical photos look suspicious and locks you out with no appeal. Immich is the community-built escape hatch: a self-hosted photo and video backup platform that looks and feels like Google Photos but runs entirely on your own VPS. Automatic mobile uploads, facial recognition, natural-language search, shared albums, memories, and a polished iOS and Android app — all of it running on infrastructure you control.

This guide walks you end to end: a clean Ubuntu 24.04 VPS becomes a production-ready Immich server in about 35 minutes, with TLS, reverse proxy tuning for multi-gigabyte video uploads, machine learning enabled, mobile apps configured, and a repeatable backup routine.

Recommended plan: Immich is memory-hungry once machine learning kicks in. The CloudCore Professional plan at EUR 19.99/month gives you 6 vCPU, 12 GB RAM, and 100-200 GB NVMe — the sweet spot for a single household or small team photo library.

Table of Contents

  • Why Self-Host Instead of Using Google Photos or iCloud?
  • What You Get With Immich
  • Prerequisites
  • Step 1: Prepare the Server
  • Step 2: Install Docker and Docker Compose
  • Step 3: Download the Immich Compose Files
  • Step 4: Configure the Environment
  • Step 5: Launch the Immich Stack
  • Step 6: First User Signup
  • Step 7: Mobile App Setup and Auto Backup
  • Step 8: Machine Learning — CLIP Search and Face Recognition
  • Step 9: Albums and Shared Links
  • Step 10: Nginx Reverse Proxy with TLS
  • Step 11: Backups — rsync and pg_dump
  • Upgrading Immich
  • Troubleshooting
  • FAQ
  • Next Steps
  • Why Self-Host Instead of Using Google Photos or iCloud?

    Every major cloud photo service starts cheap and gets expensive once your library grows beyond a single phone. Here is how the cost curve actually looks once you are a household of three with a decade of photos and video:

    Storage tierGoogle OneiCloud+Immich on CloudCore Professional
    200 GBEUR 2.99/moEUR 2.99/moIncluded (EUR 19.99 flat)
    2 TBEUR 9.99/moEUR 9.99/moIncluded (add block storage EUR 5/mo)
    6 TBEUR 24.99/moEUR 29.99/moEUR 19.99 + storage volume
    12 TBEUR 49.99/moNot availableEUR 19.99 + storage volume
    Family members5 max5 maxUnlimited
    Who reads your photos?Google ML scans all contentApple scans for CSAMNobody. You hold the keys.
    Moving to another serviceExport via Takeout (hours)Manual export per devicersync, you own the files
    Account shutdown riskReal — automated, no human reviewReal — same storyNone. Your VPS, your rules
    Sovereignty matters beyond price. When Google or Apple bans an account because an automated scanner misclassifies a bath-time photo of your kid, there is no appeal process that actually works — major news outlets have covered multiple incidents where parents lost a decade of memories overnight. With Immich, the files sit on your filesystem. You back them up. You decide who sees them. No third party has any involvement in the chain.

    Cost at scale. A 2 TB Google One plan is EUR 120/year forever. A CloudCore Professional VPS costs EUR 240/year total — and that same VPS also runs your Jellyfin media server, your Nextcloud, your Nginx, and any other self-hosted tool you want. Past the 6 TB point, Immich on a VPS with attached block storage is flatly cheaper than any cloud equivalent, and the savings compound every year.

    GDPR by default. For EU users, keeping family photos on an EU-hosted VPS under your name means you never signed them over to a US ad-tech company. There is no shadow profile, no facial embeddings in a corporate database, no training-data hoovering.

    What You Get With Immich

    Immich is not a minimal viable product. In feature parity with Google Photos, it has shipped almost everything the big players offer:

    • Automatic mobile backup from iOS and Android, background upload on new photos
    • CLIP-powered semantic search — type "red car on a beach" and get matching photos from a decade ago
    • Face recognition and clustering — group people automatically, tag them, merge clusters
    • Albums, smart albums, and nested albums with custom cover photos
    • Shared links with optional expiry, password, and download toggles for non-users
    • Memories — "on this day" surfaced automatically
    • Map view with EXIF-based geolocation clustering
    • Video transcoding via integrated FFmpeg for web-friendly playback
    • RAW support — DNG, CR2, NEF, ARW, and others
    • External libraries — point Immich at an existing NAS folder without reuploading
    • Multi-user with per-user quotas
    • Hardware-accelerated ML on NVIDIA, Intel, and ARM
    Under the hood, Immich is a stack of five containers: a Node.js server, a Python machine learning service, PostgreSQL 16 with the pgvector extension for embedding search, Redis for background jobs, and an optional separate microservices container for transcoding and indexing work. Docker Compose orchestrates everything.

    Prerequisites

    Before you start, confirm you have the following in place:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • At least 4 vCPU cores and 8 GB of RAM (6 vCPU / 12 GB strongly recommended for smooth ML)
    • At least 50 GB of free disk for the OS and container images, plus enough space for your photo library (plan 4 MB per photo, 30-100 MB per minute of 4K video)
    • A domain name pointed to the server's public IP (for TLS via Let's Encrypt)
    • Ports 80 and 443 open in your firewall
    • SSH access from your workstation
    Connect to your server:

    bash
    ssh root@your-server-ip

    If you are not running as root, prefix subsequent commands with sudo.

    Step 1: Prepare the Server

    Start with a clean, fully patched system. Update the package index, upgrade installed packages, and install a small set of utilities you will need along the way.

    bash
    apt update && apt upgrade -y
    apt install -y curl wget gnupg2 ca-certificates lsb-release ufw git

    Create a dedicated user for running the stack. Running Docker Compose as root is possible but unnecessary — the Immich containers set their own internal UIDs, and keeping the host-side service files under a non-root account is cleaner for backups and permissions.

    bash
    adduser --disabled-password --gecos "" immich
    usermod -aG sudo immich

    Configure the firewall to allow SSH and HTTPS traffic:

    bash
    ufw allow OpenSSH
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw --force enable

    Set the timezone so EXIF dates and memory cards line up correctly:

    bash
    timedatectl set-timezone Europe/Berlin

    Replace Europe/Berlin with your actual timezone (use timedatectl list-timezones to browse).

    Step 2: Install Docker and Docker Compose

    Immich ships exclusively as a Docker Compose stack, so Docker Engine with the Compose v2 plugin is mandatory. Add Docker's official apt repository, then install the latest Engine and plugins in one shot.

    bash
    install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    chmod a+r /etc/apt/keyrings/docker.asc

    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ | tee /etc/apt/sources.list.d/docker.list > /dev/null

    apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Add the immich user to the docker group so you do not need sudo for every Compose command:

    bash
    usermod -aG docker immich

    Verify the install:

    bash
    docker --version
    docker compose version

    Expected output (versions may differ):

    text
    Docker version 27.3.1, build ce12230
    Docker Compose version v2.29.7

    For a deeper walkthrough of Docker itself, see our companion guide: How to Install Docker on Ubuntu 24.04.

    Step 3: Download the Immich Compose Files

    Immich publishes its official docker-compose.yml and an example.env alongside each release. Rather than cloning the entire repository, you pull the two files directly into a deployment directory.

    Switch to the immich user and create a working directory:

    bash
    su - immich
    mkdir -p ~/immich && cd ~/immich

    Download the latest release assets:

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

    Copy the example env to your real env file:

    bash
    cp example.env .env

    Take a quick look at what you downloaded:

    bash
    ls -la

    You should see four files: docker-compose.yml, example.env, .env, and eventually your upload directory.

    Step 4: Configure the Environment

    The .env file controls every adjustable setting. Open it in your editor of choice:

    bash
    nano .env

    Three variables matter most:

    env
    # Where photo and video originals are stored on the host
    UPLOAD_LOCATION=/home/immich/immich/library

    Where PostgreSQL data lives

    DB_DATA_LOCATION=./postgres

    Tag for the container images — pin to a known-good release rather than "release"

    IMMICH_VERSION=v1.119.0

    Database credentials (generate a strong random password)

    DB_PASSWORD=CHANGE_ME_TO_A_LONG_RANDOM_STRING

    These defaults work but you can override them

    DB_USERNAME=postgres DB_DATABASE_NAME=immich

    Generate a strong database password

    Never keep the default password. Generate one with:

    bash
    openssl rand -base64 36

    Copy the result into DB_PASSWORD. Save and close (Ctrl+O, Enter, Ctrl+X in nano).

    Pick your UPLOAD_LOCATION carefully

    UPLOAD_LOCATION is the directory on the host that will hold every original photo and video, plus the generated thumbnails and encoded video proxies. It is the single most important path in your entire deployment — this is what you back up, what you rsync off-site, and what balloons to hundreds of gigabytes over time.

    Best practice:

    • On the main disk: /home/immich/immich/library works fine for libraries under 100 GB
    • On a mounted block storage volume: /mnt/photos/library — ideal for large libraries, mount before starting Immich
    • Never put it inside ./postgres or the Immich config directory; keep media and database storage fully separate
    Create the directory up front so Docker does not create it with root ownership:

    bash
    mkdir -p /home/immich/immich/library

    External block storage for large libraries

    If you attached a 1 TB volume and mounted it at /mnt/photos, set:

    env
    UPLOAD_LOCATION=/mnt/photos/library

    And ensure the immich user can write to it:

    bash
    sudo chown -R immich:immich /mnt/photos

    Step 5: Launch the Immich Stack

    With the environment configured, start the full stack in detached mode:

    bash
    docker compose up -d

    The first run pulls five images — about 3 GB total — and initializes the Postgres database. On a Professional plan this takes two to four minutes.

    Watch progress with:

    bash
    docker compose logs -f

    Press Ctrl+C to detach from the log stream (the containers keep running).

    Check that all services came up:

    bash
    docker compose ps

    Expected output:

    text
    NAME                    IMAGE                                              STATUS
    immich_machine_learning ghcr.io/immich-app/immich-machine-learning:v1.119  Up 1 minute (healthy)
    immich_postgres         ghcr.io/immich-app/postgres:14-vectorchord         Up 1 minute (healthy)
    immich_redis            docker.io/redis:6.2-alpine                         Up 1 minute (healthy)
    immich_server           ghcr.io/immich-app/immich-server:v1.119            Up 1 minute (healthy)

    All four containers must report healthy. If any shows unhealthy, jump to the Troubleshooting section.

    Verify the web UI is serving on port 2283:

    bash
    curl -I http://localhost:2283

    Expected:

    text
    HTTP/1.1 200 OK

    Step 6: First User Signup

    The first person to register on a fresh Immich instance becomes the administrator — no invite code, no email verification. This happens before you put Nginx and TLS in front, so you do it over a temporary SSH tunnel to keep the signup off the public internet.

    From your local workstation, open an SSH tunnel that forwards port 2283:

    bash
    ssh -L 2283:localhost:2283 root@your-server-ip

    Leave that terminal open, then visit http://localhost:2283 in your browser.

    You will see the Immich welcome screen. Click Get Started and fill in:

    • Admin email (used for login; receives no mail by default)
    • Admin password (use a password manager — this protects your entire photo library)
    • Name (shown in the UI)
    Immich creates the admin account and redirects you to the login screen. Sign in with the credentials you just set. You are now in an empty library — the real fun starts once photos show up.

    Create additional user accounts

    If family members will share this server, create a user for each one now so they can install the mobile app against their own account.

    Go to Administration > Users > Create user. Each user gets:

    • Email (login identifier)
    • Password (give them something temporary; they can change it)
    • Name
    • Optional storage quota in gigabytes

    Step 7: Mobile App Setup and Auto Backup

    Automatic backup from your phone is the killer feature. It runs silently in the background, uploads on Wi-Fi only by default, and makes Immich actually feel like Google Photos rather than a manual upload tool.

    iOS

  • Install Immich from the App Store
  • Open the app and tap Server URL (for now: http://your-server-ip:2283 while you test — you will change this to your HTTPS domain after Step 10)
  • Sign in with the email and password for your user
  • Go to Settings > Backup > Backup Albums and select which albums on your phone should back up (typically "Recents" and any manually curated albums)
  • Enable Foreground backup and Background backup
  • Toggle Use Wi-Fi only on if you have a metered data plan
  • iOS aggressively kills background tasks. The Immich maintainers document a workaround: enable Background App Refresh for Immich in iOS Settings, and keep the app in your recent apps list rather than force-quitting it. Background uploads happen reliably when the phone charges overnight.

    Android

  • Install Immich from the Play Store (or via F-Droid for a fully open-source build)
  • Enter your server URL and credentials
  • Under Backup, enable Background backup
  • Grant the notification permission Android requests — it uses a silent foreground service
  • Disable battery optimization for Immich in Android Settings > Apps > Immich > Battery
  • Android background uploads are far more reliable than iOS and will pick up new photos within minutes of capture.

    Verify uploads are working

    Take a photo on your phone, wait 30-60 seconds, and refresh the Immich web UI. The new photo should appear in the timeline. If it does not, check Settings > Backup in the mobile app for upload status and pending count.

    Step 8: Machine Learning — CLIP Search and Face Recognition

    The Immich machine learning container runs three models by default:

    • CLIP (Contrastive Language-Image Pretraining) for natural-language search
    • Face detection using RetinaFace
    • Face recognition using ArcFace to cluster faces into people
    On first run, the container downloads the model weights (about 500 MB total) into a named Docker volume. No configuration is needed to get baseline behavior — Immich automatically queues every uploaded photo for ML processing.

    Trigger a full library rescan

    Once you have seeded the library with a few hundred photos, go to Administration > Jobs in the web UI. From there you can:

    • Run Smart Search (CLIP) across all photos to build embeddings
    • Run Face Detection followed by Facial Recognition to populate the People view
    • Run Thumbnail Generation if any previews are missing
    On a 6 vCPU CloudCore Professional server with no GPU, expect:

    • CLIP embedding: ~5-10 photos per second
    • Face detection: ~3-5 photos per second
    • Thumbnail generation: ~20-30 photos per second
    A 20,000-photo library completes all three passes in roughly three to four hours. After the initial indexing, newly uploaded photos are processed in real time.

    Try the semantic search

    Click the search bar and type something descriptive like:

    • sunset on a mountain
    • birthday cake with candles
    • red car
    • person holding a book
    CLIP ranks every photo in your library by how closely its learned embedding matches the text embedding. Results are astonishingly good even without any tagging.

    Identify and name faces

    Open the People view (sidebar). Immich has already clustered similar faces. Click a face cluster and give it a name — from that point forward, you can search by person name, and new photos of that person are auto-tagged.

    Merge clusters that belong to the same person (common for photos at different ages). Hide clusters that contain only strangers, mirrors, or statues.

    GPU acceleration (optional)

    If your VPS has an NVIDIA GPU, switch the ML container to the CUDA image for a 10-20x speedup. Edit docker-compose.yml and change the immich-machine-learning service to use :cuda:

    yaml
    immich-machine-learning:
        image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
        extends:
          file: hwaccel.ml.yml
          service: cuda

    Then:

    bash
    docker compose up -d

    See immich.app/docs for OpenVINO (Intel) and ARM-NN (Raspberry Pi, Apple Silicon) variants.

    Step 9: Albums and Shared Links

    Albums in Immich are flat collections of photos you curate manually. Select photos from the timeline (shift-click for ranges, or lasso-drag), then Add to Album. Each album can have a custom cover, description, and start/end dates.

    Shared albums

    Inside an album, click Share, then Add users. Any Immich user on the same server can be invited as either Viewer or Contributor. Contributors can add their own photos to the album — perfect for family events where multiple people have their own copies.

    Shared links (external)

    For people who do not have an Immich account, create a public shared link:

  • Open the album (or select photos)
  • Click Share > Share link
  • Configure:
  • - Expiration: hours, days, or never - Password: optional, protects the link even if the URL leaks - Allow downloads: off by default, toggle on if appropriate - Show metadata: hide EXIF if sharing publicly

    Immich generates a URL like https://photos.yourdomain.com/share/abc123xyz. Anyone with the link views a gallery without seeing your main UI or creating an account.

    Step 10: Nginx Reverse Proxy with TLS

    Serving Immich on plain HTTP at port 2283 works on a LAN but is unacceptable over the public internet. You want a proper domain, an HTTPS certificate from Let's Encrypt, and a proxy tuned for very large uploads. Nginx handles all three.

    Install Nginx and Certbot:

    bash
    sudo apt install -y nginx certbot python3-certbot-nginx

    Create the site configuration:

    bash
    sudo tee /etc/nginx/sites-available/immich > /dev/null <<'EOF'
    server {
        listen 80;
        server_name photos.yourdomain.com;

    # Certbot writes a challenge file to this path during cert issuance location /.well-known/acme-challenge/ { root /var/www/html; }

    # Redirect everything else to HTTPS location / { return 301 https://$host$request_uri; } }

    server { listen 443 ssl http2; server_name photos.yourdomain.com;

    # Certbot fills in these paths in the next step ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;

    # Critical: allow multi-gigabyte video uploads client_max_body_size 5G;

    # Long timeouts for big file uploads proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s;

    # Disable buffering so uploads stream through to Immich proxy_request_buffering off; proxy_buffering off; proxy_http_version 1.1;

    # Required for WebSocket notifications proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

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

    location / { proxy_pass http://127.0.0.1:2283; } } EOF

    Replace photos.yourdomain.com with your actual domain. Enable the site and issue the certificate:

    bash
    sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/
    sudo rm -f /etc/nginx/sites-enabled/default
    sudo nginx -t
    sudo certbot --nginx -d photos.yourdomain.com --non-interactive --agree-tos -m [email protected]
    sudo systemctl reload nginx

    Certbot auto-renews via the installed systemd timer — no further action needed.

    Update the mobile app

    Now that HTTPS works, open the Immich app on each phone, go to Settings > Server URL, and change it from http://your-server-ip:2283 to https://photos.yourdomain.com.

    Why 5 GB body size matters

    Modern phones produce 4K 60fps video and ProRes clips from pro cameras that easily exceed 2 GB per file. A default Nginx install caps uploads at 1 MB, so any large video upload fails silently with a 413 error. Setting client_max_body_size 5G gives comfortable headroom; raise it further if you regularly archive RAW photo bursts or hours-long video files.

    Step 11: Backups — rsync and pg_dump

    Immich's data has two parts: the media files under UPLOAD_LOCATION and the Postgres database that indexes them, stores thumbnails-to-original mappings, and holds face embeddings. Both must be backed up together, or a restored library will not match its metadata.

    Back up the database with pg_dump

    Immich ships a recommended dump command. Create a helper script at /home/immich/backup-db.sh:

    bash
    tee /home/immich/backup-db.sh > /dev/null <<'EOF'
    #!/bin/bash
    set -e

    BACKUP_DIR=/home/immich/backups/db STAMP=$(date +%Y-%m-%d_%H-%M-%S) mkdir -p "$BACKUP_DIR"

    docker exec -t immich_postgres \ pg_dumpall --clean --if-exists --username=postgres \ | gzip > "$BACKUP_DIR/immich-$STAMP.sql.gz"

    Keep the last 14 daily dumps

    find "$BACKUP_DIR" -name "immich-*.sql.gz" -mtime +14 -delete EOF

    chmod +x /home/immich/backup-db.sh

    Test it once manually:

    bash
    /home/immich/backup-db.sh
    ls -lh /home/immich/backups/db/

    You should see a compressed SQL dump, typically 20-500 MB depending on library size.

    Mirror media with rsync

    For off-site media backup, rsync to another VPS, a home NAS, or cloud storage. Example to a remote NAS over SSH:

    bash
    tee /home/immich/backup-media.sh > /dev/null <<'EOF'
    #!/bin/bash
    rsync -avz --delete \
      --exclude='encoded-video/' \
      --exclude='thumbs/' \
      --exclude='upload/' \
      /home/immich/immich/library/ \
      [email protected]:/volume1/immich-backup/
    EOF

    chmod +x /home/immich/backup-media.sh

    The excluded directories are regenerated by Immich from originals, so backing them up wastes space. Back up the library directory only — originals plus sidecars plus external libraries.

    Schedule everything with cron

    Edit the immich user's crontab:

    bash
    crontab -e

    Add:

    text
    # Database dump at 02:15 every night
    15 2   * /home/immich/backup-db.sh >> /home/immich/backups/backup.log 2>&1

    Media rsync at 03:00 every night

    0 3 * /home/immich/backup-media.sh >> /home/immich/backups/backup.log 2>&1

    Restore procedure (for reference)

    If disaster strikes:

    bash
    # Stop the stack
    cd ~/immich && docker compose down

    Wipe and recreate the database volume

    docker volume rm immich_immich_postgres || true docker compose up -d database

    Restore the dump

    zcat /home/immich/backups/db/immich-2026-04-15_02-15-00.sql.gz \ | docker exec -i immich_postgres psql --username=postgres

    Restore the media

    rsync -avz backup@nas:/volume1/immich-backup/ /home/immich/immich/library/

    Start everything

    docker compose up -d

    Test this procedure on a staging VPS at least once — an untested backup is an assumption, not a backup.

    Upgrading Immich

    Immich releases roughly every two weeks with new features and schema migrations. Upgrades are straightforward:

    bash
    cd ~/immich

    1. Read the release notes first — some releases have breaking changes

    Visit https://github.com/immich-app/immich/releases

    2. Update the version pin in .env

    nano .env

    change IMMICH_VERSION=v1.119.0 to the new version

    3. Pull and restart

    docker compose pull docker compose up -d

    Schema migrations run automatically on startup. Always take a fresh pg_dump immediately before upgrading — if a migration fails, you can revert by restoring the dump and pinning back to the previous version.

    Troubleshooting

    ProblemLikely causeFix
    413 Request Entity Too Large on large videosNginx body limit too lowRaise client_max_body_size to 5G or higher, reload Nginx
    Mobile app says "cannot connect" after adding TLSOld HTTP URL cachedUpdate server URL in app settings, force-close and reopen
    ML jobs stuck at 0% progressimmich_machine_learning unhealthy, model download faileddocker compose logs immich-machine-learning, restart service; ensure outbound HTTPS is allowed from the container
    Postgres container restart loopBad DB_PASSWORD change after first runPasswords are baked into the volume on first init — either revert the .env change or wipe the postgres volume and restore from pg_dump
    Uploads succeed but photos do not appearStorage template job backlogAdministration > Jobs, force-run Storage Template and Metadata Extraction
    "Out of disk space" errorsUPLOAD_LOCATION filesystem fullExpand the volume or move UPLOAD_LOCATION to a larger mount and rsync existing data
    Face recognition groups strangers togetherDefault confidence threshold too lowAdmin > Settings > Machine Learning > raise Facial Recognition min confidence to 0.8
    Slow first page load over HTTPSLarge EXIF reads on cold cacheNormal on first visit after restart; subsequent loads use Redis cache

    View service logs

    bash
    cd ~/immich
    docker compose logs -f immich-server
    docker compose logs -f immich-machine-learning
    docker compose logs -f redis
    docker compose logs -f database

    Reset a forgotten admin password

    bash
    docker exec -it immich_server /bin/bash
    

    inside the container:

    node /usr/src/app/dist/main reset-admin-password

    FAQ

    How much disk space do I need for Immich?

    Plan for roughly 4 MB per smartphone photo and 30-100 MB per minute of 4K video. A typical user backing up 10 years of photos needs 500 GB to 2 TB. The CloudCore Professional plan starts with 100-200 GB NVMe, and you can attach block storage for larger libraries — EUR 5/month per 200 GB is the typical rate.

    Is Immich production ready?

    Immich is under heavy active development and still labeled beta by the maintainers, but tens of thousands of users rely on it daily for their primary photo archive. As long as you follow the documented backup strategy (database dump plus media rsync, tested restore), it is safe for personal and small-team use. Read every release note before upgrading, especially when minor versions change.

    Can Immich replace Google Photos completely?

    Yes for most users. Immich offers automatic mobile backup, face recognition, object and text search via CLIP, albums, shared links, memories, map view, and polished iOS and Android apps. A few Google Photos features do not exist yet: photo books printing, family-group management, and the deeply-integrated Google Lens features. If those matter to you, keep Google Photos as a secondary and use Immich as your sovereign primary archive.

    Does Immich support GPU acceleration for machine learning?

    Yes. Immich supports NVIDIA CUDA, Intel OpenVINO, and ARM NN (Apple Silicon, Raspberry Pi) for the machine learning container. On CPU, CLIP indexing processes roughly 5-20 photos per second. With a modest NVIDIA GPU you can index tens of thousands of photos in minutes instead of hours. See immich.app/docs for per-backend setup.

    How do I migrate from Google Photos to Immich?

    Use Google Takeout to download your library as a zip (choose 50 GB split files for easier handling). Extract all files to a staging folder, then use the Immich CLI:

    bash
    npm install -g @immich/cli
    immich login https://photos.yourdomain.com YOUR_API_KEY
    immich upload --recursive /path/to/takeout

    The CLI reads Google's JSON sidecar files to restore original capture dates, preserves EXIF, and skips duplicates on retry. A 100 GB Takeout typically imports in 8-20 hours depending on network and disk.

    Why does the upload fail for large videos?

    Almost always Nginx. The default client_max_body_size is 1 MB, which blocks anything larger than a high-res photo. Raise it to 5 GB or more with client_max_body_size 5G; in your server block and reload Nginx. The Immich API itself has no hard upload limit beyond available disk.

    Can multiple family members share one Immich server?

    Yes, and this is where self-hosting shines. The admin creates additional users from Administration > Users, each with their own private library and optional storage quota. Users can then share albums with each other, contribute to joint albums (wedding, vacation, birthdays), and invite external viewers via shared links. One VPS, one monthly bill, unlimited family members.

    Next Steps

    You now have a production Immich instance with mobile backup, semantic search, face recognition, and proper backups. A few natural follow-ons:

    • Pair Immich with a full media server. Immich handles photos and home videos; pair it with Jellyfin for movies and TV shows on the same VPS.
    • Add a personal cloud for documents and files. Immich specializes in photos — for everything else (documents, contacts, calendars, file sync), install Nextcloud alongside it on the same server.
    • Harden the server with Fail2Ban and CrowdSec — see How to Install CrowdSec on Ubuntu 24.04.
    • Automate off-site backups to Backblaze B2 or a second VPS in a different region. Your media on one VPS plus nightly rsync to another location gives you the 3-2-1 backup strategy professionals actually use.
    • Browse the upstream docs at immich.app/docs for advanced topics: external libraries, hardware video transcoding, OAuth SSO, and the REST API.
    Need more headroom? The CloudCore Professional plan at EUR 19.99/month gives you 6 vCPU, 12 GB RAM, and 100-200 GB NVMe — comfortable for a family photo archive plus Jellyfin, Nextcloud, and a handful of other services on one VPS. Launch your server and have Immich running in under an hour.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket