Build Famliy Album with PhotoPrism

5 minute read

After I uploaded my photos to nextcloud, I realized, nextcloud is probably not a good choice for hosting photos, so this time I try to manage these photos with photoprism - a AI-powered photo app.

Add entries to frp client configuration

[photo]
type = http
local_ip = 192.168.0.15
local_port = 2342
subdomain = photo
use_encryption = true
use_compression = true

[photo-secure]
type = https
subdomain = photo
plugin = https2http
plugin_local_addr = 127.0.0.1:2342
plugin_crt_path = /etc/frp/ssl/baylabs.cc.cer
plugin_key_path = /etc/frp/ssl/baylabs.cc.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp

Run PhotoPrism with Docker

The official docker-compose.yml is a good example to start with:

wget https://dl.photoprism.app/docker/docker-compose.yml

It’s pretty much like this:

version: '3.5'

# Example Docker Compose config file for PhotoPrism (Linux / AMD64)
#
# Note:
# - Running PhotoPrism on a server with less than 4 GB of swap space or setting a memory/swap limit can cause unexpected
#   restarts ("crashes"), for example, when the indexer temporarily needs more memory to process large files.
# - If you install PhotoPrism on a public server outside your home network, please always run it behind a secure
#   HTTPS reverse proxy such as Traefik or Caddy. Your files and passwords will otherwise be transmitted
#   in clear text and can be intercepted by anyone, including your provider, hackers, and governments:
#   https://docs.photoprism.app/getting-started/proxies/traefik/
#
# Documentation : https://docs.photoprism.app/getting-started/docker-compose/
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
#
# DOCKER COMPOSE COMMAND REFERENCE
# see https://docs.photoprism.app/getting-started/docker-compose/#command-line-interface
# --------------------------------------------------------------------------
# Start    | docker-compose up -d
# Stop     | docker-compose stop
# Update   | docker-compose pull
# Logs     | docker-compose logs --tail=25 -f
# Terminal | docker-compose exec photoprism bash
# Help     | docker-compose exec photoprism photoprism help
# Config   | docker-compose exec photoprism photoprism config
# Reset    | docker-compose exec photoprism photoprism reset
# Backup   | docker-compose exec photoprism photoprism backup -a -i
# Restore  | docker-compose exec photoprism photoprism restore -a -i
# Index    | docker-compose exec photoprism photoprism index
# Reindex  | docker-compose exec photoprism photoprism index -f
# Import   | docker-compose exec photoprism photoprism import
#
# To search originals for faces without a complete rescan:
# docker-compose exec photoprism photoprism faces index
#
# All commands may have to be prefixed with "sudo" when not running as root.
# This will point the home directory shortcut ~ to /root in volume mounts.

services:
  photoprism:
    ## Use photoprism/photoprism:preview for testing preview builds:
    container_name: photoprism
    image: photoprism/photoprism:latest
    depends_on:
      - mariadb
    ## Don't enable automatic restarts until PhotoPrism has been properly configured and tested!
    ## If the service gets stuck in a restart loop, this points to a memory, filesystem, network, or database issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    # restart: unless-stopped
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "2342:2342" # HTTP port (host:container)
    environment:
      PHOTOPRISM_ADMIN_PASSWORD: ${PHOTOPRISM_ADMIN_PASSWORD}          # !!! PLEASE CHANGE YOUR INITIAL "admin" PASSWORD !!!
      PHOTOPRISM_SITE_URL: ${PHOTOPRISM_SITE_URL}  # public server URL incl http:// or https:// and /path, :port is optional
      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_DEBUG: "false"                      # run in debug mode (shows additional log messages)
      PHOTOPRISM_PUBLIC: "false"                     # no authentication required (disables password protection)
      PHOTOPRISM_READONLY: "false"                   # don't modify originals directory (reduced functionality)
      PHOTOPRISM_EXPERIMENTAL: "false"               # enables experimental features
      PHOTOPRISM_DISABLE_CHOWN: "false"              # disables storage permission updates on startup
      PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
      PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables Settings in Web UI
      PHOTOPRISM_DISABLE_TENSORFLOW: "false"         # disables all features depending on TensorFlow
      PHOTOPRISM_DISABLE_FACES: "false"              # disables facial recognition
      PHOTOPRISM_DISABLE_CLASSIFICATION: "false"     # disables image classification
      PHOTOPRISM_DARKTABLE_PRESETS: "false"          # enables Darktable presets and disables concurrent RAW conversion
      PHOTOPRISM_DETECT_NSFW: "false"                # flag photos as private that MAY be offensive (requires TensorFlow)
      PHOTOPRISM_UPLOAD_NSFW: "true"                 # allows uploads that MAY be offensive
      # 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_DATABASE_NAME}         # MariaDB or MySQL database schema name
      PHOTOPRISM_DATABASE_USER: ${PHOTOPRISM_DATABASE_USER}         # MariaDB or MySQL database user name
      PHOTOPRISM_DATABASE_PASSWORD: ${PHOTOPRISM_DATABASE_PASSWORD}       # MariaDB or MySQL database user password
      PHOTOPRISM_SITE_TITLE: ${PHOTOPRISM_SITE_TITLE}
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: ""
      PHOTOPRISM_SITE_AUTHOR: ""
      ## Run/install on first startup (options: update, gpu, tensorflow, davfs, nano, clean):
      # PHOTOPRISM_INIT: "gpu tensorflow"
      ## Hardware video transcoding config (optional)
      # PHOTOPRISM_FFMPEG_BUFFERS: "64"              # FFmpeg capture buffers (default: 32)
      # PHOTOPRISM_FFMPEG_BITRATE: "32"              # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
      # PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m"    # use Video4Linux for AVC transcoding (default: libx264)
      # PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv"        # use Intel Quick Sync Video for AVC transcoding (default: libx264)
      ## Run as a specific user, group, or with a custom umask (does not work together with "user:")
      # PHOTOPRISM_UID: 1000
      # PHOTOPRISM_GID: 1000
      # PHOTOPRISM_UMASK: 0000
      HOME: "/photoprism"
    ## Start as a non-root user (see https://docs.docker.com/engine/reference/run/#user)
    # user: "1000:1000"
    ## Share hardware devices with FFmpeg and TensorFlow (optional):
    # devices:
    #  - "/dev/dri:/dev/dri"
    #  - "/dev/nvidia0:/dev/nvidia0"
    #  - "/dev/nvidiactl:/dev/nvidiactl"
    #  - "/dev/video11:/dev/video11" # Video4Linux (h264_v4l2m2m)
    working_dir: "/photoprism"
    ## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory
    volumes:
      # "/host/folder:/photoprism/folder"                # example
      - "~/photoprism/Pictures:/photoprism/originals"               # original media files (photos and videos)
      # - "/example/family:/photoprism/originals/family" # *additional* media folders can be mounted like this
      # - "~/Import:/photoprism/import"                  # *optional* base folder from which files can be imported to originals
      - "./storage:/photoprism/storage"                  # *writable* storage folder for cache, database, and sidecar files (never remove)

  ## Database Server (recommended)
  ## see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
  mariadb:
    ## If MariaDB gets stuck in a restart loop, this points to a memory or filesystem issue:
    ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
    restart: unless-stopped
    image: mariadb:10.7
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    command: mysqld --innodb-buffer-pool-size=128M --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
    ## Never store database files on an unreliable device such as a USB flash drive, an SD card, or a shared network folder:
    volumes:
      - "./database:/var/lib/mysql" # important, don't remove
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  ## Watchtower upgrades services automatically (optional)
  ## see https://docs.photoprism.app/getting-started/updates/#watchtower
  #
  # watchtower:
  #   restart: unless-stopped
  #   image: containrrr/watchtower
  #   environment:
  #     WATCHTOWER_CLEANUP: "true"
  #     WATCHTOWER_POLL_INTERVAL: 7200 # checks for updates every two hours
  #   volumes:
  #     - "/var/run/docker.sock:/var/run/docker.sock"
  #     - "~/.docker/config.json:/config.json" # optional, for authentication if you have a Docker Hub account

And fill the required env variable in .env:

PHOTOPRISM_SITE_URL="http://photos.baylabs.cc"
PHOTOPRISM_ADMIN_PASSWORD=admin
PHOTOPRISM_DATABASE_NAME=photoprism
PHOTOPRISM_DATABASE_USER=photoprism
PHOTOPRISM_DATABASE_PASSWORD=85%n87Z@aLAzPt
PHOTOPRISM_SITE_TITLE="Famliy Album"
MYSQL_ROOT_PASSWORD=8m%U!WpuDBsZF^
MYSQL_DATABASE=photoprism
MYSQL_USER=photoprism
MYSQL_PASSWORD=85%n87Z@aLAzPt

Please note that PHOTOPRISM_DATABASE_PASSWORD and MYSQL_PASSWORD should be the same.

Upload Photos to PhotoPrism

There is not offical app for mobile phones currently, since most of the photos are stored in my Ubuntu, so just copy them to $HOME/Pictures and then do a scan with the following command:

docker exec photoprism photoprism index -f

This process is very cpu intensive and may not respond, be patient to wait, after scan finished, head to https://photo.baylabs.cc to see what it looks.