šŸ“ø Immich - Self-Hosted Photo Backup [Part 6 of 10]

:camera_with_flash: Immich - Self-Hosted Photo Backup [Part 6 of 10]

Your own private photo library with face recognition and AI features
:framed_picture::cloud::locked::robot:

Tired of paying for cloud storage? Worried about privacy? Want unlimited photo storage?

Meet Immich - a self-hosted photo and video backup solution with features similar to popular cloud services.

Features:

  • Automatic mobile backup (iOS & Android)
  • Face recognition and object detection
  • Photo search by content
  • Albums and sharing
  • Live photos support
  • Video transcoding
  • Timeline view
  • Map view (with GPS data)
  • Completely free and private

Let’s set it up!


:brain: What is Immich?

Immich is an open-source, self-hosted photo and video backup platform.

Key Features:

  • Mobile apps - Auto-backup from your phone
  • AI-powered search - Find photos by content (ā€œbeachā€, ā€œdogā€, ā€œsunsetā€)
  • Face recognition - Automatically group photos by person
  • Object detection - Search for specific objects in photos
  • Live photos - Full support for iOS live photos
  • Video support - Upload and stream videos
  • Sharing - Share albums with family/friends
  • Timeline - Chronological photo browsing
  • Map view - See where photos were taken

Privacy:

  • All data stays on your server
  • No cloud uploads
  • No tracking
  • You control everything

:clipboard: What You’ll Need

Prerequisites

  • :white_check_mark: Docker and Portainer running (Part 4)
  • :white_check_mark: Nginx Proxy Manager configured (Part 5)
  • :white_check_mark: At least 16GB RAM (32GB+ recommended for ML features)
  • :white_check_mark: Storage space for your photos/videos

System Requirements

  • CPU: Multi-core processor (ML features are CPU-intensive)
  • RAM: 16GB minimum, 32GB+ for better performance
  • Storage: Depends on your photo library size
    • 10,000 photos ā‰ˆ 50-100GB
    • Videos take significantly more space

Ports Required

  • Port 2283 - Immich web interface

:rocket: Installing Immich

Immich uses multiple containers working together:

  • immich-server - Main application
  • immich-machine-learning - AI features (face recognition, object detection)
  • PostgreSQL - Database
  • Redis - Caching and job queue

We’ll deploy everything as a single stack in Portainer.


Step 1: Create Data Directories

On your Ubuntu server (via SSH):

# Create directories for Immich data
sudo mkdir -p /mnt/storage/docker/immich/library
sudo mkdir -p /mnt/storage/docker/immich/postgres

# Set ownership (replace 'admin' with your username)
sudo chown -R admin:admin /mnt/storage/docker/immich

Step 2: Generate Database Password

Generate a secure password for PostgreSQL:

# Generate a 32-character password (A-Z, a-z, 0-9 only)
openssl rand -base64 32 | tr -dc 'A-Za-z0-9' | head -c 32

Save this password - you’ll need it in the next step!


Step 3: Deploy via Portainer

Login to Portainer:

https://portainer.homelab.example.com

Create new stack:

  1. Click Stacks in left sidebar
  2. Click + Add stack
  3. Name: immich
  4. Build method: Web editor

Paste this compose configuration:

version: '3.8'

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:release
    command: ['start.sh', 'immich']
    volumes:
      - /mnt/storage/docker/immich/library:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    environment:
      DB_HOSTNAME: immich_postgres
      DB_USERNAME: postgres
      DB_PASSWORD: ${DB_PASSWORD}
      DB_DATABASE_NAME: immich
      REDIS_HOSTNAME: immich_redis
      TZ: America/New_York  # Change to your timezone
    depends_on:
      - redis
      - database
    restart: unless-stopped
    ports:
      - 2283:3001
    networks:
      - immich-network
      - portainer-network

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:release
    volumes:
      - /mnt/storage/docker/immich/model-cache:/cache
    environment:
      TZ: America/New_York  # Change to your timezone
    restart: unless-stopped
    networks:
      - immich-network

  redis:
    container_name: immich_redis
    image: registry.hub.docker.com/library/redis:6.2-alpine
    restart: unless-stopped
    networks:
      - immich-network

  database:
    container_name: immich_postgres
    image: registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: postgres
      POSTGRES_DB: immich
    volumes:
      - /mnt/storage/docker/immich/postgres:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - immich-network

networks:
  immich-network:
    driver: bridge
  portainer-network:
    external: true

Note about timezone:

  • Find your timezone: TZ Database Timezones
  • Examples: America/New_York, America/Los_Angeles, Europe/London, Asia/Tokyo

Step 4: Set Environment Variable

Scroll down to ā€œEnvironment variablesā€ section:

  1. Click + Add environment variable
  2. Name: DB_PASSWORD
  3. Value: Paste the password you generated in Step 2
  4. Click Add

Step 5: Deploy the Stack

Deploy:

  • Scroll down
  • Click Deploy the stack
  • Wait 3-5 minutes for deployment (first run downloads images)

Verify deployment:

  • Go to Containers in Portainer
  • Confirm all containers are running:
    • immich_server
    • immich_machine_learning
    • immich_redis
    • immich_postgres

Step 6: Configure Firewall

On your Ubuntu server (via SSH):

# Allow Immich from LAN
sudo ufw allow from 192.168.1.0/24 to any port 2283 proto tcp comment 'Immich from LAN'

# Check firewall status
sudo ufw status numbered

Note: Replace 192.168.1.0/24 with your network range.


:globe_with_meridians: Setting Up Proxy with NPM

Now let’s add Immich to Nginx Proxy Manager for clean URL access.

Step 1: Create SSL Certificate

Login to NPM:

https://npm.homelab.example.com

Create certificate:

  1. Go to SSL Certificates
  2. Click Add SSL Certificate → Let’s Encrypt
  3. Domain Names: photos.homelab.example.com
  4. Use a DNS Challenge: :white_check_mark: Enable (if using DNS challenge)
  5. Email Address: Your email for Let’s Encrypt notifications
  6. Agree to Terms: :white_check_mark: Check
  7. Click Save
  8. Wait for certificate issuance (1-2 minutes)

Step 2: Create Proxy Host

In NPM:

  1. Go to Hosts → Proxy Hosts
  2. Click Add Proxy Host

Details Tab:

  • Domain Names: photos.homelab.example.com
  • Scheme: http
  • Forward Hostname/IP: immich_server (container name)
  • Forward Port: 2283
  • Cache Assets: :white_check_mark: Enable
  • Block Common Exploits: :white_check_mark: Enable
  • Websockets Support: :white_check_mark: Enable

SSL Tab:

  • SSL Certificate: Select your certificate
  • Force SSL: :white_check_mark: Enable
  • HTTP/2 Support: :white_check_mark: Enable
  • HSTS Enabled: :white_large_square: Leave unchecked

Click: Save


Step 3: Test Access

Open your browser:

https://photos.homelab.example.com

You should see the Immich welcome screen!


:artist_palette: First-Time Setup

Create Admin Account

On first access:

  1. Email: Your email address
  2. Password: Choose a strong password
  3. Name: Your name
  4. Click Sign Up

Need a strong password?


Initial Configuration

After creating your account:

  1. Skip the intro (or read it!)
  2. Configure storage settings (optional)
    • Go to Administration → Settings
    • Review storage template (default is fine)
  3. Set up mobile app (see next section)

:mobile_phone: Mobile App Setup

Immich has excellent mobile apps for automatic photo backup.

iOS App

  1. Download: Immich on App Store
  2. Open app
  3. Server URL: https://photos.homelab.example.com
  4. Login with your credentials
  5. Enable auto-backup:
    • Go to Backup tab
    • Enable Background backup
    • Select albums to backup
    • Configure backup settings

Android App

  1. Download: Immich on Google Play
  2. Open app
  3. Server URL: https://photos.homelab.example.com
  4. Login with your credentials
  5. Enable auto-backup:
    • Go to Backup tab
    • Enable Background backup
    • Select albums to backup
    • Configure backup settings

Note: For mobile backup to work outside your home network, you’ll need to expose Immich publicly (not recommended) or use a VPN.


:bullseye: Using Immich

Uploading Photos

Via Web:

  1. Click Upload button
  2. Select photos/videos
  3. Wait for upload to complete

Via Mobile:

  • Enable auto-backup in mobile app
  • Photos upload automatically in background

Search Features

Search by content:

  • Type ā€œbeachā€, ā€œdogā€, ā€œsunsetā€, etc.
  • AI automatically detects objects and scenes

Search by face:

  • Go to People tab
  • Immich automatically detects faces
  • Name people to group their photos

Search by location:

  • Go to Map view
  • See photos plotted on map (requires GPS data)

Creating Albums

  1. Select photos (checkbox icon)
  2. Click Add to album
  3. Create new album or add to existing
  4. Share album with others (optional)

Sharing

  1. Open an album
  2. Click Share button
  3. Choose sharing options:
    • Link sharing - Generate shareable link
    • User sharing - Share with other Immich users
  4. Set permissions (view only, can edit, etc.)

:wrench: Maintenance

Check Storage Usage

# Check Immich storage usage
du -sh /mnt/storage/docker/immich/library

# Check database size
du -sh /mnt/storage/docker/immich/postgres

Backup Your Photos

Backup uploaded photos:

# Backup library directory
sudo tar -czf immich-library-backup-$(date +%Y%m%d).tar.gz \
  /mnt/storage/docker/immich/library

Backup database:

# Backup PostgreSQL database
docker exec immich_postgres pg_dump -U postgres immich > immich-backup-$(date +%Y%m%d).sql

Store backups off-site for true redundancy!


Update Immich

Via Portainer:

  1. Go to Stacks → immich
  2. Click Editor
  3. Click Update the stack
  4. Select Re-pull image and redeploy
  5. Wait for update to complete

Check for updates regularly - Immich is actively developed with frequent improvements.


:shield: Performance Tips

Machine Learning Performance

ML features are CPU-intensive:

  • Face recognition
  • Object detection
  • Smart search

Initial scan takes time:

  • Expect high CPU usage during first photo analysis
  • Can take hours/days for large libraries
  • Performance improves after initial scan

Optimize ML performance:

  • Ensure adequate RAM (32GB+ recommended)
  • Let initial scan complete before heavy usage
  • Consider disabling ML features on low-end hardware

Storage Optimization

Video transcoding:

  • Immich can transcode videos for web playback
  • Saves bandwidth but uses storage
  • Configure in Administration → Settings → Video

Thumbnail generation:

  • Thumbnails are generated automatically
  • Stored in /mnt/storage/docker/immich/library/thumbs
  • Can be regenerated if deleted

:brain: TL;DR

  • Immich is a self-hosted photo backup platform
  • Features: Mobile backup, face recognition, AI search, sharing
  • Installation: Deploy multi-container stack via Portainer
  • Mobile apps: iOS and Android with auto-backup
  • Privacy: All data stays on your server
  • Performance: Requires decent CPU/RAM for ML features
  • Next: We’ll set up Discourse for community forums in Part 7

:speech_balloon: Your Turn

What cloud photo service are you currently using?
How many photos do you have to backup?
Excited about having unlimited private photo storage?

Drop a comment below!


Navigation: ← Part 5 | Part 7 →