Photo Gallery is a self-hosted performant application to organize your photos. Built with speed in mind with React and Go, you can browse through your photos quick and easy.
There are a lot of photo gallery projects out there. However they often have their own unique way of storing data so you don’t really have control how it is organized, not just the photos themselves, but also like albums, favorites and other preferences alongside. All of this must be kept transparent and accessible.
Another key feature of project is its ease of use, an app that was intuitive and quick to navigate between albums and thousands of photos. And projects that have a good array of features they could be improved upon in this regard.
It was important as well supporting a wide range of data formats, including iPhone Live Photos (HEIC images and H.265 video). With so many different types of devices and formats, it can be a challenge to keep all of your photos organized in one place.
Finally, an app that is lightweight and could run on small devices like a Raspberry Pi.
To sum up, the reason for this project is to be open sourced, you owning your own data and supporting a wide range of data formats all with an easy navigation and a lightweight design.
Built around the file system: photos are loaded from albums. Data is preserved as-is in the filesystem. Changes you make later are saved as transparently as possible, like as choosing your favorites. No requirement to be tied to a database. If you decide for another solution you should own all your data.
Performant: no need for initial and regular scans. Thumbnails are used to see a large amount of photos at a time and are automatically generated on-the-fly.
Made for photography: for everyone, amateur or professional, that enjoys taking photos and revisiting precious memories captured through them.
Ease of use: navigation through albums as easy as possible
First, few concepts to keep in mind about how things are organized:
- Albums are folders in the filesystem and the images inside are the photos of the album
- Collection is a set of albums, in other words, is the location where your collection is stored
- Pseudo Album is special type of album, is file stored in the filesystem which contains links for the photos. This way you can organize your favorites without duplicating them
- [X] Multiple collections
- [X] Easy navigation between albums
- [X] Light, Dark and System-defined themes
- [X] iPhone Live Photos
- [X] Access through WebDAV
- [X] Automatic transcoding on-the-fly for required formats
- [X] for images
- [ ] for videos
- [X] Image files supported:
- [X] JPEG, GIF, PNG, BMP, TIFF, VP8, VP8L, WEBP, HEIF/HEIC
- [ ] RAW (DNG, Apple ProRaw)
- [X] Video files supported:
- [X] Containers: MP4, MOV, AVI
- [X] Codecs: H264, H265
- [X] Thumbnails generation (on-the-fly or in background)
- [X] Pseudo albums:
- [X] Create
- [X] Save favorite photos
- [X] Show storage info
- [X] Metadata extraction from photos (EXIF)
- [X] Show photo location in a map
- [ ] Organize photos:
- [ ] Upload new photos
- [ ] Move photos
- [ ] Delete photos
- [X] Save favorites
- [ ] Easy selection
- [ ] Authentication
- [ ] Photos timeline with virtual scroll
- [ ] View all places from photos in a map
- [ ] Search for duplicates
- [ ] Tool for renaming files
- [ ] Image resizing according with screen
Using docker, run:
docker run -p 3080:3080 --name photo-gallery rigon/photo-gallery:demo
That’s it, enjoy! Just open in your browser http://localhost:3080.
This image however includes a demo gallery, for your own use please use
Build and Run
First, clone the project:
git clone https://github.com/rigon/photo-gallery.git cd photo-gallery
Then, build the web interface and the server:
npm install npm run build npm run build-server
To start the server:
npm run server
Once started, open http://localhost:3080 to view it in your browser.
Optionally you can open http://localhost:3080/webdav in the file explorer as well.
Usage of ./server/photo-gallery: -b, --[no-]cache-thumbnails Generate missing thumbnails while scanning (default true) -c, --collection strings Specify a new collection. Example name=Photos,path=/photos,thumbs=/tmp List of possible options: index Position in the collection list name Name of the collection path Path to load the albums from thumbs Path to store the thumbnails db Path to cache DB, if a filename is provided it will be located in thumbnails directory hide=false Hide the collection from the list (does not affect webdav) rename=true Rename files instead of overwriting them readonly=false --disable-scan Disable scans on start, by default will cache photo info of new albums --disable-webdav Disable WebDAV --full-scan Perform a full scan on start (validates if cached data is up to date) -h, --host string Specify a host (default "localhost") -p, --port int Specify a port (default 3080) -r, --recreate-cache Recreate cache DB, required after DB version upgrade --workers-info int Number of concurrent workers to extract photos info (default 2) --workers-thumb int Number of concurrent workers to generate thumbnails, by default number of CPUs
This project is distributed via docker (Photo Gallery Docker Hub page).
The following example illustrates a case where you have two folders mounted with volumes, one with the collection of photos that is read-only and a recent folder with your still unorganized photos that is writable.
docker run -d -p 3080:3080 --restart=always --name photo-gallery \ -v photo-gallery_data:/thumbs \ -v /media/data/photos/:/photos/:ro \ -v /media/data/recent/:/recent/:rw \ rigon/photo-gallery \ -c "name=Photos,path=/photos,thumbs=/thumbs" \ -c "name=Recent,path=/recent,thumbs=/thumbs"
If you prefer Docker Compose, here is the same example:
version: "3" volumes: photo-gallery_data: services: photo-gallery: image: rigon/photo-gallery volumes: - photo-gallery_data:/thumbs - /media/data/photos/:/photos/:ro - /media/data/recent/:/recent/:rw ports: - 3080:3080 command: - "-cname=Photos,path=/photos,thumbs=/thumbs" - "-cname=Recent,path=/recent,thumbs=/thumbs"
photo-gallery_data can be safely deleted, however cached data must be regenerated.
WebDAV endpoint is like http://localhost:3080/webdav and makes it very easy to access to the photo galleries in the file explorer (just past the URL in the address bar) or to upload photos directly from your phone.
For uploading from your phone, the app PhotoSync makes that task very convinent. However for WebDAV functions you have to purchase it and we do not have any partnership with them.
When creating a new WebDAV configuration in PhotoSync, make sure you fill the field
Remote access is also possible by configuring Port forwarding over SSH using tools like Terminus.
See How to configure Port forwarding in Terminus.
For iOS is more difficult setting it up, you can find more info
Build docker multi-arch
docker buildx build --push -t rigon/photo-gallery --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x .
In the project directory, you can run:
npm run dev
Runs the app in the development mode.\
Open http://localhost:3000 to view it in your browser.
The page will reload when you make changes.
You may also see any lint errors in the console.
npm run serverand
npm run server-dev
Builds and runs the server.\
Open http://localhost:3080 to view it in your browser.
The web version served is the production build obtained with
npm run build
server-devis the same, but monitors for changes and reloads automatically
Launches the test runner in the interactive watch mode.\
See the section about running tests for more information.
npm run build
Builds the app for production to the
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about deployment for more information.
Contributions to this project are very welcome, by reporting issues or just by sharing your support. That means the world to me!
Please help me maintaining this project, only with your support I can take the time to make it even better. Look here for more info https://www.rigon.tk/#contribute