Skip to content
appsgit

Deploy guide

How to self-host PhotoPrism with Docker Compose

Deploy PhotoPrism with Docker Compose and MariaDB: originals folder, admin password, indexing, HTTPS reverse proxy, backups and upgrades in 20 minutes.

  • Updated
  • Beginner
  • About 20 minutes

You will need

  • 2 vCPU / 4 GB RAM (plus swap for large libraries)
  • Docker + Docker Compose v2
  • Your existing photo library on local or NAS storage
  • A domain name (optional, for HTTPS)

What is PhotoPrism?

PhotoPrism is an AI-powered photo management app for browsing, organising and sharing your photo and video collection. It is open source under the AGPL-3.0 license and indexes existing folders without moving them, then adds automatic tagging, face recognition, places on a world map and powerful search. It works in any browser and can be installed as a progressive web app.

Requirements

  • A Linux server with 2 CPU cores and 4 GB of RAM, plus swap. More cores make indexing faster.
  • Docker Engine and Docker Compose v2.
  • Your photo library in a folder on the server or a mounted NAS share.
  • Local SSD storage for the database and the cache folder.

Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker installed. If you need Docker, follow the official install guide. Create a project folder and check that you have swap:

mkdir -p ~/photoprism/{storage,database} && cd ~/photoprism
free -h

If Swap shows 0, add a 4 GB swap file before indexing a large library.

Step 2: Create the Docker Compose file

This is a trimmed version of the official Compose file with MariaDB, which the developers recommend over SQLite. Save as docker-compose.yml:

services:
  photoprism:
    image: photoprism/photoprism:latest
    restart: unless-stopped
    stop_grace_period: 15s
    depends_on:
      - mariadb
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "2342:2342"
    environment:
      PHOTOPRISM_ADMIN_USER: "admin"
      PHOTOPRISM_ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
      PHOTOPRISM_AUTH_MODE: "password"
      PHOTOPRISM_SITE_URL: "https://photos.example.com/"
      PHOTOPRISM_DISABLE_TLS: "true"
      PHOTOPRISM_ORIGINALS_LIMIT: 5000
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "photoprism"
      PHOTOPRISM_DATABASE_PASSWORD: "${DB_PASSWORD}"
      PHOTOPRISM_SIDECAR_YAML: "true"
      PHOTOPRISM_BACKUP_DATABASE: "true"
      PHOTOPRISM_BACKUP_SCHEDULE: "daily"
    working_dir: "/photoprism"
    volumes:
      - "/srv/photos:/photoprism/originals"
      - "./storage:/photoprism/storage"

  mariadb:
    image: mariadb:12.3
    restart: unless-stopped
    stop_grace_period: 15s
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    command: --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
    volumes:
      - "./database:/var/lib/mysql"
    environment:
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_INITDB_SKIP_TZINFO: "1"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "${DB_PASSWORD}"
      MARIADB_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"

Create .env:

ADMIN_PASSWORD=CHANGE_ME
DB_PASSWORD=CHANGE_ME
DB_ROOT_PASSWORD=CHANGE_ME

Generate each value with openssl rand -hex 32. The admin password must be 8 to 72 characters, which a 64-character hex string meets. Change /srv/photos to the folder holding your library. PHOTOPRISM_SITE_URL must match the public URL, including the trailing slash. The official Compose file lists every other option, including hardware transcoding and an optional Ollama service for AI captions.

Step 3: Start and open the app

docker compose up -d
docker compose logs -f photoprism

Open http://YOUR_SERVER_IP:2342 and sign in as admin with the password from .env. The admin password variable only applies on first start; change it later in Settings, Account. Then go to Library, Index and click "Start" to scan your originals. The first index of a large library can take hours because PhotoPrism creates thumbnails and runs image classification and face detection.

Step 4: Put it behind HTTPS

With Caddy:

photos.example.com {
    reverse_proxy 127.0.0.1:2342
}

PhotoPrism uses WebSockets for live updates, which Caddy passes through. With Nginx Proxy Manager, enable "Websockets Support" and raise the upload size limit. After HTTPS works, change the port mapping to "127.0.0.1:2342:2342".

Backups and upgrades

Back up your originals folder (your photos) and ./storage, which holds settings, sidecar YAML files with your edits and labels, and the automatic daily database dumps in storage/backup. The thumbnail cache in storage/cache can be regenerated and may be excluded to save space. You can also create a database dump manually with docker compose exec photoprism photoprism backup -i -f.

Upgrade with:

docker compose pull && docker compose up -d

MARIADB_AUTO_UPGRADE updates the database system tables automatically when the MariaDB image changes.

Troubleshooting

  • Indexing stops or the container restarts: the server is running out of memory. Add swap or RAM, or lower PHOTOPRISM_WORKERS.
  • Login fails after changing the password in .env: the variable is only used on first start. Reset it with docker compose exec photoprism photoprism passwd admin.
  • Broken links or wrong URLs in shares: PHOTOPRISM_SITE_URL does not match the address you use.
  • Database connection errors on first start: MariaDB was still initialising. Run docker compose restart photoprism.

Next steps

Name people in the People section, create albums and share links, set up WebDAV or the PhotoSync app for phone uploads, and schedule regular indexing with PHOTOPRISM_INDEX_SCHEDULE.

Spotted something out of date? Tell us and we will update the guide.

FAQ

PhotoPrism questions

Still curious? Email info@appsgit.com.

What port does PhotoPrism use?

PhotoPrism listens on port 2342. The official Compose file serves it with a self-signed certificate by default; this guide disables built-in TLS and lets a reverse proxy handle HTTPS.

Is PhotoPrism free?

Yes. PhotoPrism Community Edition is free and open source under the AGPL-3.0 license. Paid memberships add extras such as higher-detail maps and support the developers.

Does PhotoPrism modify my original photos?

No. PhotoPrism reads your originals folder and writes thumbnails, sidecar files and the index to a separate storage folder. You can also set PHOTOPRISM_READONLY to true to guarantee it never writes to originals.

PhotoPrism vs Immich?

PhotoPrism excels at indexing and browsing an existing library on a NAS through the browser. Immich is built around automatic phone backup with native mobile apps, closer to a Google Photos replacement.

How much RAM does PhotoPrism need?

The developers recommend at least 4 GB of RAM and enough swap, because indexing large RAW files and videos can briefly use a lot of memory. Too little memory makes indexing crash or restart.