Immich on Ubuntu 24.04 on Azure User Guide
Overview
Immich is a self-hosted photo and video management platform - a private alternative to commercial cloud photo services. You upload your photos and videos, browse them on a fast timeline, organise them into albums, search and share them, and keep everything in sync from the Immich mobile apps. The cloudimg image installs the official Immich self-host Docker Compose stack, pinned to v3.1.0: the immich-server (the API and web UI), a PostgreSQL 14 database with the VectorChord / pgvecto-rs vector extension, and a redis (Valkey) cache. A host nginx allowlist reverse-proxy publishes the app on port 80, and the database and cache stay on the internal Docker network only.
Immich has no default administrator - the first account registered on a new instance becomes the admin. On a public VM that is a trap: an unauthenticated visitor could seize a fresh machine by registering first. The cloudimg image closes it. On the first boot of every VM, before the site is reachable, a fresh per-VM admin is seeded through the Immich admin sign-up API, the database password is rotated and the database is initialised clean (which regenerates all of Immich's session material), and the one unique admin password is written to a root-only file. Backed by 24/7 cloudimg support.
What is included:
- The official Immich v3.1.0 self-host stack running under Docker (the
immich-server, a PostgreSQL 14 + VectorChorddatabaseand a Valkeyredis), pinned so it never silently upgrades - The web UI and API published on port
80through an nginx allowlist reverse-proxy (server_tokens off,absolute_redirect off, the.envand compose file return404) - A per-VM admin account seeded on first boot - a unique password recorded in a root-only file - before the site is reachable, so the first-registration-becomes-admin trap is closed on every VM
- The PostgreSQL password rotated and the database re-initialised clean on first boot, so no two VMs share a database or session secret
- The whole stack managed as one
immich.servicesystemd unit, gated on the first-boot marker, plusnginx.serviceanddocker.service, all enabled - PostgreSQL and Redis bound to the internal Docker network only - just
22/tcp(SSH) and80/tcp(the Immich UI) are exposed - Machine learning (smart search, face recognition) shipped switched off so the appliance runs comfortably on a small VM, with clear steps to enable it on a larger one
- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) comfortably runs the core stack (server + database + cache) with machine learning off. If you want Immich's machine-learning features (smart search and face recognition), launch on a larger size such as Standard_B4ms (see Step 10). NSG inbound: allow 22/tcp from your management network and 80/tcp from the clients that will use Immich. The app serves plain HTTP; for production, put it behind your own domain and TLS.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Immich by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), then add 80 after deployment. Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name immich \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name immich --port 80 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the stack is running
Immich runs as a Docker Compose stack managed by a single systemd unit. On first boot the stack rotates its database password, re-initialises on a clean database, seeds the per-VM admin and starts; the multi-container stack can take a minute or two to become fully healthy after the VM is created.
systemctl is-active immich.service
It reports active. You can list the running containers with:
sudo docker compose -f /var/lib/immich/docker-compose.yml ps

The whole stack is managed as one systemd unit - use sudo systemctl status immich and sudo systemctl restart immich to control every container together.
Step 5 - Retrieve your per-VM admin credentials
The admin password is generated uniquely on the first boot of your VM and written to a root-only file. Confirm the file exists (it is 0600, root-only):
sudo ls -l /root/immich-credentials.txt
Then read it to get your credentials:
sudo cat /root/immich-credentials.txt
The file contains immich.url (the address to browse to), immich.admin.email and IMMICH_ADMIN_PASSWORD (for the web UI). Store them somewhere safe. The first-boot service that seeded them is a one-shot unit you can confirm ran:
systemctl is-active immich-firstboot.service

Step 6 - Confirm the endpoints are healthy
The Immich UI answers on port 80 through the nginx reverse-proxy:
curl -s -o /dev/null -w 'UI (nginx :80) -> HTTP %{http_code}\n' http://localhost/
It returns HTTP 200. The Immich server's health endpoint answers pong:
curl -s http://localhost/api/server/ping
You can confirm which ports are published - PostgreSQL (5432) and Redis (6379) are deliberately not among them, they stay on the internal Docker network:
sudo ss -tlnH | awk '{print $4}' | sort -u

Step 7 - Confirm the pinned release
The images are pinned to Immich v3.1.0 (with the database and cache images digest-pinned) so the appliance never silently upgrades:
sudo docker compose -f /var/lib/immich/docker-compose.yml images

Step 8 - Sign in to the web UI
In a browser, go to http://<vm-public-ip>/. You are greeted by the Immich login page. Sign in with the immich.admin.email and IMMICH_ADMIN_PASSWORD from Step 5. Because the admin was already seeded on first boot, there is no "register" step for a stranger to hijack - you land straight on the login form.

Step 9 - Upload your first photos
Select Upload (top right) and choose some photos or videos, or install an Immich mobile app and point it at http://<vm-public-ip>/ to back up your camera roll automatically. Uploaded media appears on the timeline immediately, grouped by date.

Group photos into albums from the Albums section - create an album, add assets to it, and share it with a link or another user.

Step 10 - Manage users and enable machine learning (optional)
As the admin you manage users and server settings from Administration. The image ships with exactly one account - your per-VM admin - and Immich only creates further users when you invite them, so there is no open sign-up.

Machine learning (smart search and face recognition) ships disabled so the appliance fits a small VM. To enable it, launch the image on a larger VM (Standard_B4ms or bigger), then bring the machine-learning container up and turn the feature on:
cd /var/lib/immich
sudo docker compose --profile ml up -d
Then, in the web UI, go to Administration -> Settings -> Machine Learning Settings and enable it. Immich will begin generating smart-search embeddings and detecting faces on your library.
Support
Every cloudimg image is backed by 24/7 support and a deploy guide tested against the exact build. If you need help, contact cloudimg support.