PhotoPrism
PhotoPrism indexes a photo library, classifies what is in the pictures, and recognises faces and places. Two containers — the Go server with its models, and MariaDB.
Last run on a host 8 Nov 2026
Pinned at 261029 (released 29 Oct 2026) · the newest upstream release
In the upstream images: 1 CRITICAL · 26 HIGH with a published fix — per image
To try it: Docker, and the first start still downloads roughly 1 GB of classification models. See Try it locally.
To deploy it behind the proxy: Traefik running, a domain, and disk space for the library and the models.
Try it locally
Section titled “Try it locally”On your own machine, with no proxy, domain or certificate. From apps/photoprism/:
cp .env.local.example .env.local
# The secrets ship empty; generate the ones this stack needs{ echo "DB_PASSWORD=$(openssl rand -hex 32)" echo "DB_ROOT_PASSWORD=$(openssl rand -hex 32)" echo "ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '\n')"} >> .env.local
docker compose -f docker-compose.local.yml --env-file .env.local up -dThen open http://localhost:2342. Stop it again with the same command and down.
Installation
Section titled “Installation”From apps/photoprism/:
-
Copy the environment file:
Terminal window cp .env.example .envSet
APP_TRAEFIK_HOST,TZ,PUID/PGID,SITE_TITLE, andORIGINALS_PATH— the last one is where your photos live and it may point outside the stack directory. -
Generate the database secrets and mirror the password into
.env. PhotoPrism has no_FILEform for its database password, so the value exists twice:Terminal window mkdir -p .secretsopenssl rand -base64 32 | tr -d '\n' > .secrets/db_pwd.txtopenssl rand -base64 32 | tr -d '\n' > .secrets/db_root_pwd.txtsed -i "s|^DB_PWD_INLINE=.*|DB_PWD_INLINE=$(cat .secrets/db_pwd.txt)|" .env -
Set the initial administrator password, which is read once at first start:
Terminal window ADMIN_PWD_VAL=$(openssl rand -base64 24 | tr -d '\n')sed -i "s|^ADMIN_PASSWORD=.*|ADMIN_PASSWORD=${ADMIN_PWD_VAL}|" .envecho "Initial admin password: ${ADMIN_PWD_VAL}"Keep that value somewhere safe. After the first login, change the password in the interface and remove it from
.env. -
Create the volumes:
Terminal window mkdir -p volumes/database volumes/storage volumes/originals -
Start it. The first run downloads the classification models and takes several minutes:
Terminal window docker compose up -ddocker compose logs photoprism-app --followWait for
server: listening on 0.0.0.0:2342. -
Open
https://<APP_TRAEFIK_HOST>and log in withADMIN_USERand the password from step 3.
Verify
Section titled “Verify”docker compose ps # two services, healthycurl -fsSI https://<APP_TRAEFIK_HOST>/api/v1/status # 200Then put a few photos into the originals path and start an index run from the interface. Pictures appearing with thumbnails and detected content is the check — the server answers long before indexing works.
Going further
Section titled “Going further”Memory during indexing
Section titled “Memory during indexing”The indexer can reach several gigabytes while processing large RAW files or
video. photoprism-app runs with a 2 GB memory limit and no swap
(memswap_limit equals the limit). A ceiling the indexer touches ends as an
out-of-memory kill mid-run, so a library of large RAW files or video needs a
higher limit: raise memory and memswap_limit together in
docker-compose.yml and run docker compose up -d.
Date-based versions
Section titled “Date-based versions”PhotoPrism tags releases by date — 260601 is 1 June 2026. There is no semantic
version to read, so the release notes are the only way to know what a bump
contains.
If MariaDB crashes on an older kernel
Section titled “If MariaDB crashes on an older kernel”Upstream works around an io_uring issue by running MariaDB with seccomp and
AppArmor unconfined. This stack keeps the defaults; the block is present in
docker-compose.yml and commented out, to be enabled only if that crash appears.
What it sends outward
Section titled “What it sends outward”On first run and on renewal, PhotoPrism posts to my.photoprism.app/v1/hello
with a persistent client serial, the version, the operating system, the
architecture and the CPU core count. The serial does not rotate, so the vendor
can follow this installation over time.
There is no supported way to switch it off. hub.Disable() exists but is
reachable only through the test configuration. Blocking it needs an egress rule
on the host or the network.
Backup
Section titled “Backup”| Database | MariaDB, container photoprism-db, database photoprism, user photoprism |
| Password | .secrets/db_pwd.txt |
| The library | ORIGINALS_PATH — the photos, which may sit outside the stack directory |
| Also needed | volumes/storage/sidecar — edits and metadata written back |
| Rebuildable | the rest of volumes/storage — thumbnail cache, regenerated by an index run |
| Quiescing | Not needed for the dump. |
For borgmatic:
mariadb_databases: - name: photoprism container: photoprism-db username: photoprism password: "{credential file /srv/docker/apps/photoprism/.secrets/db_pwd.txt}"Exclude the thumbnail cache subdirectory rather than all of volumes/storage.
Most of that tree is cache, but the sidecar files in it carry edits and metadata
that exist nowhere else.
Restore order: database, then originals and sidecars, then the application.
Updates
Section titled “Updates”-
Read the release notes — the tag is a date, so it is the only description of what changed.
-
Back up the database, the originals and the sidecar directory together.
-
Raise
APP_TAGin.env, then:Terminal window docker compose pull && docker compose up -ddocker compose logs photoprism-app --follow -
Open the library and run an index. A schema change surfaces during indexing rather than at start.
Troubleshooting
Section titled “Troubleshooting”The indexer stops partway through a large file. Out of memory against the
2 GB limit — docker inspect photoprism-app --format '{{.State.OOMKilled}}'
answers true. Raise the limit as under
Memory during indexing.
Login fails with the password from .env. ADMIN_PASSWORD is read only at
first start. If the stack has run before, the password is whatever is stored in
the database.
MariaDB crashes on start. The io_uring case. Uncomment the seccomp and
AppArmor block in docker-compose.yml.
Photos are visible but nothing is classified. The model download did not
finish. Check docker compose logs photoprism-app from the first start.
Repository files
Section titled “Repository files”apps/photoprism/README.md— setup, security model, known issuesapps/photoprism/UPSTREAM.md— source and upgrade checklist
Official sources
Section titled “Official sources”© 2026 SecDockBlueCode Apache-2.0Site content CC BY-NC 4.0