# Self-host Immich on a VPS

> Run Immich, the self-hosted photo and video backup, from its Docker Compose file, keep it private until it has HTTPS, and back up your phone to it.

Source: https://vpsnine.com/help/self-host-immich · Updated: 2026-10-21

To self-host Immich, download the `docker-compose.yml` and `example.env` from its latest release, set a database password and a storage location, and start it with `docker compose up -d`. On VPSNine the Immich one-click app does that on the first boot, keeps Immich on the server's loopback, creates the admin account for you, and puts it on your domain with HTTPS in one command.

Immich backs up photos and videos from your phone and organises them with faces, places and search, much like Google Photos.

## What you need

- The Extreme plan (4 vCPU, 8 GB). It's the only plan we offer Immich on: Immich asks for at least 6 GB of memory and recommends 8 GB, and 4 GB only works with its machine learning turned off.
- Room for your library. Extreme has 160 GB, shared between your originals, Immich's thumbnails and converted videos (10 to 20% on top), the database (1 to 3 GB) and the system. That's roughly 120 GB of photos and videos. Check your phone's library size before you start.
- A domain or subdomain for it, like `photos.example.com`. The phone app connects to it over HTTPS.

## Install it with the one-click app

Order a server with the [Immich app](https://vpsnine.com/apps/immich). On the first boot we install Docker and use the `docker-compose.yml` and `example.env` from Immich's latest release in `/opt/immich`: the server, machine learning, PostgreSQL and Valkey. Immich's own Compose file publishes port 2283 to everyone; the installer changes it to `127.0.0.1:2283`, and stops rather than start Immich publicly if it can't. Immich normally makes the first person to sign up its admin, so the installer creates the admin before anyone can reach the port. [One-click apps](https://vpsnine.com/help/one-click-apps) shows how to follow the install.

Immich is ready when this answers `pong` on the server:

```bash
curl http://127.0.0.1:2283/api/server/ping
```

Then:

1. Point `photos.example.com` at the server (an `A` record with its IPv4 address, for example `203.0.113.10`), allow ports 80 and 443 in [the panel firewall](https://vpsnine.com/help/server-firewall), and run:

   ```bash
   vps9-https photos.example.com
   ```

2. Show your login, open `https://photos.example.com` and log in. In **Account Settings**, change the admin's email (it starts as `admin@example.com`) and password.

   ```bash
   cat /root/immich-admin.txt
   ```

3. Install the Immich app on your phone, connect it to `https://photos.example.com`, and turn on backup.

To look around before you have a domain, open an SSH tunnel from your computer with `ssh -L 2283:127.0.0.1:2283 root@203.0.113.10` and browse to `http://localhost:2283`.

## Put it on your domain with HTTPS

For Immich, `vps9-https` installs Caddy from Caddy's own packages, writes a site for your domain that passes everything to `127.0.0.1:2283`, and reloads Caddy, which gets and renews a Let's Encrypt certificate. Port 2283 stays on loopback; only 80 and 443 face the internet.

If the domain doesn't point at the server yet, it says so, and Caddy gets the certificate once DNS catches up. To move to another domain, run it again with the new one.

## Doing it by hand on another server

Immich's [Docker Compose guide](https://docs.immich.app/install/docker-compose) is the official method. You need Docker Engine with the Compose plugin; [Install Docker](https://vpsnine.com/help/install-docker) covers it. The outline:

```bash
mkdir /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
```

In `.env`, set `UPLOAD_LOCATION` to a folder with enough space, `DB_DATA_LOCATION` to local storage (not a network share), `DB_PASSWORD` to letters and digits only, and `TZ` to your time zone. Before you start it, change the server's `2283:2283` port line in `docker-compose.yml` to `127.0.0.1:2283:2283`, so the first visitor can't claim the admin account. Then:

```bash
docker compose up -d
```

Open it through an SSH tunnel, create the admin account, and put a reverse proxy with a certificate in front, as in [Serve a site with nginx and HTTPS](https://vpsnine.com/help/nginx-and-https).

## Updates and backups

Updates are yours, and Immich changes often. Read the release notes first, especially for breaking changes, then:

```bash
cd /opt/immich
docker compose pull
docker compose up -d
```

We turn on the operating system's automatic security updates; they don't touch Immich's containers.

Immich dumps its database every night into the `backups` folder under `/opt/immich/library`. Copy that, and the `library`, `upload` and `profile` folders that hold your photos, off the server. [Backups you should run](https://vpsnine.com/help/backups-you-should-run) shows how to do it nightly.

Immich isn't a backup on its own, and its own documentation says not to rely on it as your only copy. Keep a second copy of your library somewhere else, such as an external drive or another provider's storage, and test that you can restore it.

## When it goes wrong

- **The phone app can't connect**: give it the full `https://photos.example.com` address. Port 2283 isn't public, so `http://203.0.113.10:2283` won't work from your phone. If the HTTPS address doesn't load in a browser either, check the domain points at the server and that ports 80 and 443 are open; `journalctl -u caddy -n 30` shows whether Caddy got its certificate.
- **The disk fills up**: check with `df -h` and `du -sh /opt/immich/library`. Converted videos and thumbnails add 10 to 20% to your originals. Empty Immich's trash, or add disk with the [Extra NVMe add-on](https://vpsnine.com/help/add-ons) before you hit the limit, since a full disk can stop the database.
- **The server runs out of memory**: machine learning is the biggest user. You can turn it off in **Administration**, **Settings**, **Machine Learning**, and remove the `immich-machine-learning` service from `/opt/immich/docker-compose.yml`. Face recognition and smart search then stop working.
