Login

Backing up and Curating a Photo Collection from Multiple Devices Using PhotoPrism

by Eric Bette

Backing up and Curating a Photo Collection from Multiple Devices Using PhotoPrism

Share this post

Backing up and Curating a Photo Collection from Multiple Devices Using PhotoPrism

Backing up and Curating a Photo Collection from Multiple Devices Using PhotoPrism

When de-Googling, one of the biggest challenges in terms of services to replace is management of your digital photo library.

Not only is it critical to back up a photo library in the event that something happens to your device, having a photo repository hosted in the cloud allows you to keep and browse photos from multiple devices in one centralized place. In addition to this, 1st-party apps, such as Google Photos, offers a litany of helpful features, such as face-scanning, timelines, and mapping.

In this post, I'll show how to set up a cloud-based photo collection from multiple devices, including an Android smartphone, using PhotoPrism and Nextcloud.

PhotoPrism to the rescue

PhotoPrism is feature-rich photos app for self-hosters which allows you to connect WebDAV clients, such as Nextcloud, for automated uploads.

In PhotoPrism's own words:

PhotoPrism® is an AI-Powered Photos App for the Decentralized Web.
It makes use of the latest technologies to tag and find pictures automatically without getting in your way. You can run it at home, on a private server, or in the cloud.

It has a bunch of cool features, such as

PhotoPrism: Browse Your Life in Pictures
AI-Powered Photos App for the Decentralized Web

Sold? Great! (it didn't take long for me, either).

Without further ado, let's get started.

Backing up photos from your devices to Nextcloud

The first step in this process will be to get photos from your device onto the Nextcloud server that will be connected to PhotoPrism. If you're only reading this to figure out how to back up photos from your devices to Nextcloud, this will be the only section you'll need.

Prerequisites

There's one thing that you'll need to get started:

A running Nextcloud server

This guide will assume that you've already got a running Nextcloud server on which to store your photos.

If not, there are a lot of ways to get this set up, but it's out of scope for this post. I'd recommend with starting with the official documentation here and, for making it available on the public internet, my previous post about setting up a reverse proxy in Docker using Cloudflare here.

All other setup will be handled through the guide.

Setting up file sync from your device to Nextcloud

There's a few different ways to do this: an automatic way, for automatically uploading all files from certain directories on your device to Nextcloud (and ultimately PhotoPrism), or a manual way. We've covered both in the previous post on uploading files from a mobile device directly to a target destination directory on Nextcloud.

Syncing Files from an Android Device to a Nextcloud Server
OK, so you’ve got a Nextcloud server set up, ready to back up and store all of your files. Now what? There’s a lot of reasons you’d want to sync files from your Android device to your Nextcloud server: backing up photos/screenshots, storing notes or other files that others

Note: if there are other directories that you'd like to upload as well (such as screenshots, etc), you can do that here. Personally, I also take photos on my wife's Sony Alpha camera, so I upload those through Sony's software to my Android device, and sync that directory from my Android device to Nextcloud using the same target directory as the photos taken on my device. That way, all photos from my devices end up stored and backed up in the same collection.

Syncing files from Nextcloud to PhotoPrism library

This is where the fun really starts! Now that the photo files are on the Nextcloud server, we need to point PhotoPrism to the photos directory on the server using Nextcloud's WebDAV endpoint.

Set up PhotoPrism

First things first: let's get PhotoPrism set up and running on the server.

As with most services on my server, I opt to do this in a containerized environment using Docker (and this is what's recommended in the official documentation).

Here is my entry for PhotoPrism in my docker-compose.yml:

services:
  # Photoprism
  photoprism:
    # Container
    container_name: photoprism
    image: photoprism/photoprism:latest
    depends_on:
      - mariadb

    # Security
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined

    # Environment
    environment:
      - PHOTOPRISM_ORIGINALS_PATH=/photoprism/originals
      - PHOTOPRISM_STORAGE_PATH=/photoprism/storage
      - PHOTOPRISM_ADMIN_USER=${PHOTOPRISM_USER}     # admin login username
      - PHOTOPRISM_ADMIN_PASSWORD=${PHOTOPRISM_PASS} # initial admin password (8-72 characters)
      - PHOTOPRISM_AUTH_MODE=password                # authentication mode (public, password)
      - PHOTOPRISM_SITE_URL=https://photoprism.${BASE_URL}
      - PHOTOPRISM_DISABLE_TLS=true                  # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
      # - PHOTOPRISM_DEFAULT_TLS=true                  # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
      - PHOTOPRISM_ORIGINALS_LIMIT=5000              # file size limit for originals in MB (increase for high-res video)
      - PHOTOPRISM_HTTP_COMPRESSION=gzip             # improves transfer speed and bandwidth utilization (none or gzip)
      - PHOTOPRISM_LOG_LEVEL=info                    # log level=trace, debug, info, warning, error, fatal, or panic
      - PHOTOPRISM_READONLY=false                    # do not modify originals directory (reduced functionality)
      - PHOTOPRISM_EXPERIMENTAL=false                # enables experimental features
      - PHOTOPRISM_DISABLE_CHOWN=false               # disables updating storage permissions via chmod and chown on startup
      - PHOTOPRISM_DISABLE_WEBDAV=false              # disables built-in WebDAV server
      - PHOTOPRISM_DISABLE_SETTINGS=false            # disables settings UI and API
      - PHOTOPRISM_DISABLE_TENSORFLOW=false          # disables all features depending on TensorFlow
      - PHOTOPRISM_DISABLE_FACES=false               # disables face detection and recognition (requires TensorFlow)
      - PHOTOPRISM_DISABLE_CLASSIFICATION=false      # disables image classification (requires TensorFlow)
      - PHOTOPRISM_DISABLE_VECTORS=false             # disables vector graphics support
      - PHOTOPRISM_DISABLE_RAW=false                 # disables indexing and conversion of RAW images
      - PHOTOPRISM_RAW_PRESETS=false                 # enables applying user presets when converting RAW images (reduces performance)
      - PHOTOPRISM_JPEG_QUALITY=85                   # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)
      - PHOTOPRISM_DETECT_NSFW=false                 # automatically flags photos as private that MAY be offensive (requires TensorFlow)
      - PHOTOPRISM_UPLOAD_NSFW=true                  # allows uploads that MAY be offensive (no effect without TensorFlow)
      # - PHOTOPRISM_DATABASE_DRIVER=sqlite          # SQLite is an embedded database that doesn't require a server
      - PHOTOPRISM_DATABASE_DRIVER=mysql             # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
      - PHOTOPRISM_DATABASE_SERVER=mariadb:3306      # MariaDB or MySQL database server (hostname:port)
      - PHOTOPRISM_DATABASE_NAME=photoprism          # MariaDB or MySQL database schema name
      - PHOTOPRISM_DATABASE_USER=photoprism          # MariaDB or MySQL database user name
      - PHOTOPRISM_DATABASE_PASSWORD=insecure        # MariaDB or MySQL database user password
      - PHOTOPRISM_SITE_CAPTION=AI-Powered Photos App
      - PHOTOPRISM_SITE_DESCRIPTION=""               # meta site description
      - PHOTOPRISM_SITE_AUTHOR=""                    # meta site author
      - PHOTOPRISM_UID=1000
      - PHOTOPRISM_GID=1000
      - PHOTOPRISM_UMASK=002

    # Networking
    ports:
      - 2342:2342
    
    # Share hardware devices with FFmpeg and TensorFlow (optional):
    devices:
      - /dev/dri:/dev/dri                         # Intel QSV
    #  - "/dev/nvidia0:/dev/nvidia0"                 # Nvidia CUDA
    #  - "/dev/nvidiactl:/dev/nvidiactl"
    #  - "/dev/nvidia-modeset:/dev/nvidia-modeset"
    #  - "/dev/nvidia-nvswitchctl:/dev/nvidia-nvswitchctl"
    #  - "/dev/nvidia-uvm:/dev/nvidia-uvm"
    #  - "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools"
    #  - "/dev/video11:/dev/video11"                 # Video4Linux Video Encode Device (h264_v4l2m2m)
    
    # Mounts
    working_dir: "/photoprism" # do not change or remove
    volumes:
      - ${MEDIA_DIR}/content/Photos:/photoprism/originals     # Original media files (DO NOT REMOVE)
      - /etc/docker/photoprism/storage:/photoprism/storage    # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE)

    # Config
    restart: unless-stopped
    stop_grace_period: 10s
    

  # Maria Database Server (recommended by Photoprism)
  # see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
  mariadb:
    container_name: photoprism-mariadb
    image: mariadb:10.11
    command: mariadbd --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
    
    # Security
    security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239
      - seccomp:unconfined
      - apparmor:unconfined

    # Environment
    environment:
      - MARIADB_AUTO_UPGRADE=1
      - MARIADB_INITDB_SKIP_TZINFO=1
      - MARIADB_DATABASE=photoprism
      - MARIADB_USER=photoprism
      - MARIADB_PASSWORD=insecure
      - MARIADB_ROOT_PASSWORD=insecure

    # Mounts
    volumes:
      - /etc/docker/photoprism/database:/var/lib/mysql

    # Config
    restart: unless-stopped
    stop_grace_period: 5s

A few notes on my implementation:

From there you should be able to launch PhotoPrism for the first time by simply running docker compose up -d.

Now you should be able to access your newly deployed instance of PhotoPrism. After you've logged in, it will look like this:

The app's default settings should work for more users, so we're going to move on to getting your photo stores synced with the app. If you're interested, there's a lot of fine-tuning and various levers that can be tweaked, so feel free to check out the official docs for more info.

Syncing Nextcloud with PhotoPrism

This is the final step in the process, where we'll utilize Nextcloud's WebDAV interface with PhotoPrism to automatically curate photos from the Nextcloud store into the PhotoPrism app.

  1. Navigate Settings > Services > Connect +
  1. Navigate to your file store in Nextcloud, click Files settings, and copy the WebDAV URL (unless you changed the default, this will be: https://your-nextcloud-site.tld/remote.php/dav/files/your-nextcloud-user). Copy this.
  1. Go back to PhotoPrism, and enter in the following information in the Add Account dialog that appeared after you clicked Connect:
    • Service URL: enter the URL that you copied from Nextcloud in the previous step
    • Username: your Nextcloud username
    • Password: your Nextcloud password

You should now see your account listed in the Services section.

There's one more step before we're actually synced. Click the symbol under Sync to get started.

There will be a configuration dialog that pops. Here, the most important setting is to set Folder to the directory in Nextcloud where the photo files are stored. Toggle the toggle and enter this directory into the Folder section.

This is the default, but also check to make sure that you're set to Download remote files (not Upload local files).

I also chose to un-check Preserve filenames. Since I am uploading files from multiple devices, I'm choosing to let PhotoPrism rename them so that everything in my curated collection is named consistently.

I set Interval to 1 hour, because why not?

Click Save, and you're done! Simply repeat for any other photo directories on the Nextcloud server that you'd like to sync, wait for the first scan and indexing to complete, and your collection is... collected!

Conclusion

There you have it! You now have a suitable cloud-based, feature-rich, FOSS photo collection that acts as both a browsing/collection service as well as a remote data store to get the photos off of your devices into the cloud.

In this post, I showed explained how to set up PhotoPrism using Docker on a self-hosted server, and how to sync files from a WebDAV client (such as Nextcloud) so that files uploaded to the server are automatically added and processed into your library.

From here, I'd recommend checking out the various features that PhotoPrism has to offer (it's probably a good idea to start putting names to the faces that PhotoPrism is finding in all of your photos in the People section in the sidebar). The PhotoPrism PWA is also easy to set up on mobile for a great mobile browsing experience.

What are your thoughts on PhotoPrism? Let me know below.