From 4e2021052652898728bc9c1db076f4f7a3ea0da1 Mon Sep 17 00:00:00 2001 From: Rafael Blumberg Date: Sun, 5 Dec 2021 02:55:05 +0000 Subject: [PATCH] Add PhotoPrism Stack to Template (#236) --- images/photoprism.png | Bin 0 -> 31893 bytes stack/photoprism.yml | 136 +++++++++++++++++++++++++++++++ template/portainer-v2-arm64.json | 88 ++++++++++++++++++++ tools/install_photoprism.sh | 19 +++++ 4 files changed, 243 insertions(+) create mode 100644 images/photoprism.png create mode 100644 stack/photoprism.yml create mode 100755 tools/install_photoprism.sh diff --git a/images/photoprism.png b/images/photoprism.png new file mode 100644 index 0000000000000000000000000000000000000000..77a3c4fef453d28f9a726e132e06b6f7875bd5d0 GIT binary patch literal 31893 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 L6u=d)jRO83FpI5M literal 0 HcmV?d00001 diff --git a/stack/photoprism.yml b/stack/photoprism.yml new file mode 100644 index 0000000..662475e --- /dev/null +++ b/stack/photoprism.yml @@ -0,0 +1,136 @@ +version: '3.5' + +# 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"), especially 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, Caddy, or NGINX. Your files and passwords will otherwise be transmitted +# in clear text and can be intercepted by anyone, including your provider, hackers, and governments. +# +# Documentation : https://docs.photoprism.org/getting-started/docker-compose/ +# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/ +# +# DOCKER COMPOSE COMMAND REFERENCE +# see https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface +# -------------------------------------------------------------------------- +# 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 placeholder ~ to /root in volume mounts. + +services: + ## App Server (required) + photoprism: + ## Use photoprism/photoprism:preview for testing preview builds: + image: photoprism/photoprism:latest + depends_on: + - mariadb + ## Only enable automatic restarts once your installation is properly + ## configured as it otherwise may get stuck in a restart loop, + ## see https://docs.photoprism.org/getting-started/faq/#why-is-photoprism-getting-stuck-in-a-restart-loop + container_name: photoprism + restart: unless-stopped + security_opt: + - seccomp:unconfined + - apparmor:unconfined + ## Run as a specific, non-root user (see https://docs.docker.com/engine/reference/run/#user): + user: "1000:1000" + ports: + - "2342:2342" # HTTP port (host:container) + environment: + PHOTOPRISM_ADMIN_PASSWORD: "${PHOTOPRISM_ADMIN_PASSWORD}" # PLEASE CHANGE: Your initial admin password (min 4 characters) + 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: "${PHOTOPRISM_PUBLIC:-false}" # No authentication required (disables password protection) + PHOTOPRISM_READONLY: "${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: "${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" # Allow 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" # MariaDB or MySQL database schema name + PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name + PHOTOPRISM_DATABASE_PASSWORD: "${MYSQL_PASSWORD}" # MariaDB or MySQL database user password + PHOTOPRISM_SITE_TITLE: "PhotoPrism" + PHOTOPRISM_SITE_CAPTION: "Browse Your Life" + PHOTOPRISM_SITE_DESCRIPTION: "" + PHOTOPRISM_SITE_AUTHOR: "" + ## Set a non-root user, group, or custom umask if your Docker environment doesn't support this natively: + # PHOTOPRISM_UID: 1000 + # PHOTOPRISM_GID: 1000 + # PHOTOPRISM_UMASK: 0000 + ## Enable TensorFlow AVX2 support for modern Intel CPUs (requires starting the container as root): + # PHOTOPRISM_INIT: "tensorflow-amd64-avx2" + ## 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) + # PHOTOPRISM_INIT: "intel-graphics tensorflow-amd64-avx2" # Enable TensorFlow AVX2 & Intel Graphics support + HOME: "/photoprism" + ## Hardware devices for video transcoding and machine learning (optional): + # devices: + # - "/dev/video11:/dev/video11" # Video4Linux (h264_v4l2m2m) + # - "/dev/dri/renderD128:/dev/dri/renderD128" # Intel GPU + # - "/dev/dri/card0:/dev/dri/card0" + working_dir: "/photoprism" + volumes: + ## The *originals* folder contains your original photo and video files (- "[host folder]:/photoprism/originals"): + - "${HOST_MEDIA_PATH}:/photoprism/originals" + ## Multiple folders can be made accessible by mounting them as subfolders of /photoprism/originals: + # - "/mnt/Family:/photoprism/originals/Family" # [folder 1]:/photoprism/originals/[folder 1] + # - "/mnt/Friends:/photoprism/originals/Friends" # [folder 2]:/photoprism/originals/[folder 2] + ## You may mount an *import* folder from which files can be transferred to *originals* (optional): + # - "~/Import:/photoprism/import" + ## Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove): + - "/portainer/Files/AppData/Config/PhotoPrism/storage:/photoprism/storage" + + ## Database Server (recommended) + ## see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql + mariadb: + restart: unless-stopped + image: mariadb:10.6 + security_opt: + - seccomp:unconfined + - apparmor:unconfined + command: mysqld --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: + - "/portainer/Files/AppData/Config/PhotoPrism/database:/var/lib/mysql" # never remove + environment: + MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}" + MYSQL_DATABASE: photoprism + MYSQL_USER: photoprism + MYSQL_PASSWORD: "${MYSQL_PASSWORD}" + + ## Watchtower upgrades services automatically (optional) + ## see https://docs.photoprism.org/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 diff --git a/template/portainer-v2-arm64.json b/template/portainer-v2-arm64.json index 80ad4fb..9becfe7 100644 --- a/template/portainer-v2-arm64.json +++ b/template/portainer-v2-arm64.json @@ -3597,6 +3597,94 @@ } ] }, + { + "categories": [ + "Photos" + ], + "description": "PhotoPrism® is an AI-powered app for browsing, organizing & sharing your photo collection. 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.", + "env": [ + { + "default": "change me to a secure password", + "label": "PHOTOPRISM_ADMIN_PASSWORD", + "name": "PHOTOPRISM_ADMIN_PASSWORD" + }, + { + "default": "http://localhost:2342/", + "label": "PHOTOPRISM_SITE_URL", + "name": "PHOTOPRISM_SITE_URL" + }, + { + "label": "PHOTOPRISM_PUBLIC", + "name": "PHOTOPRISM_PUBLIC", + "select": [ + { + "text": "Enable Password Protection", + "value": "false", + "default": true + }, + { + "text": "No authentication required", + "value": "true" + } + ] + }, + { + "label": "PHOTOPRISM_READONLY", + "name": "PHOTOPRISM_READONLY", + "select": [ + { + "text": "Photo folder in Read/Write mode", + "value": "false", + "default": true + }, + { + "text": "Don't modify originals directory (reduced functionality)", + "value": "true" + } + ] + }, + { + "label": "PHOTOPRISM_DISABLE_FACES", + "name": "PHOTOPRISM_DISABLE_FACES", + "select": [ + { + "text": "Enable facial recognition", + "value": "false", + "default": true + }, + { + "text": "Disable facial recognition", + "value": "true" + } + ] + }, + { + "default": "change me to a secure password", + "label": "MYSQL_PASSWORD", + "name": "MYSQL_PASSWORD" + }, + { + "default": "change me to a secure password", + "label": "MYSQL_ROOT_PASSWORD", + "name": "MYSQL_ROOT_PASSWORD" + }, + { + "default": "/portainer/PhotoPrism", + "label": "HOST_MEDIA_PATH", + "name": "HOST_MEDIA_PATH" + } + ], + "logo": "https://raw.githubusercontent.com/novaspirit/pi-hosted/master/images/photoprism.png", + "name": "PhotoPrism", + "note": "Your device should have at least \u003cb\u003e4 GB\u003c/b\u003e of memory. Running PhotoPrism on a server with less than 4 GB of swap space or setting a memory/swap limit can cause unexpected restarts, especially when the indexer temporarily needs more memory to process large files.\u003cbr\u003eIt's important to boot your Rapsberry Pi 3/4 with the parameter \u003cb\u003earm_64bit=1\u003c/b\u003e in \u003cb\u003econfig.txt\u003c/b\u003e to use ARM64 image.\u003cbr\u003eIf you see Docker errors related to \u003cb\u003e\"cgroups\"\u003c/b\u003e, it may help to add the following to \u003cb\u003e/boot/firmware/cmdline.txt\u003c/b\u003e:\u003cbr\u003e\u003cbr\u003e\u003cb\u003ecgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1\u003c/b\u003e\u003cbr\u003e\u003cbr\u003eUser pi needs to have access to \u003cb\u003eHOST_MEDIA_PATH\u003c/b\u003e, you can force it with:\u003cbr\u003e\u003cbr\u003e\u003cb\u003esudo chown -R pi:pi /path/to/media\u003c/b\u003e\u003cbr\u003e\u003cbr\u003eRun \u003cb\u003einstall_photoprism.sh\u003c/b\u003e before deploying this container.", + "platform": "linux", + "title": "PhotoPrism", + "type": 3, + "repository": { + "stackfile": "stack/photoprism.yml", + "url": "https://github.com/novaspirit/pi-hosted" + } + }, { "categories": [ "Photos" diff --git a/tools/install_photoprism.sh b/tools/install_photoprism.sh new file mode 100755 index 0000000..74b29f3 --- /dev/null +++ b/tools/install_photoprism.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +function error { + echo -e "\\e[91m$1\\e[39m" + exit 1 +} + +echo "Creating directories..." +sudo mkdir -p /portainer/Files/AppData/Config/PhotoPrism/{storage,database} || error "Failed to create storage and database directories!" + +echo "Setting permissions..." +sudo chown -R 1000:1000 /portainer/Files/AppData/Config/PhotoPrism/{storage,database} || error "Failed to set permissions for PhotoPrism data!" + +echo +echo -e "If you already have a folder for images, make sure the user \\e[32mpi\\e[m has access to it." +echo -e "If required, you can change permissions with:" +echo -e " \\e[32msudo chown -R pi:pi /path/to/folder\\e[m" +echo -e "If not, create it now and give user \\e[32mpi\\e[m permission" +echo -e "When done you can continue to install PhotoPrism Stack"