New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
PhotoPrism indexes photos and videos on your own server, groups them by date, place, and people, reads metadata, and provides browser-based search. This recipe uses MariaDB, keeps originals locally, and exposes the web interface on localhost only.
PhotoPrism turns a directory of photos and videos into a private web library. It indexes the existing folder structure, reads EXIF and XMP, generates previews, shows calendar and map views, recognizes faces, and searches with filters. It is suited to personal or family archives as an alternative to Google Photos, iCloud Photos, and cloud file viewers. Community Edition has no first-party native mobile app for automatic uploads.
The recipe runs official PhotoPrism image 260728, corresponding to release
260728-bbde8f452, with MariaDB 12.3.2. Originals and writable storage use host
directories, while the database uses a separate Docker volume. Optional Ollama,
PhotoPrism Vision, Watchtower, and hardware acceleration are deliberately absent.
The full HTTP smoke test has passed on amd64 and arm64; backup, restore, and real
media processing remain untested. The port binds to localhost, MariaDB is not published, and
password authentication is required. The recipe does not encrypt originals,
previews, the database, or .env. The indexer passes untrusted formats to
external libraries and needs bursts of memory while it works. The recipe
therefore sets no memory limit — a tight cap gets the indexer OOM-killed
mid-run — so size the host for the peak instead.
Community Edition is available under AGPL-3.0, while additional upstream terms protect the trademark and brand assets. Some paid-edition capabilities are not part of Community Edition; consult upstream’s current comparison.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
260728260728There is no exact release-notes URL for this manually tracked source. Start with the project sources below.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Manual steps after the pull. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has not been tested.
An exact Fully verified check for this target was recorded on 2026-09-03.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
You still need to add: single server, local access, minimum components.
A public deployment with protected access and backups.
You still need to add: domain, https via reverse proxy, off-server backup.
A setup designed for predictable operations and observability.
You still need to add: external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run PhotoPrism bundle.
Screenshots have not been added yet.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psUse Ubuntu 22.04+ or Debian 12+ with Docker Engine and Compose v2.24+. Allocate at least 2 CPUs, 4 GB RAM, and 4 GB swap; 8 GB RAM is recommended for large files and indexing. Disk must hold originals, previews, sidecars, and backups.
docker --version
docker compose version
free -h && df -h /srv
mkdir -p ~/services/photoprism
sudo mkdir -p /srv/photoprism/{originals,storage,backups}
sudo chown -R "$(id -u):$(id -g)" /srv/photoprism
cd ~/services/photoprism
cp .env.example .env
chmod 600 .env
sed -i "s|^PHOTOPRISM_ADMIN_PASSWORD=.*|PHOTOPRISM_ADMIN_PASSWORD=$(openssl rand -base64 36 | tr -d '/+=')|" .env
sed -i "0,/^PHOTOPRISM_DATABASE_PASSWORD=.*/s||PHOTOPRISM_DATABASE_PASSWORD=$(openssl rand -hex 32)|" .env
sed -i "s|^PHOTOPRISM_DATABASE_ROOT_PASSWORD=.*|PHOTOPRISM_DATABASE_ROOT_PASSWORD=$(openssl rand -hex 32)|" .env
sed -i 's|^PHOTOPRISM_ORIGINALS_PATH=.*|PHOTOPRISM_ORIGINALS_PATH=/srv/photoprism/originals|' .env
sed -i 's|^PHOTOPRISM_STORAGE_PATH=.*|PHOTOPRISM_STORAGE_PATH=/srv/photoprism/storage|' .env
sed -i 's|^PHOTOPRISM_BACKUP_DIR=.*|PHOTOPRISM_BACKUP_DIR=/srv/photoprism/backups|' .env
sed -i "s|^PHOTOPRISM_UID=.*|PHOTOPRISM_UID=$(id -u)|" .env
sed -i "s|^PHOTOPRISM_GID=.*|PHOTOPRISM_GID=$(id -g)|" .env
Every .env variable:
PHOTOPRISM_VERSION is the exact official image tag;PHOTOPRISM_PORT is the local web port;PHOTOPRISM_SITE_URL is the public URL with a trailing /;PHOTOPRISM_ADMIN_USER and PHOTOPRISM_ADMIN_PASSWORD form the initial administrator account;PHOTOPRISM_DEFAULT_LOCALE selects the initial interface language;PHOTOPRISM_ORIGINALS_PATH holds original photos and videos;PHOTOPRISM_STORAGE_PATH holds previews, cache, sidecars, configuration, and dumps;PHOTOPRISM_BACKUP_DIR is the local backup directory used by backup.sh;PHOTOPRISM_UID and PHOTOPRISM_GID are the user the image runs the server as; they must match the owner of the directories above;PHOTOPRISM_INIT is empty by default; setting tensorflow downloads a CPU-tuned TensorFlow build (~500 MB) on every container re-creation and holds the web server back until it lands;PHOTOPRISM_DATABASE_NAME, PHOTOPRISM_DATABASE_USER, and PHOTOPRISM_DATABASE_PASSWORD configure the application database account;PHOTOPRISM_DATABASE_ROOT_PASSWORD is used only for MariaDB administration and restore;PHOTOPRISM_DATABASE_VOLUME names the MariaDB volume;TZ is an IANA time zone.docker compose config
docker compose pull
docker compose up -d --wait
docker compose ps
curl --fail http://127.0.0.1:2342/api/v1/status
Open http://localhost:2342 through an SSH tunnel and sign in with .env:
ssh -L 2342:127.0.0.1:2342 user@server.example
Keep the 127.0.0.1 binding, do not publish MariaDB, and allow only SSH, HTTP,
and HTTPS through the firewall. Set
PHOTOPRISM_SITE_URL=https://photos.example.com/, recreate the container, and
expose it only through an HTTPS reverse proxy.
Without TLS, use an SSH tunnel or VPN. For permanent LAN access, replace
127.0.0.1 in compose.yaml with a specific private address, set the matching
origin in PHOTOPRISM_SITE_URL, and restrict the port with a firewall. Do not
use 0.0.0.0 without network controls.
Replace photos.example.com in one file under proxy/. Caddy obtains a
certificate, Nginx expects Certbot files, and Traefik uses the letsencrypt
resolver. For a containerized proxy, localhost means the proxy itself; use a
reachable host gateway. After changing the URL, run:
docker compose up -d --force-recreate photoprism
curl --fail https://photos.example.com/api/v1/status
chmod +x backup.sh restore.sh
./backup.sh
The script stops PhotoPrism, dumps MariaDB, and archives the originals and
storage directories into a single .tar in PHOTOPRISM_BACKUP_DIR. Stopping is
required: an index running during the copy would leave the database describing
files the originals archive does not contain. The root password reaches the
container through MYSQL_PWD rather than argv, so it stays out of the process
list. The archive holds photos and passwords: encrypt it, keep an off-server
copy, and test restores. Built-in database dumps in storage do not replace an
originals backup.
Restore irreversibly replaces the originals, storage, and database. The script
takes an emergency copy of the current state before replacing it. Use the same
image versions, check .env, then:
./restore.sh ./backups/photoprism-YYYYMMDDTHHMMSSZ.tar
docker compose ps
curl --fail http://127.0.0.1:2342/api/v1/status
The procedure has not passed a practical restore test; test it on a separate server first.
Back up, read the release notes, and change PHOTOPRISM_VERSION only to a
reviewed exact tag, never latest. Update MariaDB separately.
docker compose pull photoprism
docker compose up -d --wait photoprism
docker compose logs --tail=200 photoprism
Do not run old PhotoPrism code over a migrated database. Restore the previous tag and complete pre-update archive, including its dump and storage. Photos added after that backup are absent; copy them aside before replacing data.
docker compose down preserves data. After verifying an external backup,
remove everything irreversibly:
docker compose down
docker volume rm photoprism-database
sudo rm -rf /srv/photoprism
rm -rf ~/services/photoprism
Sources: Docker Compose, configuration, backup, updates, and release 260728.
docker compose ps
docker compose logs --tail=200 photoprism mariadb
docker inspect --format '{{json .State.Health}}' "$(docker compose ps -q photoprism)"
First startup and TensorFlow installation take time. Check free RAM, swap, and disk, originals/storage permissions, and replacement of all three passwords.
docker compose exec mariadb healthcheck.sh --connect --innodb_initialized
docker compose exec photoprism photoprism show config | grep -i database
The .env password takes effect when the volume is initialized. Changing it
does not alter an existing MariaDB user. Restore the old value or explicitly
change the database password. Never remove the volume without a verified dump.
Upstream warns that less than 4 GB swap and hard memory limits may cause
restarts while large files are processed. Check free -h, docker stats, logs,
and storage space. Do not start another complete index before a backup.
Verify that PHOTOPRISM_ORIGINALS_PATH points to media and is readable:
docker compose exec photoprism find /photoprism/originals -maxdepth 2 -type f | head
docker compose exec photoprism photoprism index
On the host, check curl http://127.0.0.1:2342/api/v1/status.
PHOTOPRISM_SITE_URL must exactly match the public HTTPS URL and end in /.
A containerized proxy cannot reach host localhost without a host gateway.
Do not roll back only the image tag over a migrated database. Inspect migration
logs, restore the previous Compose and .env, then restore one consistent
pre-update archive containing the MariaDB dump, storage, and originals.
Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.
A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.