Proxmox: Installing Photoprism in LXC

Rahul Rao
6 min readJul 26, 2023

--

Photoprism UI. Credit: Photoprism (https://docs.photoprism.app/user-guide/navigate/)

Photoprism is a cool, AI powered photo management service that you can host to index, view, and share your photos. It offers plenty of features that you can read about on their website. Today, we will be installing this in an LXC container on Proxmox in home environment.

July 2024 Update: For those who want a turnkey solution, there is a script available that will handle all the installation for you. You may find the script here. Simply run the following command in the Proxmox host shell (it will create the container for you).

bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/photoprism.sh)"

Requirements:

  • Proxmox fully installed and configured and access to GUI
  • Access to router control panel to set static IP address and basic knowledge of static IPs, DHCP ranges.
  • Sufficient storage for photos and thumbnails (I have read online that larger collections can push 200gb in total size. In this tutorial I will be using a network share from my NAS but you can use any folder on local disk too if you like
  • Basic knowledge of the terminal (opening, saving files etc.)
  • Basic Proxmox container knowledge (downloading LXC templates, setting up containers etc)

Creating the container:

Create a container with the following resources:

  • Privileged container with whatever hostname (container name) you choose.
  • Your favorite flavor of Linux. I used Debian 11 here.
  • ~16Gb root storage. (Definitely NOT sufficient for storing photos at all. I strongly recommend using external storage. I will be using storage from my NAS.)
  • All cores on your system (between 4–8 should be good)
  • ≥ 8Gb RAM, ≥ 4Gb Swap
  • Select DHCP IPv4 address, we will set this in the router later.
  • Leave everything else as default and DO NOT start the container.
  • Navigate to options in the side bar of the container and enable:
nesting=1
SMB/CIFS=1 #Optional only if you are using external shares like I am
  • Now start the container.

Set the IP address:

Setting a static IP address makes it easier for you to access your service.

This step will vary between router to router. You need to log into your control panel, typically accessible via 192.168.xxx.1 and add a static IP address for your container. Make sure your static IP assignment does not overlap with the DHCP assignment range. I typically recommend 192.168.xxx.1 — 192.168.xxx.50 be reserved for static IPs only.

Note: If your container does not pop up on your router device list, go back to the container and run apt update then refresh the router screen.

There should be plenty of YouTube videos covering how to do this for most popular routers. Once you have done this, reboot the container. There is no need to reboot Proxmox.

Setup storage:

As I mentioned before, the 16Gb of boot disk space is not enough for storing thumbnails or photos in large quantities. If you have plenty of space on your proxmox host disk, and this space has been appropriately configured for lvm storage, then you could add 200–300gb storage for boot disk and continue on.

I don’t like storing any files on my container boot disk, keeping them as small as possible. If you fill up your Proxmox host disk… recovering it is possible but definitely not a situation you want to end up in.

In this instance I have a NAS which exposes a SMB shared folder called appdataat 192.168.xxx.yy

Install required packages:

apt install cifs-utils

Create the mount folder:

mkdir /media/appdata

Create the SMB credentials file:

nano /root/.smb

Add your credentials to the file as below:

username=YOUR_USERNAME
password=YOUR_PASSWORD

Configure fstab:

nano /etc/fstab

Add the following line:
Change 192.168.xxx.yy/appdata to suit your setup.

//192.168.xxx.yy/appdata /media/appdata cifs credentials=/root/.smb,uid=0,gid=0,dir_mode=0777,file_mode=0777,users,rw,iocharset=utf8,noperm 0 0

Now run mount -a to mount the share.

Install Photoprism:

Now that we have a container, and storage set up. We can begin to install Photoprism itself.

Update existing packages:

apt update && apt upgrade

Install required packages:

apt install -y gcc g++ git gnupg make zip unzip ffmpeg exiftool darktable libpng-dev libjpeg-dev libtiff-dev imagemagick libheif-examples

Install Node.js:

wget https://deb.nodesource.com/setup_18.x -O node_setup.sh
chmod +x node_setup.sh
./node_setup.sh
apt install -y nodejs
rm node_setup.sh

Install GoLang:
Version 1.20.6 is the latest as of writing this guide. Visit the website to find the most up to date version and change the URLs accordingly.

wget https://golang.org/dl/go1.20.6.linux-amd64.tar.gz
rm -rf /usr/local/go
tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin/go
rm go1.20.6.linux-amd64.tar.gz

Install Tensorflow:
This version is for AVX2 compatible CPUs (pretty much every modern CPU). Go to Photoprism’s website to find versions for CPUs compatible with just AVX or those that don’t support AVX at all.

wget https://dl.photoprism.org/tensorflow/linux/libtensorflow-linux-avx2-1.15.2.tar.gz
sudo tar -C /usr/local -xzf libtensorflow-linux-avx2–1.15.2.tar.gz
sudo ldconfig
rm libtensorflow-linux-avx2–1.15.2.tar.gz

Download and Install Photoprism:
Building Photoprism may use a lot of memory. If you have configured your container as I did here, you should not see any errors. If you see out of memory (OOM) errors, consult this, and run each make step individually.

mkdir -p /opt/photoprism/bin
git clone https://github.com/photoprism/photoprism.git
cd photoprism
git checkout release
make all
./scripts/build.sh prod /opt/photoprism/bin/photoprism
cp -a assets/ /opt/photoprism/assets/

Configuration:

Create Photoprism’s working directory and add the configuration file.
For full configuration options, see here.

mkdir /var/lib/photoprism
nano /var/lib/photoprism/.env

Add the following to the configuration file:
Using the default SQLite database is not recommended for anything besides small collections. Consider using MariaDB for that. I have a separate guide on how to install MariaDB here.

Optional: If using external storage, change Photoprism storage paths to your mounted folder which in my case would be /media/appdata.

# Initial password for the admin user
PHOTOPRISM_AUTH_MODE=”password”
PHOTOPRISM_ADMIN_PASSWORD=”photoprism”

# PhotoPrism storage directories
PHOTOPRISM_STORAGE_PATH="/var/lib/photoprism"
PHOTOPRISM_ORIGINALS_PATH="/var/lib/photoprism/photos/Originals"
PHOTOPRISM_IMPORT_PATH="/var/lib/photoprism/photos/Import"

# Uncomment below if using MariaDB/MySQL instead of SQLite (the default)
# PHOTOPRISM_DATABASE_DRIVER="mysql"
# PHOTOPRISM_DATABASE_SERVER="MYSQL_IP_HERE:PORT"
# PHOTOPRISM_DATABASE_NAME="DB_NAME"
# PHOTOPRISM_DATABASE_USER="USER_NAME"
# PHOTOPRISM_DATABASE_PASSWORD="PASSWORD"

Set up Photoprism’s service:
This will enable Photoprism to start on boot.

Create service definition file:

nano /etc/systemd/system/photoprism.service

Add the following to the service file:

[Unit]
Description=PhotoPrism service
After=network.target
StartLimitIntervalSec=500
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5s
WorkingDirectory=/opt/photoprism
EnvironmentFile=/var/lib/photoprism/.env
ExecStart=/opt/photoprism/bin/photoprism up
ExecStop=/opt/photoprism/bin/photoprism down

[Install]
WantedBy=multi-user.target

Now reload the daemon and start the service!

systemctl daemon-reload
systemctl start photoprism
systemctl enable photoprism

Check the status of the service:

systemctl status photoprism

If all went well you should see this (active in green):

Successful service start

You should now be able to access your server from the IP address we set earlier and port 2342.

http://YOUR-IP:2342

Credit:

The installation of Photoprism is based on the guide below and was invaluable to me. You should consider reading it too, in case you need to troubleshoot.

Disclaimer:

This is not a guide for setup in production or business environments, and is most certainly not ready to be exposed to the public internet.

I am not an IT professional. I am not tech support. I am a college student with a server. You are ultimately responsible for any commands you run on your system.

If you have any questions, leave a comment. Enjoy!

--

--

Rahul Rao

The cup is always entirely full. Half water, half air.