Application setup for Home Information/Media Central Store

Vijay
Written by Vijay on
Application setup for Home Information/Media Central Store

Application/services setup for a DIY low cost home network attached photos/media storage archive.


I have tried different commercially available NAS (Network Attached Storage) solutions in the past. They make it easy to have a backup of photos and documents locally. This time I managed to build such a device myself. Being a DIY, I know what software/hardware components are in it, and gives me full access for any level of customization.

It does a handful of different functions. Primarily this is a photo & document backup solution. As a secondary benefit it’s also a PiHole (a network wide DSN based ad-blocker), Wireguard server (a virtual private network/VPN) gateway, a DDNS(Dynamic Domain Name System) client, and Plex media server for my local media.

In the previous post I explained how to prepare a Raspberry-Pi-4. In this post I am going to explain in detail how I installed and setup each of the application services.

Overview of the process

  1. Prepare Raspberry Pi
  2. Setup nextcloud
  3. Setup photoprism
  4. Setup Pi-Hole
  5. Setup Wireguard
  6. Setup DDNS
  7. Setup Plex

Prepare Raspberry Pi

See the previous post for Raspberry Pi installation and disk setup.

Nextcloud

For automating photo backup from my phone I chose nextcloud. Nextcloud also acts as documents/files explorer and frontend. It’s available as a preinstalled docker image. I used docker-compose with support for mariadb and below is my config file for reference. Visit https://my-raspberry-pi-IP:443 from browser to access nextcloud. On first startup you will have to create a nextcloud user account and configure mariadb credentials on the welcome screen. Use mariadb:3306 as the server address for mysql db. Once configured headover to phone app store and install nextcloud app. Configure it to work with the nextcloud docker service using the credentials you created on first run. You can setup automatic photo backup from phone app. Don’t forget to disable Most Compatible option in advanced settings section. Keeping the Most Compatible option ON will convert HEIC photos to JPG which are larger in size. I didn’t want that.

version: "2.1"
services:
  nextcloud:
    depends_on:
      - mariadb
    image: lscr.io/linuxserver/nextcloud
    container_name: nextcloud
    volumes:
      - "./config:/config"
      - "./data:/data"
    ports:
      - 443:443
    restart: unless-stopped
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Los_Angeles
      - MYSQL_PASSWORD=secret
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=mariadb:3306

  mariadb:
    restart: unless-stopped
    image: arm64v8/mariadb:10.5
    user: "1000:1000"
    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: # Don't remove permanent storage for index database files!
      - "./database:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: secret

Photoprism

For automating photo library processing/indexing/searching I used photoprism. Photoprism provides a nice frontend as progressive web app. It’s available as a preinstalled docker image. I used docker-compose with support for mariadb and below is my config file for reference. Visit https://my-raspberry-pi-IP:2342 from browser to access photoprism. On first startup you will have to create a user account and configure it. Mount the photos folder from nextcloud into photoprism in the docker-compose.yml. This allows us to import the photo files managed by nextcloud to be seen and indexed in photoprism.

# Example Docker Compose config file for PhotoPrism (Raspberry Pi / ARM64)
#
# Documentation : https://docs.photoprism.org/getting-started/raspberry-pi/
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
#
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
# e.g. when running PhotoPrism on a public server outside your home network.
#
# -------------------------------------------------------------------
# DOCKER COMPOSE COMMAND REFERENCE
# -------------------------------------------------------------------
# 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
# -------------------------------------------------------------------
# Note: All commands may have to be prefixed with "sudo" when not running as root.
#       This will change the home directory "~" to "/root" in your configuration.

services:
  photoprism:
    # Use photoprism/photoprism:preview instead 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:
    # https://docs.photoprism.org/getting-started/faq/#why-is-photoprism-getting-stuck-in-a-restart-loop
    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" # [server]:[container]
    environment:
      PHOTOPRISM_ADMIN_PASSWORD: "secret"          # PLEASE CHANGE: Your initial admin password (min 4 characters)
      PHOTOPRISM_ORIGINALS_LIMIT: 5000               # File size limit for originals in MB (increase for high-res video)
      PHOTOPRISM_HTTP_COMPRESSION: "none"            # Improves transfer speed and bandwidth utilization (none or gzip)
      PHOTOPRISM_WORKERS: 2                          # Limits the number of indexing workers to reduce system load
      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: "true"           # Enables Darktable presets and disables concurrent RAW conversion
      # PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m"    # FFmpeg AVC encoder for video transcoding (default: libx264)
      # PHOTOPRISM_FFMPEG_BUFFERS: "64"              # FFmpeg capture buffers (default: 32)
      PHOTOPRISM_DETECT_NSFW: "false"                # Flag photos as private that MAY be offensive
      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 (or MySQL) instead of SQLite for improved performance
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"     # MariaDB database server (hostname:port)
      PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB database schema name
      PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB database user name
      PHOTOPRISM_DATABASE_PASSWORD: "secret"       # MariaDB database user password
      PHOTOPRISM_SITE_URL: "http://localhost:2342/"  # Public PhotoPrism URL
      PHOTOPRISM_SITE_TITLE: "PhotoPrism"
      PHOTOPRISM_SITE_CAPTION: "Browse Photos"
      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
      HOME: "/photoprism"
    # Optional hardware devices for video transcoding and machine learning:
    # devices:
    #  - "/dev/video11:/dev/video11" # Video4Linux (h264_v4l2m2m)
    working_dir: "/photoprism"
    volumes:
      # Your photo and video files ([local path]:[container path]):
      - "~/Pictures:/photoprism/originals"
      # Multiple folders can be indexed by mounting them as sub-folders 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]
      - "../nextcloud/data/vijay/files/Photos:/photoprism/originals/nextcloud-v"
      # Mounting an import folder is optional (see docs):
      # - "~/Import:/photoprism/import"
      # Permanent storage for settings, index & sidecar files (DON'T REMOVE):
      - "./storage:/photoprism/storage"

  mariadb:
    restart: unless-stopped
    image: arm64v8/mariadb:10.5
    user: "1000:1000"
    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: # Don't remove permanent storage for index database files!
      - "./database:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: photoprism
      MYSQL_USER: photoprism
      MYSQL_PASSWORD: secret

# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
#
#  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      

Pi-Hole

Pi-Hole is a network wide advertise blocker.

Wireguard

Wireguard is a VPN server and client solution. This helps if I have to connect to my home network while I am not at home.

DDNS

DDNS client is needed to resolve the public IP address of my home network for the use of wireguard.

Plex

Plex manages all local videos and music files on my storage for streaming purposes.