PhotoStructure for Node
These are instructions for advanced users who want to run PhotoStructure on a server without Docker.
If you have questions or get stuck, hop into the forum or discord – we’ll help get you set up!
Prerequisites ๐
PhotoStructure for Node requires:
-
agreement to all terms in the end-user license
-
a 64-bit Intel or AMD CPU. Note that Apple Silicon and Linux ARM support is experimental.
-
Ubuntu LTS 22.04, Fedora (38 or later), Windows 10, Windows 11, or macOS 12 (Monterey, Ventura, or Sonoma). (Big Sur support was recently dropped by Homebrew).
-
Node.JS (version 18.16 or later).
Contents ๐
We’ve got instructions for the following operating systems:
Installation for Ubuntu ๐
Step 1: Consider hardening your server ๐
Instructions for “server hardening” are on the forum.
Step 2: Install prerequisite packages ๐
Open a terminal and run:
sudo apt install build-essential python3-dev \
git perl libjpeg-turbo-progs libheif-examples ffmpeg
Notes:
build-essential
andpython3-dev
lets us compile several native libraries for your system. used to accelerate image and database operations.git
is used to fetch and update the code that makes up PhotoStructure.perl
runs ExifTool, used for reading and writing metadata to images, videos, and sidecars.libjpeg-turbo-progs
lets us validate and manipulate JPEG images.libheif-examples
adds support for HEIF images.ffmpeg
adds support for videos.
Step 3: Create a role user to run PhotoStructure ๐
Consider creating a role user to run PhotoStructure, as you should do for any service.
sudo adduser --disabled-password photostructure
This role user needs read access to your photos and videos, and write access to
- the directory that holds your PhotoStructure library
~photostructure/.config/PhotoStructure
(the system settings directory)~photostructure/.cache/PhotoStructure
(the scratch directory)
Note:
- The system settings directory default can be changed by setting the
PS_CONFIG_DIR
environment variable. - The scratch directory can be changed by setting the
PS_CACHE_DIR
environment variable. - Read more about advanced settings.
Step 4: Install Node.js ๐
There are two ways to install the current version of Node.js. There are pros and cons to each:
Option 1, via your package manager ๐
This option installs Node.js via NodeSource packages.
The main advantage of this approach is that your installation of Node.js will get security updates automatically whenever you update your system (with apt update && apt upgrade
).
The two disadvantages of this approach (over nvm
) is that it’s a bit more complicated to get set up initially, and that it doesn’t support installing multiple versions of Node.js.
- Download and import the Nodesource GPG key
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
- Set up the deb repository:
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \
| sudo tee /etc/apt/sources.list.d/nodesource.list
- Run update and install:
sudo apt-get update
sudo apt-get install nodejs -y
export NPM_PREFIX=~/.npm
mkdir -p "$NPM_PREFIX"
npm config set prefix "$NPM_PREFIX"
if [ -f ~/.bashrc ]; then
echo "export PATH=\"\$PATH:$NPM_PREFIX/bin\"" >> ~/.bashrc
else
echo "Please add $NPM_PREFIX/bin to your shell login script"
fi
This last step configures npm
to write globally-installed packages into
~/.npm
, instead of the default, which is to write to
/usr/lib/node_modules
, which is a system directory that no user should have
write-access to.
More information about the prefix
setting is on the npmjs.com website.
Option 2, via nvm
: ๐
If you have any other software on your server that needs a different version of Node.js you may want to use nvm
instead.
Node Version Manager, or nvm
, manages one or more versions of Node.js, per user.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
and then restart your shell, and run
nvm install 20 --latest-npm
Security updates to Node.js will not be applied automatically. When a new version is available, you need to run nvm install 20 --latest-npm
.
Notes ๐
- PhotoStructure requires Node.js version 18 or later.
- Consider curling (any!) setup script to a file and reviewing the file before executing as root.
- You will have performance problems if you use the snap version of Node.js.
Step 5: Download and start PhotoStructure ๐
This assumes youโre going to install PhotoStructure into your new role userโs
home directory, ~photostructure
.
sudo --login --user photostructure bash
cd ~photostructure
git clone https://github.com/photostructure/photostructure-for-servers.git
cd photostructure-for-servers
./start.sh
Jump to the Start PhotoStructure section for more information.
Step 6: Set up a systemd service (optional) ๐
You can use systemd to make PhotoStructure start up on boot and gracefully end when your system shuts down.
Configure the service ๐
Start by running sudo systemctl edit photostructure.service --full --force
and paste
the following content into your editor.
Note that the following assumes you’ve set up a photostructure
role user and installed into the directory from the prior section.
Update User
, Group
, and ExecStart
according to your own setup.
[Unit]
Description=PhotoStructure for Servers
Documentation=https://photostructure.com/servers/
# PhotoStructure binds to either 0.0.0.0 or 127.0.0.1, so we don't need to
# wait for network-online.target. See https://systemd.io/NETWORK_ONLINE/
Wants=network.target
After=network.target
[Service]
User=photostructure
Group=photostructure
ExecStart=/home/photostructure/photostructure-for-servers/start.sh --expose
Type=simple
Restart=on-failure
TimeoutSec=2min
# Remove this line if you have an old version of systemd that doesn't support PrivateTmp:
PrivateTmp=true
[Install]
WantedBy=default.target
Control the service ๐
Control the PhotoStructure service just as you would any other systemd
service.
-
To start the PhotoStructure service:
sudo systemctl start photostructure
-
To stop the PhotoStructure service:
sudo systemctl stop photostructure
-
To view the current status of the service:
sudo systemctl status photostructure
Enable the service ๐
Once you’re satisfied that the service is running correctly, enable the service to start on boot:
sudo systemctl enable photostructure.service
Uninstalling the service ๐
-
To disable start on reboot:
sudo systemctl disable photostructure
. -
To uninstall,
sudo rm /etc/systemd/system/photostructure.service
Installation for Fedora ๐
Step 1: Consider hardening your server ๐
Instructions for “server hardening” are on the forum.
Step 2: Install prerequisite packages ๐
Open a terminal and run:
sudo dnf install @development-tools \
git perl libjpeg-turbo-utils libheif-tools ffmpeg
Notes:
@development-tools
lets us compile several native libraries for your system.git
is used to fetch and update the code that makes up PhotoStructure.perl
runs ExifTool, used for reading and writing metadata to images, videos, and sidecars.libjpeg-turbo-utils
lets us validate and manipulate JPEG images.libheif-tools
adds support for HEIF images.ffmpeg
adds support for videos.
Step 3: Install Node.js ๐
You can either install with NodeSource or with nvm.
Pick NodeSource if you want Node.js to get updated automatically by yum
/dnf
. If you need to run multiple versions of Node.js concurrently, nvm
is a
better route, but note that upgrades, even for security issues, are manual.
NodeSource ๐
sudo yum install https://rpm.nodesource.com/pub_20.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm -y
sudo yum install nodejs -y --setopt=nodesource-nodejs.module_hotfixes=1
And then set up npm prefix
with these steps.
nvm ๐
Step 4: Finish ๐
The remaining installation steps are the same as on Ubuntu. Follow along here.
Installation for macOS ๐
PhotoStructure needs the following:
- Xcode’s command line tools,
- Node.js v20,
- ffmpeg,
- jpeg-turbo, and
- Python
You’re free to install these by yourself, but homebrew makes this much easier.
Step 1: Install Xcode command line tools ๐
Open Terminal.app and run this:
xcode-select --install
sudo xcode-select --reset
Note that xcode-select
will take several minutes to install.
Step 2: Install homebrew ๐
Open a terminal and run:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
At the end of this command, there are instructions to add homebrew to your PATH–make sure you do that! It’ll look something like this:
(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
Step 3: Install PhotoStructure’s dependencies ๐
In a terminal, run the following:
brew doctor && brew upgrade && brew install ffmpeg jpeg-turbo python node@20
What’s all this?
brew doctor
verifies your system setup looks OK.brew upgrade
ensures we’re getting the latest version of everything.brew install ffmpeg
installs FFmpeg, used for video encoding.brew install jpeg-turbo
installs JPEG tooling used by PhotoStructure to validate images.brew install node@20
installs Node.js. PhotoStructure is a Node.js application.
**Note that installing Node.js will emit some instructions that you must follow. They’ll look something like this:
echo 'export PATH="/opt/homebrew/opt/node@20/bin:$PATH"' >> ~/.zshrc
echo 'export LDFLAGS="-L/opt/homebrew/opt/node@20/lib"' >> ~/.zshrc
echo 'export CPPFLAGS="-I/opt/homebrew/opt/node@20/include"' >> ~/.zshrc
source ~/.zshrc
Step 4: Download PhotoStructure ๐
In a terminal, run
cd ~
git clone https://github.com/photostructure/photostructure-for-servers.git
cd photostructure-for-servers
git checkout alpha # < This is temporary step, and will not be necessary when v2023.11 is stable
./start.sh
Jump to the Start PhotoStructure section for more information.
Installation for Windows 10/11 ๐
Step 1: Install Git ๐
Install Git for Windows.
-
You want the “64-bit Git for Windows” installer option.
-
The git installer asks a lot of questions: PhotoStructure will work fine if you accept all the defaults. Hop into Discord if you have questions, though!
Step 2: Install Node.js ๐
Install Node.js version 18 or 20.
-
Keep “Add to PATH” selected.
-
On the last screen, select “Automatically install the necessary tools.”:

The installation will take a while, as the Node.js installer will install
Chocolatey, and then ask choco
to install the tools
necessary to build native modules. PhotoStructure uses several of these modules,
so this step cannot be skipped.
Step 3: Install JPEG and video support ๐
After installing node
and the build tools finish installing, open a new Administrator PowerShell, and run:
choco install ffmpeg jpegtran
Wait for the installations to finish, and then close the PowerShell window
by typing exit
and hitting return.
Step 4: Install HEIF support ๐
If you have a recent iPhone or Samsung smartphone, you probably have HEIF-encoded photos. Follow these HEIF installation instructions. Note that this is optional.
Step 5: Download PhotoStructure ๐
In a new Git Bash
terminal (don’t use cmd
or PowerShell!), run these
commands:
npm install --global yarn npm
cd ~ # (or whatever directory you want to install PhotoStructure into)
git clone https://github.com/photostructure/photostructure-for-servers.git
cd photostructure-for-servers
git checkout alpha # < This is temporary step, and will not be necessary when v2023.11 is stable
./start.sh
Note:
-
npm install --global yarn npm
installs yarn and makes sure npm is the latest available version. -
start.sh
downloads and installs some additional software (like exiftool-vendored).This can take a while, but it only happens after PhotoStructure or Node.js is upgraded. Subsequent restarts should be quick.
Step 6: Automatic launch at startup ๐
If you want PhotoStructure to run at startup, follow these instructions.
Starting PhotoStructure ๐
cd ~photostructure/photostructure-for-servers # or wherever you cloned the repo
./start.sh
The process should print a localhost URL for you to open with a browser. Current versions of Chrome, Firefox, and Safari on both desktop and mobile are supported.
Notes:
-
The
./start.sh
script verifies thatnode
,git
, and other required tools are installed. It then runsgit pull
, asksyarn
to install dependencies, and, finally, launches PhotoStructure. -
You can use
./start.sh --help
to see more detailed usage information. -
The first time you run
start.sh
, it will download and compile dependencies, which will take a moment, and then launch PhotoStructure. Subsequent starts will be much faster, unless there is a new release or your version of node is upgraded. Recompilation happens automatically. -
PhotoStructure currently binds to localhost only by default, so if you want to access it elsewhere, you need to either set the
exposeNetworkWithoutAuth
library setting to true, or set the environment variablePS_EXPOSE_NETWORK_WITHOUT_AUTH
to 1. Note that as of version 0.8, there is no authentication functionality within PhotoStructure. This feature will be added in a subsequent release. -
If you use the
--pidfile $PIDFILE
option, the process will daemonize and return you to your shell prompt.
Shutting down PhotoStructure ๐
It’s easiest to shut down PhotoStructure via the navigation menu (the “hamburger” icon in the upper right corner of the UI).
If youโre running start.sh
in the foreground in a terminal, just hit ctrl-c. The photostructure main
process will gracefully shut down when sent a SIGINT
signal.
If youโve daemonized it with a --pidfile
, run something like ./photostructure --stop --pidfile /var/run/photostructure.pid
Why is it taking so long to shut down? ๐
PhotoStructure may take upwards of a minute to shut down gracefully, depending on the size of your library and the speed of the disk your library is hosted on, as closing the library database requires copying your library database back to your library when it’s hosted on a remote filesystem.
Upgrading PhotoStructure ๐
If you’re using systemd
, just run sudo systemctl restart photostructure
to pick up the new release.
Otherwise, shut down and restart PhotoStructure: ./start.sh
checks for new versions every time it starts.
Switching between alpha, beta, and stable release channels ๐
The “release channel” you’re using is based on the git branch
you’ve checked out.
If, for any reason, you want to switch to the “stable” release, open a terminal and run
sudo su - photostructure
cd ~/photostructure-for-servers
git fetch
git stash -u
git checkout main
Read this forum post to learn more about different release channels (alpha, beta, and stable).
Advanced settings in ./start.sh
๐
The start.sh
script supports several environment variable settings to let it behave as you want:
- Setting
NOGIT=0
will prevent automatic upgrades - Setting
NODE
,PYTHON
, and/orPIP
allow you to specify different binaries (likepython3
) or different paths for these tools - Setting
PS_CONFIG_DIR
allows you to override PhotoStructure’s default configuration directory
Raspberry Pi installation instructions have been moved here.