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.
- Key Takeaways
| 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 |
| 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 |
💡 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
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 interfaceimmich-microservices — background processing (thumbnails, metadata)immich-machine-learning — AI features (face recognition, smart search)postgres — databaseredis — cachingsudo 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
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d photos.yourdomain.com
Visit https://photos.yourdomain.com.
Admin panel → User Management → Create User
Download the Immich app for iOS or Android.
https://photos.yourdomain.comThe app will now automatically upload new photos and videos as they're taken.
If your Lighthouse instance's disk is getting full:
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
.env: UPLOAD_LOCATION=/data/photos/librarydocker compose restartImmich can index photos that already exist in a directory without moving them:
/data/existing-photosnano ~/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.
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:
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
# 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
| 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 |
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.
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