Technology Encyclopedia Home >How to Deploy Immich — Self-Hosted Photo Library on a VPS

How to Deploy Immich — Self-Hosted Photo Library on a VPS

My phone's camera roll goes back years and contains photos I'd be genuinely upset to lose. I used a cloud photo service for years, which worked well — until I did the math on how many gigabytes I was accumulating and what ongoing storage costs would look like long-term.

Immich is the self-hosted alternative that actually works well enough to replace a cloud photo service. The mobile app does background sync exactly like you'd expect, the web interface has timeline view and search, and face recognition means I can search for photos of specific people.

The machine learning features are the CPU-intensive part. I'll explain how to tune that for your server size.

This guide deploys Immich on Ubuntu 22.04 using the official Docker Compose setup, with Nginx as the reverse proxy and HTTPS.

I run Immich on Tencent Cloud Lighthouse. For a personal photo library, the 4 vCPU / 8 GB RAM plan works well — the machine learning features (face detection, CLIP search) benefit from the extra CPU. CBS cloud disk expansion is the most important Lighthouse feature here: photo collections grow indefinitely, and being able to attach additional storage volumes (up to 32 TB) without server migration makes Lighthouse a practical long-term platform for photo storage. The snapshot feature also lets you protect years of photos with a full server backup before major Immich upgrades.


Table of Contents

  1. What Immich Provides
  2. Prerequisites
  3. Part 1 — Server Setup
  4. Part 2 — Deploy Immich with Docker Compose
  5. Part 3 — Configure Nginx Reverse Proxy
  6. Part 4 — Enable HTTPS
  7. Part 5 — Initial Setup and First Login
  8. Part 6 — Configure Mobile App for Auto-Backup
  9. Part 7 — Storage and External Library
  10. Part 8 — Backups
  11. The Gotcha: Machine Learning Requires Significant RAM
  12. Maintenance Commands

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

What Immich Provides {#what}

Feature What it does
Auto-backup Mobile app backs up photos/videos automatically
Timeline view Browse photos by date, month, year
Smart search Search by objects, scenes, places
Face recognition Group photos by person
Shared albums Share with family and friends
Map view View where photos were taken
Trash 30-day recovery bin
External libraries Index existing photo directories

Prerequisites {#prerequisites}

Requirement Notes
Cloud server Tencent Cloud Lighthouse — select Docker CE application image for pre-installed Docker
4 GB+ RAM Machine learning features need 2+ GB
20 GB+ storage Grows with your photo library; add data disk
Domain name For mobile app and HTTPS

Part 1 — Server Setup {#part-1}

💡 If you selected the Docker CE application image, Docker is already running. Skip the Docker install lines and start from sudo apt update.

ssh ubuntu@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

sudo apt install -y nginx
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

# Create photos directory (or point to mounted data disk)
sudo mkdir -p /data/immich
sudo chown ubuntu:ubuntu /data/immich

Part 2 — Deploy Immich with Docker Compose {#part-2}

mkdir -p ~/apps/immich && cd ~/apps/immich

# Download official docker-compose.yml and .env template
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

Edit .env:

nano .env

Key settings to configure:

# Photo upload location
UPLOAD_LOCATION=/data/immich/library

# Database credentials (auto-generated, change if desired)
DB_PASSWORD=generate_a_strong_password
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

# Machine learning
IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003

# Timezone
TZ=America/New_York
chmod 600 .env

# Start Immich (all services)
docker compose up -d

# Monitor startup (takes 2-5 minutes on first run)
docker compose logs -f immich-server
# Wait for: Immich Server is listening on...

Immich starts several services:

  • immich-server — main API and web interface
  • immich-microservices — background processing (thumbnails, metadata)
  • immich-machine-learning — AI features (face recognition, smart search)
  • postgres — database
  • redis — caching

Part 3 — Configure Nginx Reverse Proxy {#part-3}

sudo nano /etc/nginx/sites-available/immich
server {
    listen 80;
    server_name photos.yourdomain.com;

    # Large file upload support (videos and RAW photos)
    client_max_body_size 50000m;
    proxy_request_buffering off;

    location / {
        proxy_pass http://127.0.0.1:2283;
        proxy_http_version 1.1;

        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;

        proxy_buffering off;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}
sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Part 4 — Enable HTTPS {#part-4}

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d photos.yourdomain.com

Part 5 — Initial Setup and First Login {#part-5}

Visit https://photos.yourdomain.com.

  1. Create admin account — this is the first user, automatically granted admin
  2. Log in and explore the interface
  3. Admin → System Settings — configure storage quotas, OAuth, etc.

Create additional users (optional)

Admin panel → User Management → Create User


Part 6 — Configure Mobile App for Auto-Backup {#part-6}

Download the Immich app for iOS or Android.

  1. Open Immich app
  2. Server URL: https://photos.yourdomain.com
  3. Log in with your credentials
  4. Photos tab → Backup → Enable Background Backup
  5. Configure: backup on WiFi only, backup videos, etc.

The app will now automatically upload new photos and videos as they're taken.


Part 7 — Storage and External Library {#part-7}

Add more storage

If your Lighthouse instance's disk is getting full:

  1. Add a data disk in the Lighthouse console
  2. Format and mount it:
    sudo mkfs.ext4 /dev/vdb
    sudo mkdir -p /data/photos
    sudo mount /dev/vdb /data/photos
    echo "/dev/vdb /data/photos ext4 defaults 0 2" | sudo tee -a /etc/fstab
    
  3. Update .env: UPLOAD_LOCATION=/data/photos/library
  4. Restart Immich: docker compose restart

External libraries

Immich can index photos that already exist in a directory without moving them:

  1. Admin → External Libraries → Create Library
  2. Set the path: /data/existing-photos
  3. Click Scan — Immich indexes the photos without copying them

Part 8 — Backups {#part-8}

nano ~/backup_immich.sh
#!/bin/bash
BACKUP_DIR=/home/ubuntu/backups/immich
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

source ~/apps/immich/.env

# Backup database
docker exec immich-postgres pg_dump \
  -U postgres immich | \
  gzip > $BACKUP_DIR/immich_db_$DATE.sql.gz

# Note: Photo files in $UPLOAD_LOCATION are the most important backup
# Use rsync to a separate storage location:
# rsync -avz /data/immich/library/ /backup/immich/library/

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

echo "Immich backup: $DATE"
chmod +x ~/backup_immich.sh
(crontab -l; echo "0 3 * * * ~/backup_immich.sh") | crontab -

Most important: back up the actual photo files in UPLOAD_LOCATION. These are the originals — the database can be rebuilt, but photos cannot.


The Gotcha: Machine Learning Requires Significant RAM {#gotcha}

Immich's machine learning service (face recognition, smart search, CLIP embeddings) loads AI models into RAM. On first load, it uses 1-2 GB of RAM.

On servers with 4 GB total RAM:

  • Postgres: ~200 MB
  • Immich server + microservices: ~500 MB
  • Machine learning: ~1-2 GB (on first use)
  • OS: ~500 MB

This leaves minimal headroom. If you're on a 2 GB RAM server, disable machine learning:

In docker-compose.yml, comment out the immich-machine-learning service and remove references to IMMICH_MACHINE_LEARNING_URL.

Alternatively, add swap:

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

Maintenance Commands {#maintenance}

# Update Immich (do this regularly — Immich releases often)
cd ~/apps/immich
docker compose pull
docker compose up -d --remove-orphans

# View server logs
docker compose logs -f immich-server

# View machine learning logs
docker compose logs -f immich-machine-learning

# Force re-scan all photos
docker exec immich-microservices node dist/main.js metadata-extraction

# Check container resource usage
docker stats

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

How much disk space do I need for Immich?
Start with the base system disk (40–80 GB). For media-heavy uses, attach a CBS cloud disk — Lighthouse supports expansion up to 32 TB. Add storage as your collection grows without re-provisioning the server.

How do I migrate Immich data to a larger disk?
On Lighthouse, you can attach an additional CBS disk and move data to it. For the OS disk itself, take a snapshot and restore to a larger instance. The guide covers storage expansion options.

Is data on a cloud VPS truly private?
Data on your Lighthouse instance is stored in Tencent Cloud's infrastructure. For maximum privacy, enable encryption at the application layer. Lighthouse provides data center compliance but you're ultimately trusting the cloud provider's infrastructure security.

How do I handle backups for large media collections?
For Immich specifically: use Lighthouse snapshots for full system recovery plus application-level exports for granular recovery. For very large collections, consider versioned backups and retention policies.

What happens to my data if I stop paying for the server?
Cloud servers are terminated after a grace period if payment lapses. Always maintain your billing and export critical data regularly to an independent location (external storage, another cloud provider).

Self-host your photo library:
👉 Tencent Cloud Lighthouse — High-storage VPS for photo management
👉 View current pricing and promotions
👉 Explore all active deals and offers