← Blog
Self-Host Your Photo Library with Immich

Your photos are probably sitting in someone else’s cloud right now. Every picture of your kids, every vacation, every moment — stored on servers you don’t control, scanned by algorithms you didn’t agree to, and subject to pricing changes you can’t predict.

Immich changes that. It’s a self-hosted photo and video management platform that runs on your own server. Face recognition, mobile auto-backup, smart search, shared albums, map view — all the features you expect from a modern photo service, but on hardware you own.

This guide walks you through deploying Immich on a Linux server using Docker Compose. You’ll have a working photo server in under 30 minutes.

What you’ll need

  • A Linux server (Ubuntu 22.04/24.04, Debian 12, or any distro with Docker support)
  • At least 6 GB RAM (8 GB recommended — the ML container needs room to work)
  • 2+ CPU cores (4 recommended)
  • Storage sized to your photo library — plan for your existing library plus 10–20% overhead for thumbnails and transcoded video
  • Docker Engine 25+ with the docker compose plugin (not the deprecated docker-compose)

A VPS with 4 cores and 8 GB RAM handles a family library of 50,000+ photos comfortably. For larger collections or if you want snappier face recognition processing, a dedicated server with more RAM and NVMe storage makes a noticeable difference.

Step 1 — Install Docker

If Docker isn’t already installed, set it up from the official repository. Don’t use the docker.io package from Ubuntu’s default repos — it’s outdated and missing the Compose plugin.

# Remove old versions
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null

# Add Docker’s official GPG key and repository
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

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

# Install Docker Engine + Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Add your user to the docker group
sudo usermod -aG docker $USER

Log out and back in for the group change to take effect. Verify with:

docker compose version

Step 2 — Download the Immich config files

Create a directory for Immich and pull the official Docker Compose and environment files:

mkdir -p /opt/immich && cd /opt/immich

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>

Step 3 — Configure the environment

Edit the .env file to set your storage paths and a secure database password:

nano .env

The key variables to change:

UPLOAD_LOCATION=/mnt/data/immich/library
DB_DATA_LOCATION=/opt/immich/postgres
IMMICH_VERSION=v2
DB_PASSWORD=your_secure_password_here

Generate a strong password with:

openssl rand -base64 32

Two important rules for storage paths:

  • UPLOAD_LOCATION can be on any filesystem — this is where your photos live, so point it at your largest drive.
  • DB_DATA_LOCATION should be on an SSD. The database performance directly affects how fast the UI feels.

Step 4 — Start Immich

cd /opt/immich
docker compose up -d

Watch the logs to make sure everything starts cleanly:

docker compose logs -f immich-server

You’re looking for the server to report that it’s listening on port 2283. The machine learning container takes a minute or two on first start to download its models — that’s normal.

Verify all containers are running:

docker compose ps

Step 5 — Create your admin account

Open your browser and go to http://your-server-ip:2283

Click “Getting Started” and create the first account. This will be the admin user.

Step 6 — Set up mobile backup

Install the Immich app on your phone (iOS App Store or Android Google Play/F-Droid).

  1. Enter your server URL
  2. Log in with your admin credentials
  3. Enable automatic backup in the cloud icon settings
  4. Select which albums to back up

Step 7 — Set up HTTPS with a reverse proxy

For remote access, you’ll want HTTPS. Basic Nginx reverse proxy with Let’s Encrypt:

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

Create a config file at /etc/nginx/sites-available/immich:

server {
    listen 80;
    server_name photos.yourdomain.com;
    client_max_body_size 50000M;
    location / {
        proxy_pass <http://127.0.0.1:2283>;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Enable and get SSL:

sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d photos.yourdomain.com

Step 8 — Import an existing photo library

Immich can index existing photos without copying them. Add a volume mount to docker-compose.yml:

services:
  immich-server:
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /path/to/existing/photos:/mnt/photos:ro

Then go to Administration → External Libraries → Create External Library and set the import path to /mnt/photos.

Keeping Immich updated

cd /opt/immich
docker compose pull
docker compose up -d
docker image prune -f

Backups matter

Add a nightly database backup to your crontab:

0 3 * * * cd /opt/immich && docker compose exec -T immich_postgres pg_dumpall -U postgres | gzip > /mnt/backups/immich-db-$(date +\\%Y\\%m\\%d).sql.gz

Troubleshooting

  • ML container restarting: Usually RAM. Need more RAM or switch to smaller ML models.
  • Uploads slow: Check Nginx client_max_body_size. Database must be on SSD.
  • Face recognition not working: Runs in background. Check Administration → Jobs.

Continue reading

Community zone

A question ?
Find answers and share your knowledge !

We are waiting you on community zone. More than 70 guides (sysadmin, gaming, devops...) !

Let me check
DEDIMAX DEDIMAX DEDIMAX DEDIMAX
DEDIMAX

Need a quote ?

Write us !

Contact us

Prendre contact