Free and OpenSource Photo Libraries


In my quest to reduce my reliance upon proprietary software applications, I’ve begun to focus some more time in finding a good Google Photos or Apple Photos alternative. As began looking at the alternatives, I discovered that there were way more options that I had originally anticipated. Each alternative had a different feature set and I found it difficult to compare the different options. To solve this dilemma for myself (and hopefully for many others), I’m compiling a list of free and open source photo libraries that can be self-hosted or run locally without any need for cloud services.

Google/Apple Photos Alternatives

My alternative comparison list looks like the following (Be sure to visit the github repository for the most up to date comparison.

** This page was last updated on 2023-06-05

Free and OpenSource Photo Libraries

There are many great free and open-source alternatives to paid photo libraries. This project aims to track and compare the feature set between the many different options with a focus on ‘Gratis’ (free as in free beer) open source photo libraries. ‘Libre’ (free as in free speech) projects are also welcome, but will likely need to be submitted via a pull request since the time in testing each different project is significant.


✅ = Feature exists in at least a limited fashion
🚧 = Feature may exist but may not be practical or officially released
❌ = Feature does not yet exist
#️⃣ = Subjective measure of feature quality (on scale of 0-10)
Tip: Hover over icons for missing/incomplete features for more information (link to repository issue, etc)
Feature Damselfly HomeGallery Immich Librephotos Lychee Nextcloud Photos Nextcloud Memories Photonix Photofield PiGallery2 Photoprism Photoview Piwigo
Github Stars ? ? ? ? ? ? ? ? ? ? ? ? ?
Active Contributors 1 1 4 2 3 3 1 1 1 1 4 1 3
Source Language C# JavaScript / TypeScript Dart / TypeScript Python PHP JavaScript PHP / Vue Python Go / Vue TypeScript Go Typescript / Go PHP
License ? ? ? ? ? ? ? ? ? ? ? ? ?
Demo 6️⃣ 6️⃣ 5️⃣ 4️⃣ 4️⃣ 8️⃣ 8️⃣ 6️⃣ 8️⃣ 9️⃣ 9️⃣ 9️⃣
Freeness ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 ✅🔟 🚧7️⃣ ✅🔟 ✅🔟
Automatic Mobile Upload ✅7️⃣ ✅7️⃣ ✅7️⃣ ✅6️⃣ ✅7️⃣
Web App ✅8️⃣ ✅8️⃣ ✅8️⃣ ✅8️⃣ ✅8️⃣ ✅7️⃣ ✅9️⃣ ✅7️⃣ ✅9️⃣ ✅7️⃣ ✅7️⃣ ✅8️⃣ ✅8️⃣
Android App 8️⃣ 7️⃣ 3️⃣ 3️⃣ 4️⃣ 🚧4️⃣ 🚧3️⃣ 7️⃣
iOS App 8️⃣ 🚧3️⃣ 3️⃣ 3️⃣ 4️⃣ 🚧4️⃣ 6️⃣ 7️⃣
Desktop App ✅9️⃣ ✅8️⃣ 2️⃣ 2️⃣
LivePhotos Support ✅9️⃣ 6️⃣ ✅️3️⃣ ✅8️⃣ ✅7️⃣
Video Support ✅6️⃣ 7️⃣ ✅8️⃣ ✅6️⃣ ✅5️⃣ ✅7️⃣ 3️⃣ ✅8️⃣ ✅7️⃣ ✅7️⃣ ✅4️⃣
Photo Map ✅7️⃣ ✅8️⃣ ✅4️⃣ ✅8️⃣ ✅5️⃣ ✅6️⃣ ✅8️⃣ ✅9️⃣ ✅8️⃣ ✅6️⃣ ✅8️⃣ ✅7️⃣
Photo Discovery ✅7️⃣ ✅6️⃣ ✅6️⃣ ✅7️⃣ ✅6️⃣ ✅1️⃣
Albums ✅8️⃣ ✅9️⃣ ✅8️⃣ ✅4️⃣ ✅8️⃣ ✅5️⃣ ✅6️⃣ ✅8️⃣ ✅6️⃣ ✅8️⃣
Slideshow ✅5️⃣ ✅5️⃣ ✅6️⃣ ✅7️⃣ ✅6️⃣ ✅5️⃣
Timeline ✅5️⃣ ✅3️⃣ ✅8️⃣ ✅9️⃣ ✅4️⃣ ✅9️⃣ ✅5️⃣ ✅6️⃣ ✅5️⃣ ✅5️⃣ ✅9️⃣ ✅3️⃣
Photo Sharing ✅4️⃣ ✅9️⃣ ✅9️⃣ ✅8️⃣ ✅8️⃣ ✅7️⃣ ✅7️⃣ ✅8️⃣ ✅5️⃣
Photo Search ✅8️⃣ ✅7️⃣ ✅7️⃣ ✅8️⃣ ✅5️⃣ ✅4️⃣ ✅4️⃣ ✅8️⃣ ✅9️⃣ ✅7️⃣ ✅8️⃣ ✅5️⃣ ✅7️⃣
Duplicate Handling ✅6️⃣ 8️⃣ 8️⃣ ✅5️⃣ 6️⃣ ✅6️⃣
User Defined Tags ✅7️⃣ ✅7️⃣ ✅5️⃣ ✅️3️⃣ ✅️3️⃣ ✅6️⃣ ✅6️⃣ ✅5️⃣ ✅7️⃣
Docker Installation ✅8️⃣ ✅8️⃣ ✅7️⃣ ✅7️⃣ ✅7️⃣ 6️⃣ 6️⃣ ✅8️⃣ ✅7️⃣ ✅7️⃣ ✅6️⃣ ✅8️⃣ 7️⃣
Object/Face Recognition ✅8️⃣ ✅6️⃣ ✅6️⃣ ✅8️⃣ ✅8️⃣ ✅8️⃣ ✅8️⃣ ✅7️⃣ ✅6️⃣ ✅9️⃣ ✅6️⃣ 5️⃣
Basic Editing ✅6️⃣ ✅6️⃣
EXIF Data ✅9️⃣ ✅7️⃣ ✅7️⃣ ✅8️⃣ ✅7️⃣ 🚧3️⃣ ✅7️⃣ ✅9️⃣ ✅7️⃣ ✅6️⃣
Multiple User Support ✅7️⃣ ✅7️⃣ ✅8️⃣ ✅6️⃣ ✅9️⃣ ✅9️⃣ ✅7️⃣ ✅7️⃣ ✅6️⃣ ✅8️⃣

Note: This list is by no means comprehensive. For links to other photo library projects, see the Awesome Self-Hosted list and the Awesome Privacy list.

An HTML version of this comparison table is here:


Please contribute additions and corrections! When contributing, please add links to the source of the information. (i.e. link to an issue that indicates that a feature does not exist)

~ Don’t give away your photos to the largest data collection entities in the world! Your photos document your life better than any other kinds of data. Pictures are worth more than a thousand words to advertisers!

Uptime Kuma


Uptime Kuma is a ‘fancy’ self-hosted monitoring service that can be used to create your very own status page of any services you would like to monitor. Initial configuration and setting up monitors is very easy.

Setting Up Uptime Kuma

The preferred method for setting up Uptime Kuma is Docker. And to make the setup in docker even easier, I like to use Portainer:

Create a new stack in Portainer:

version: '3.3'

    image: louislam/uptime-kuma
    container_name: uptimekuma
    restart: always
      - data:/app/data
      - 3001:3001


Start the Stack and Log In

Login Page

Add Monitors

Sample HTTP Monitor


You can use a reverse proxy like NGINXProxyManager to fetch an SSL cert and expose the Uptime Kuma service publicly:

Self-Hosing Should Be (and can be) Easy


Any readers of this blog are probably aware that I often self-host open-source services. Self-Hosting can be daunting at first, but with a little groundwork, it can be quite easy, safe, and rewarding. Recently I deployed my own instance of the handy – from start to finish it took me less than 5 minutes. The ease of deploying the service reminded me how far I have come in my journey of self-hosting. Only a couple years ago I would have been completely lost about where to begin, but now I have it boiled down to two primary steps: Deploy docker container, expose docker container using NGINXProxymanager.


There are some prerequisites that should be in place before self hosting. Some of them listed below are not required but make it much more enjoyable and rewarding. I won’t get into the weeds about why these are important, since my goal in the post is to show how easy self-hosting CAN be – not how hard it actually IS!

  • Your own Domain
  • A good internet connection (specifically upload speeds)
  • A router that supports advanced options (like OPNSense)
  • A properly configured NGINX reverse proxy (like NGINXProxyManager)
  • A hypervisor (like proxmox) and/or a docker host in 5 Minutes

The below steps are not a tutorial on how to setup, but rather my workflow now that I have all the prerequisites in place to spin up a new self-hosted service in minutes. My steps were:

  • SSH into my Docker Host and modify my docker_compose.yaml file that contains the blueprint of my docker services. I simply add the following:
    image: fjudith/
    container_name: drawio
    restart: unless-stopped
      - 1005:8080
  • On my Docker host I run the following to bring up my docker container.
sudo docker-compose up -d
  • Next I open up NGINXProxyManager and expose the service to the Internet. NGINXProxyManager handles the task of using a Let’s Encrypt certificate to expose the internal service over HTTPS:
  • That’s it. Now I can navigate to and enjoy running on my own personal server! welcome screen.

What, Why, When, and How Nextcloud

What is Nextcloud?

TLDR: A Nextcloud description is below, but why not just check out the demo!

Nextcloud is a Free and Open Source Software (FOSS) that provides an enterprise grade all-in-one solution for file storage, collaboration, meetings, etc. Over the past few years Nextcloud has come a long way and is now my recommended solution for anyone seriously interested in hosting their own data with privacy and security in mind. Nextcloud is made up of many, many apps that can be installed as needed. Some of the apps include:

A sampling of a few Nextcloud apps
  • Files (This is installed by default and aids in storing/sharing/managing your files)
  • Calendar (This uses WebDav and can be synced to other devices more on this in a later post)
  • Tasks (This also can be synced using WebDav to other devices like MacOS/iOS Reminders)
  • Gallery (This helps with managing your photos in a centralized location)
  • Maps (Directions, pinning locations, mapping where your photos were taken, etc)
  • Contacts (Address book that uses WebDav to sync with other devices)
  • Bookmarks (Bookmark storage that can be synced to your browser using Floccus)
  • Talk (Meeting software like Zoom or Jitsi, no Nextcloud account needed to join calls!)
  • Mail (A very functional Mail client application with encryption, multiple accounts, etc)
  • Other features:
    • 2 Factor Authentication
    • File Sharing policies (timeframe, encryption options, public link expiration, etc)
    • LDAP user/group managment
    • Automated updates & Security audits
    • Forms
    • Polls
    • Project Management
    • Social Plugins
    • Password Manager
    • Many others (See the Nextcloud App Store)

Why Nextcloud?

Why use Nextcloud? Simply put: data privacy. Nextcloud provides a private and secure vault for all your personal information. No need to worry about Google reading your emails and using your photos for machine learning purposes. No need to pay Dropbox or any other cloud storage company a monthly fee for storing your files on a server you have no control over. Nextcloud makes it easier to take responsibility for your own data so you know where it resides. If you’re still not convinced, check out Nextcloud’s reasoning.

When Nextcloud

Given my bullish stance on Nextcloud, I would also like to make clear that Nextcloud isn’t for everyone. It does require some technical experience and a use case that is worth while. Nextcloud works best and is most enjoyable when it is used for more than just a few files. Casual or non-technical Nextcloud users would be better off signing up with a Nextcloud provider rather then self-hosting it since the providers will handle the configuration and hosting of the storage (this however does reduce your visibility in where and how your data is stored). An alternative to a cloud provider is to buy a dedicated, pre-configured piece of Nextcloud hardware with some tech support.

How Nextcloud


Memory Required: 512MB

Nextcloud can be installed in a variety of ways. My preferred method is using the per-configured virtual appliance, but other methods include docker, Ubuntu snap, web-server script, archive extraction. Detailed installation instructions can be found in the Nextcloud Docs, but a simple rundown of the installation methods are listed below:


Virtual Machine (My preferred method)

I prefer this method since it allows me to take easy snapshots/backups of the entire Nextcloud environment. This gives me peace of mind so I can be sure I can rollback to a point in time if anything goes wrong.

  1. Download the Virtual Machine (There are also advanced-configured VMs here)
  2. Setup a VM in your favorite Hypervisor (Proxmox, Hyper-V, VirtualBox, VMWare, etc)
  3. Import the downloaded Virtual Machine file and start the virtual machine (check the console)
  4. Login to the pre-configured Nextcloud instance and enjoy!

Appliance: Docker (Great for those already using Docker)

For those already using docker, this method may be appealing. I avoided this option primarily because it didn’t have a very clean docker-compose setup.

  1. On a docker-enabled machine run `docker run -d -p 8080:80 nextcloud`
  2. Alternatively, if you use docker-compose, start with this template:
version: '2'


    image: mariadb
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
      - db:/var/lib/mysql
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

    image: nextcloud
    restart: always
      - 8080:80
      - db
      - nextcloud:/var/www/html
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db

Appliance: Ubuntu Snap (Easy for Beginners, but not recommended!)

This installation method is very easy but does have some drawbacks. From my experience, updates are slower to be released to the Nextcloud ubuntu snap distribution and often has issues with edge cases (I’ve noticed this with Collabora docs). It is also very difficult to migrate Nextcloud from a snap installation to a different installation method (I learned this the hard way!).

  1. Setup an ubuntu machine with snap enabled.
  2. Run `snap install nextcloud`
  3. Follow the installation steps and enjoy.

Web Installer (Good for C-Panel style web-hosting)

  1. Download the php script from the Nextcloud Site
  2. Upload the php scrip to your web server
  3. Point your browser to the php script
  4. Walk through the installation wizard (default user: ncadmin default password: nextcloud)
  5. Enjoy!

Manual Archive File Installation (Most Difficult)

  1. Download the Archive from the Nextcloud site
  2. Extract the archive file to an accessible location on your web server
  3. Configure Apache webserver
  4. Configure SSL
  5. Walk through installation wizard

Enjoy Nextcloud!

‘Don’t be Evil’ Isn’t enough for me!

Repurposing a Squeezebox

Squeezebox Boom

Squeezebox – A bit ahead of it’s time

First off, I’d like to spend a minute appreciating the craftsmanship and the premium nature of the squeezebox line of products. Almost a decade before the current ‘smart’ speakers that are common today (Echo, HomePod, GoogleHome, etc), the Squeezebox sported much of the same functionality:

  • Premium Quality Sound
  • Remote Control (via a handheld remote & web interface)
  • Streaming radio, podcasts, music, etc
  • Apps for extensible functionality
  • Web Interface for local and remote access (most modern speakers don’t offer local control)
  • Local API for extensibility (I don’t know of any modern speakers that offer this!)
  • A community of users for great support (still exists today!)

An Orphaned Squeezebox

Recently at my workplace we upgraded the office speaker and had an orphaned Squeezebox Boom. We were ready to recycle the 12 year old speaker, but it still seemed to have so much potential. The speaker hardware worked flawlessly (although the online services have been neglected by Logitech). Naturally, since I knew the Squeezebox had a local API, my instinct was to check if Home Assistant had any support for such a device, and sure enough it has a Logitech Squeezebox integration! After browsing the integration documentation I figured it would be worth an effort to give the Squeezebox a new life.

Prerequisite for Integration: Logitech Media Server

The Home Assistant documentation indicated that I would need to have a Logitech Media Server in order to control the Squeezebox – A slight inconvenience, but a quick search on DockerHub revealed some pre-built docker containers that can provide me with a self-hosted alternative to the Internet reliant interface that Logitech could shut down at any time. Setting up the docker container was as simple as adding the following to my docker-compose file and running: docker-compose up -d. Stay tuned for future posts about Docker & docker-compose. They are great tools for quickly setting up various services!

#Logitech Media Server
  container_name: "logitechmediaserver"
  image: lmscommunity/logitechmediaserver:stable
  restart: always
    - 9000:9000/tcp
    - 9090:9090/tcp
    - 3483:3483/tcp
    - 3483:3483/udp
    - logitechmediaserver_config:/config:rw
    - logitechmediaserver_music:/music:ro
    - logitechmediaserver_playlist:/playlist:rw
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro



Exploring Logitech Media Server

After starting the docker container I was able to natigate to the Lotitech Media Server web interface which was a bit outdated:

Logitech Media Server Default Interface

Let’s fix the outdated interface by trying a community developed ‘Material Skin’. Ah.. much better!

A Community Developed Material Theme for Logitech Media Server

There are numerous other extensions that sounded promising (i.e. Airplay/Chromecast support), but those will wait for another day. Let’s get back to integrating this into Home Assistant…

Home Assistant Integration

The Home Assistant integration was a breeze to setup:

  1. Open Home Assistant web interface
  2. Click Configuration Menu Icon (Gear)
  3. Click Integrations
  4. Click Add Integrations
  5. Click on Logitech Squeezebox
    • At this point Home Assistant may auto-discover your Squeezebox, if not continue…
  6. Enter the IP address of the Squeezebox
  7. Enter the Username/Password for the Squeezebox Web interface (if configured)
  8. Enjoy!
    • Home Assistant control of the Squeezebox
    • Additional features like playing Home Assistant media & sending Text to Speech to the speaker.
    • History of played media
    • Trigger media based on other smart devices/sensors.

Squeezebox reborn!

< Home Assistant Media Card

Home Assistant Card Detail >

Post #1

Welcome to my first blog post! It won’t be impressive, so don’t get your hopes up. I don’t currently have a structured plan for this blog yet, but I need to start somewhere, so basically I will explain how you are able to read this post – note the terms in italics – these may be topics of future blog posts:

  1. You entered or clicked on a link with the URL of
  2. Your device made a DNS query to find out that is located at a specific IP Address
    • Hopefully you are not using Google DNS or your ISP’s DNS – more on this in a future post
  3. The DNS request returns my Public IP address because I’ve used a Dynamic DNS service to update my Domain Registrar with the public IP address your machine needs to access this website.
  4. Your machine requested this page by sending a GET request, but before you were able to read anything on this page your request was Routed through your home router (or cell tower) to your ISP’s network, and on through the Internet before finally reaching my router,
  5. After reaching my router, my router forwarded your GET request to a Self-Hosted NGINX Reverse Proxy which then forwarded your traffic to my Self-Hosted WebServer
  6. My WebServer is running WordPress which then responded to your GET request with this webpage.

The few steps above are a simplified version of what actually happened, but a good opportunity to throw out some terms (Italicized) that may be topics of future blog posts.

Thought of the day: “Why am I still using Gmail when I care about my own privacy?