- Introduced a new GitHub Actions workflow in `core-image.yml` to automate the build and publish process for the core Docker image. - The workflow triggers on pushes to the main branch and supports manual dispatch. - Configured steps for checking out the repository, setting up Docker Buildx, logging into the GitHub Container Registry, extracting Docker metadata, and building and pushing the Docker image. Additionally, updated documentation to reflect changes in the deployment process, including a new section for multi-tenant SaaS deployment. Signed-off-by: Innei <tukon479@gmail.com>
Afilmory
Afilmory (/əˈfɪlməri/, "uh-FIL-muh-ree") is a term created for personal photography websites, blending Auto Focus (AF), aperture (light control), film (vintage medium), and memory (captured moments).
A modern photo gallery website built with React + TypeScript, supporting automatic photo synchronization from multiple storage sources (S3, GitHub), featuring high-performance WebGL rendering, masonry layout, EXIF information display, thumbnail generation, and more.
Live Photo Galleries:
- https://afilmory.innei.in
- https://gallery.mxte.cc
- https://photography.pseudoyu.com
- https://afilmory.magren.cc
🌟 Features
Core Functionality
- 🖼️ High-Performance WebGL Image Renderer - Custom WebGL component with smooth zoom and pan operations
- 📱 Responsive Masonry Layout - Powered by Masonic, adapts to different screen sizes
- 🎨 Modern UI Design - Built with Tailwind CSS and Radix UI component library
- ⚡ Incremental Sync - Smart change detection, processes only new or modified photos
- 🌐 i18n - Multi-language support
- 🔗 OpenGraph - OpenGraph metadata for social media sharing
Image Processing
- 🔄 HEIC/HEIF Format Support - Automatic conversion of Apple device HEIC format
- 📷 TIFF Format Support - Automatic conversion of TIFF format
- 🖼️ Smart Thumbnail Generation - Multi-size thumbnails for optimized loading performance
- 📊 EXIF Information Display - Complete shooting parameters including camera model, focal length, aperture, etc.
- 🌈 Blurhash Placeholders - Elegant image loading experience
- 📱 Live Photo Support - Detection and display of iPhone Live Photos
- ☀️ HDR Image Support - Display HDR images
Advanced Features
- 🎛️ Fujifilm Recipe - Read and display Fujifilm camera film simulation settings
- 🔍 Fullscreen Viewer - Image viewer with gesture support
- 🏷️ File System Tags - Auto-generated tags based on file system
- ⚡ Concurrent Processing - Multi-process/multi-thread concurrent processing support
- 🗂️ Multi-Storage Support - S3, GitHub, and other storage backends
- 📷 Share Image - Share image to social media or embed iframe to your website
- 🗺️ Interactive Map Explorer - Geographic visualization of photos with GPS coordinates from EXIF data using MapLibre
🏗️ Technical Architecture
Frontend Tech Stack
- React 19 - Latest React version with Compiler
- TypeScript - Complete type safety
- Vite - Modern build tool
- Tailwind CSS - Atomic CSS framework
- Radix UI - Accessible component library
- Jotai - State management
- TanStack Query - Data fetching and caching
- React Router 7 - Routing management
- i18next - Internationalization
Build System
- Node.js - Server-side runtime
- Sharp - High-performance image processing
- AWS SDK - S3 storage operations
- Worker Threads/Cluster - Concurrent processing
- EXIF-Reader - EXIF data extraction
Storage Architecture
Designed with adapter pattern, supporting multiple storage backends:
- S3-Compatible Storage - AWS S3, MinIO, Alibaba Cloud OSS, etc.
- GitHub Storage - Using GitHub repository as image storage
- Eagle Storage - Using Eagle app library as image storage
- Local File System - Local storage for development and testing
🚀 Self-Host
Option A: Docker (recommended)
Docker deployment guide ships prebuilt images with minimal setup.
Option B: Manual install
- Copy
config.example.jsontoconfig.jsonand fill in your site name, description, and social links. - Prepare access to your photo storage (S3/B2/GitHub/local). The builder will read photos and generate thumbnails plus
photos-manifest.json. - Run the builder to generate assets, then start the site.
Looking for developer commands, environment variables, and builder config details? See DEVELOPMENT.md.
🔧 Advanced Usage
Custom Storage Provider
Implement the StorageProvider interface to support new storage backends:
import { StorageProvider } from './src/core/storage/interfaces'
class MyStorageProvider implements StorageProvider {
async getFile(key: string): Promise<Buffer | null> {
// Implement file retrieval logic
}
async listImages(): Promise<StorageObject[]> {
// Implement image list retrieval logic
}
// ... other methods
}
Custom Image Processing
Add custom processors in the src/core/image/ directory:
export async function customImageProcessor(buffer: Buffer) {
// Custom image processing logic
return processedBuffer
}
📄 License
Attribution Network License (ANL) v1.0 © 2025 Afilmory Team. See LICENSE for more details.
🔗 Related Links
If this project helps you, please give it a ⭐️ Star for support!
