PhotoPrism on Ubuntu 24.04 on Azure User Guide
Overview
PhotoPrism is an AI-powered, self-hosted application for browsing, organising and sharing your photos and videos. It indexes your collection into a fast, searchable library, automatically tags what is in each picture and groups faces, places and moments, so you can find any shot in seconds - all on infrastructure you control rather than a third-party photo service. The cloudimg image installs PhotoPrism 260601 as the official container paired with MariaDB, runs it behind nginx as a systemd service, and even indexes a small demo library on first boot, so your photo library is online and ready to explore within minutes of launch.
What is included:
- PhotoPrism 260601 (AGPL-3.0) deployed from the official
photoprism/photoprismDocker image, pinned so the image never silently upgrades at build time - Docker Engine (Docker CE) + the Docker Compose plugin, installed from the official Docker package repository
- The PhotoPrism stack: the
photoprismcontainer (the Go application with bundled TensorFlow models, ffmpeg, libheif and RAW converters) andmariadb(mariadb:11, PhotoPrism's recommended index database), run together via Docker Compose on a private network - Automatic tagging and face recognition powered by the bundled TensorFlow models, running entirely on CPU - no GPU instance required
- A system
nginxreverse proxy on port 80 forwarding to PhotoPrism on127.0.0.1:2342, with the WebSocket upgrade headers and a raised upload limit for large photos and videos - All stateful data - the MariaDB database, your imported originals and the thumbnail and sidecar storage tree - on a dedicated 64 GiB data disk mounted at
/var/lib/photoprism(Docker's data-root is relocated there), independently resizable and re-provisioned on every VM - A per-VM administrator account and fresh MariaDB user and root passwords, all generated at first boot, plus a small public-domain demo library indexed so the grid is populated on your first sign-in
- Four systemd units:
docker.service,nginx.service,photoprism.service(a wrapper arounddocker compose up -d) andphotoprism-firstboot.service - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key, and a VNet plus subnet. Standard_B2ms (2 vCPU / 8 GB RAM) is the recommended size - PhotoPrism loads the TensorFlow classification and face models into memory and MariaDB adds its buffer pool, so 8 GB gives comfortable headroom for indexing. NSG inbound rules: allow 22/tcp from your management CIDR for SSH and 80/tcp from the CIDR that needs the PhotoPrism web app (add 443/tcp if you enable HTTPS).
Step 1: Connect over SSH
Replace <vm-ip> with the public IP of your VM. The default login user is azureuser.
ssh azureuser@<vm-ip>
Step 2: Confirm the services are active
sudo systemctl is-active docker.service photoprism-firstboot.service photoprism.service nginx.service
sudo ss -tlnp | grep -E ':80 |2342'
You should see active printed four times. The ss output shows nginx listening publicly on port 80, while PhotoPrism is bound to the loopback interface only on 127.0.0.1:2342 - nginx is the only service exposed on the public interface.

Step 3: Confirm the PhotoPrism containers are running
grep image /opt/photoprism/compose.yaml
cd /opt/photoprism && sudo docker compose --env-file .env -f compose.yaml ps --format "table {{.Name}}\t{{.Image}}\t{{.Status}}"
You should see the pinned image tags and the two containers - photoprism-photoprism-1 and photoprism-mariadb-1 - both in the Up state (MariaDB reports healthy).

Step 4: Confirm the data disk and read the per-VM credentials
All stateful PhotoPrism data - the MariaDB database, your imported originals and the thumbnail and sidecar storage - lives on a dedicated data disk mounted at /var/lib/photoprism. A unique administrator password and fresh database secrets are generated for your instance on its first boot and written to a root-only file.
df -h /var/lib/photoprism
sudo cat /root/photoprism-credentials.txt
The credentials file lists PHOTOPRISM_URL (where to sign in), PHOTOPRISM_ADMIN_USER (admin) and PHOTOPRISM_ADMIN_PASSWORD. Store the password somewhere safe.

Step 5: Check the endpoint and the security model
The nginx reverse proxy serves PhotoPrism's unauthenticated /api/v1/status readiness endpoint on port 80, and every protected action requires the per-VM administrator credentials.
curl -s http://localhost/api/v1/status
U=admin
P=$(sudo grep '^PHOTOPRISM_ADMIN_PASSWORD=' /root/photoprism-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w "wrong password -> HTTP %{http_code}\n" -X POST http://localhost/api/v1/session \
-H 'Content-Type: application/json' -d "{\"username\":\"$U\",\"password\":\"wrong\"}"
curl -s -X POST http://localhost/api/v1/session -H 'Content-Type: application/json' \
-d "{\"username\":\"$U\",\"password\":\"$P\"}" | grep -o '"access_token"' | head -1
/api/v1/status returns {"status":"operational"}, a wrong password is rejected with HTTP 401, and the correct per-VM password returns an access_token - confirming the appliance is up and that there is no default or shared login.

Step 6: Sign in to PhotoPrism
Open http://<vm-ip>/ in your browser. Enter admin as the username and the PHOTOPRISM_ADMIN_PASSWORD from Step 4, then click Sign in.

Step 7: Browse your photo library
After signing in you land on the library grid. A small demo library of public-domain photos has already been indexed for you, so the grid shows real thumbnails from the moment you arrive. Each tile shows the picture, its file name and its dimensions.

Click any picture to open it full screen in the viewer, where you can page through your photos, zoom, and open the details panel for the metadata, labels and location extracted on indexing:

Step 8: Explore places, search and albums
The left navigation gives you the full PhotoPrism experience: search across your whole library, an interactive Places map that plots geotagged photos, a Calendar view, Albums, Labels (the automatic AI tags), Faces and more.

To add your own photos, either upload them from the web UI with the Upload button, or copy files into /var/lib/photoprism on the data disk and start an index from the Library menu - PhotoPrism extracts the metadata, generates thumbnails, tags the content with machine learning and recognises faces. The demo photos are just sample content; you can select and delete them at any time.
Managing the stack
The PhotoPrism stack is wrapped by the photoprism.service systemd unit, which runs docker compose up -d from /opt/photoprism.
sudo systemctl restart photoprism.service
sudo systemctl status photoprism.service --no-pager
To inspect the application logs, tail the PhotoPrism container:
cd /opt/photoprism
sudo docker compose --env-file .env -f compose.yaml logs --tail 50 photoprism
PhotoPrism configuration lives in /opt/photoprism/compose.yaml and the per-VM secrets in /opt/photoprism/.env. By default this image disables PhotoPrism's quality-review filter so all indexed photos appear in the main library view immediately; you can re-enable review under Settings > Library if you prefer to approve lower-quality pictures before they show.
Enabling HTTPS
The image serves plain HTTP on port 80. For any public deployment, put TLS in front with your own domain. Point a DNS A record at the VM public IP, then install a certificate with certbot's nginx plugin. Outline:
- Install certbot and the nginx plugin from the Ubuntu repositories.
- Run certbot against your domain to obtain and install a certificate into the nginx site.
- Once TLS is terminating at nginx, set
PHOTOPRISM_SITE_URL=https://your-domain/in/opt/photoprism/.env, then restart the stack withsudo systemctl restart photoprism.serviceso PhotoPrism generates correcthttps://links and share URLs.
Use your own registered domain in place of any example placeholder.
Maintenance
The OS receives unattended security updates. To update PhotoPrism itself, edit the pinned image tag in /opt/photoprism/compose.yaml, then from /opt/photoprism run sudo docker compose --env-file .env -f compose.yaml pull followed by sudo systemctl restart photoprism.service. Always snapshot the /var/lib/photoprism data disk before a major version upgrade.
Support
Backed by 24/7 cloudimg support. PhotoPrism and MariaDB are trademarks of their respective owners. This image is provided by cloudimg and is not affiliated with or endorsed by the PhotoPrism project or MariaDB.