Self Hosted Photo Albums with pigallery2
(Updated: )
After setting up my nextcloud instance (vanwerkhoven.org), I set out to organize my photo albums online. I tried piwigo before (vanwerkhoven.org), but pigallery2 (github.com) is easier to use and is more slick.
Update 20240103: Added instructions on how to upload from iOS
Requirements ¶
I was looking to have a similar experience as commercial/cloud albums, meanning:
- Can be self-hosted ~easily –> check
- Has an app to upload images for at least iOS –> check, using NextCloud
- Has a nice album viewing interface –> check, including lazy loading and infinite scrolling out of the box
- Must support photos and videos –> check, including compression with ffmpeg
- Supports private albums accessible via unique token-URLs –> check
Alternatives ¶
- Nextcloud (nextcloud.com):
- pros: has an app, already installed, supports shared folders
- con: album layout not my preference
- Piwigo (piwigo.org):
- pro: has an app, nice album layout, supports sharing via unique links
- con: not available via apt, requires plugins for infinite scroll & sharing etc.
- Zenphoto (zenphoto.org):
- pro: has an app
- con: album layout not my preference
- Ownphotos (github.com):
- con: has no app, cannot share albumes
- Photoview (github.io):
- pro: has albums, can share
- con: resource heavy, no app (can upload via NextCloud)
New alternatives not investigated:
- Files (files.gallery) - very nice but full version requires $39 license
- Expose (github.com) - bash script to generate static albums
Setting up pigallery2 ¶
- Read documentation (github.com)
- Get Docker image
- Tweak
docker-compose.yml
settings, prefer to use container without nginx so we can run our reverse proxy ourselves::
version: '3' services: pigallery2: image: bpatrik/pigallery2:latest-debian-buster container_name: pigallery2 environment: - NODE_ENV=production volumes: - "/var/lib/pigallery/config:/app/data/config" # CHANGE ME - "/var/lib/pigallery/db-data:/app/data/db" # CHANGE ME - "/media/pigalleryphotos:/app/data/images:ro" # CHANGE ME - "/var/lib/pigallery/tmp:/app/data/tmp" # CHANGE ME ports: - 3010:80 restart: always volumes: db-data:
- Tweak
- Run pigallery2 container, tweak settings
- Add new user, delete default admin user (for security/ease of use)
- Set page title, fix images path (github.com)
- Reduce ffmpeg quality: 2mbit/crf28 (good enough)
- Add reverse proxy settings in nginx
Configure nextcloud ¶
The actual media files are hosted on Nextcloud, in a folder shared with all users that need write access. This way I can use the nextcloud app to upload new pictures & videos. To use this, I need to enable two things:
- Ensure pigallery2 can read the files uploaded to nextcloud
- Tweak nextcloud such that it doesn’t overwrite files by default
Share nextcloud folder ¶
However, since Nextcloud runs as a snap, the pigallery2
docker image cannot access the files easily. To solve this, there are three
options, I used the mount -o bind
version first (option 3), but then changed
to the direct reading (option 1) because it creates less clutter in my filesystem.
- Option a: use snap data folder. Risk: permissions might be reset on update
- Find photo folder:
/var/snap/nextcloud/common/nextcloud/data/<user>/files/<folder>
- Make http-user accessible (
www-data
in my case)
sudo chown root:www-data /var/snap/nextcloud/common/nextcloud sudo chown root:www-data /var/snap/nextcloud/common/nextcloud/data sudo chmod g-rw /var/snap/nextcloud/common/nextcloud/data sudo chmod o-rx /var/snap/nextcloud/common/nextcloud/data/${USER} sudo chown root:www-data /var/snap/nextcloud/common/nextcloud/data/${USER} sudo chmod g-rw /var/snap/nextcloud/common/nextcloud/data/${USER} sudo chmod o-rx /var/snap/nextcloud/common/nextcloud/data/${USER}/* sudo chown root:www-data /var/snap/nextcloud/common/nextcloud/data/${USER}/files sudo chmod g-rw /var/snap/nextcloud/common/nextcloud/data/${USER}/files sudo chmod o-rx /var/snap/nextcloud/common/nextcloud/data/${USER}/files/* sudo chown root:www-data /var/snap/nextcloud/common/nextcloud/data/${USER}/files/${FOLDER}
- Find photo folder:
- Option b: use removable-media folder (
/media
) to mount. Risk: might expose too many files- See details here (techrepublic.com) and here (masonbee.nz)
- Option c: use
mount -o bind
to make snap folder accessible outside snap without changing access rights:sudo mount -o bind /var/snap/nextcloud/common/nextcloud/data/${USER}/files/${FOLDER}/ /media/${FOLDER}
Prevent nextcloud overwriting files ¶
Update 20240103: Overwriting check has been fixed in the Nextcloud client (a while ago at the time of writing), so this is not required anymore
On the iOS client, if I upload a file photo.jpg
, and somebody else uploads a different photo with the same
filename, the first file will be overwritten (github.com). This is undesirable (github.com) and cannot be configured out of the box (github.com). To solve, I’m using the Workflow addon to do this manually.
- As admin, click on your user icon > Apps > Files category > install ‘Workflow external scripts’ (github.com)
- As admin, click on your user icon > Settings > Administration - Flow > Add new flow
- Make new flow on file creation
- Run script that tests if this happens in the right directory, then rename with date appended.
- ???
- Profit
While figuring out how to make this workaround, I found a workaround: regularly script on the media file directory. I do this on a macOS client, using macports gfind
.
- For each file without ‘orig’ in it 1. Get basename without extension 2. Make target filename: add suffix ‘orig’, using mktemp to ensure uniqueness 3. Rename file
gfind * -type f -not -iname "*orig*" | while read -r fname; do
tgtfile=$(mktemp -u "${fname%.*}-orig-XXX").${fname##*.}
echo mv -n "${fname}" "${tgtfile}"
mv -n "${fname}" "${tgtfile}"
done
Configure iOS client ¶
There’s two options to write files to Nextcloud
- Via WebDAV (using the built-in iOS Files app)
- Via Nextcloud app
Sometimes when sharing images/videos, iOS converts this to ‘compatible’ formats, thereby destroying the metadat (esp the creation time)
Findings:
- If you see a ‘preparing for upload’ before sharing in the app itself, iOS already converted the video
- If Nextcloud client seems to take long to upload file then it might be converting in the background
- Depends on filesize (?)
- ‘All Photos Data’ seems to work, even though it states ‘Airdrop and iCloud links only’ – 6494: OK – 5841: OK – 4358: OK – 4459: OK
- ‘Format: Current’ does not (always) work?
- 4358 not working? Converting in background?
Format: automatic | Format: automatic w/loc | Format: current w/loc | ||||
---|---|---|---|---|---|---|
Image | Video | |||||
Nextcloud | Original? | |||||
WebDAV |