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.
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. 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 shows how to follow the install.
Immich is ready when this answers pong on the server:
curl http://127.0.0.1:2283/api/server/pingThen:
Point
photos.example.comat the server (anArecord with its IPv4 address, for example203.0.113.10), allow ports 80 and 443 in the panel firewall, and run:vps9-https photos.example.comShow your login, open
https://photos.example.comand log in. In Account Settings, change the admin's email (it starts asadmin@example.com) and password.cat /root/immich-admin.txtInstall 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 is the official method. You need Docker Engine with the Compose plugin; Install Docker covers it. The outline:
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.envIn .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:
docker compose up -dOpen 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.
Updates and backups
Updates are yours, and Immich changes often. Read the release notes first, especially for breaking changes, then:
cd /opt/immich
docker compose pull
docker compose up -dWe 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 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.comaddress. Port 2283 isn't public, sohttp://203.0.113.10:2283won'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 30shows whether Caddy got its certificate. - The disk fills up: check with
df -handdu -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 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-learningservice from/opt/immich/docker-compose.yml. Face recognition and smart search then stop working.