- Architecture overview: previews/ directory structure - Backend: Sharp library for image processing - DB schema extension: preview_path column - Frontend: Use previews in galleries, keep originals in slideshow - Estimated effort: 12-22h (2-3 days) - Expected improvement: ~95% size reduction, ~96% faster load times Ref: feature/preview-images |
||
|---|---|---|
| .copilot | ||
| .github/ISSUES | ||
| backend | ||
| docs | ||
| frontend | ||
| scripts | ||
| test_photos | ||
| CHANGELOG.md | ||
| docker-compose.override.yml | ||
| docker-compose.yml | ||
| LICENSE | ||
| prod.sh | ||
| README.dev.md | ||
| README.md | ||
| TODO.md | ||
Image Uploader with Multi-Upload & Slideshow
A self-hosted image uploader with multi-image upload capabilities and automatic slideshow functionality.
Features
Multi-Image Upload: Upload multiple images at once with batch processing
Slideshow Mode: Automatic fullscreen slideshow with smooth transitions
Persistent Storage: Docker volumes ensure data persistence across restarts
Clean UI: Minimalist design focused on user experience
Self-Hosted: Complete control over your data and infrastructure
Lightweight: Built with modern web technologies for optimal performance
What's New
This project extends the original Image-Uploader by vallezw with enhanced multi-upload and slideshow capabilities.
- Multi-image batch upload with progress tracking
- Automatic slideshow presentation mode
- Image grouping with descriptions
- Random slideshow rotation
- Keyboard navigation support
- Mobile-responsive design
Quick Start
Docker Deployment (Recommended)
- Create docker-compose.yml:
services:
image-uploader-frontend:
image: gitea.lan.hobbyhimmel.de/hobbyhimmel/image-uploader-frontend:latest
ports:
- "80:80"
build:
context: ./frontend
dockerfile: ./Dockerfile
depends_on:
- "image-uploader-backend"
environment:
- "API_URL=http://image-uploader-backend:5000"
- "CLIENT_URL=http://localhost"
container_name: "image-uploader-frontend"
networks:
- npm-nw
- image-uploader-internal
image-uploader-backend:
image: gitea.lan.hobbyhimmel.de/hobbyhimmel/image-uploader-backend:latest
ports:
- "5000:5000"
build:
context: ./backend
dockerfile: ./Dockerfile
container_name: "image-uploader-backend"
networks:
- image-uploader-internal
volumes:
- app-data:/usr/src/app/src/data
volumes:
app-data:
driver: local
networks:
npm-nw:
external: true
image-uploader-internal:
driver: bridge
- Start the application:
docker compose up -d
- Access the application:
- Upload Interface:
http://localhost - Backend:
http://localhost:5000 - Slideshow Mode:
http://localhost/slideshow
Multi-Image Upload
- Visit
http://localhost - Drag & drop multiple images or click to select
- Add an optional description for your image collection
- Click "Upload Images" to process the batch
- Images are automatically grouped for slideshow viewing
Slideshow Mode
-
Automatic Access: Navigate to
http://localhost/slideshow -
Features:
- Fullscreen presentation
- 4-second display per image
- Automatic progression through all slideshow collections
- Random selection of next slideshow after completing current one
- Smooth fade transitions (0.5s)
-
Keyboard Controls:
- ESC: Exit slideshow / Return to upload page
- Spacebar / Arrow Right: Manually advance to next image
- Home Button: Return to main upload interface
Moderation Interface (Protected)
-
Access:
http://localhost/moderation(requires authentication) -
Authentication: HTTP Basic Auth (username: admin, password: set during setup)
-
Features:
- Review pending image groups before public display
- Approve or reject submitted collections
- Delete individual images from approved groups
- View group details (title, creator, description, image count)
- Bulk moderation actions
-
Security Features:
- Password protected access via nginx HTTP Basic Auth
- Hidden from search engines (
robots.txt+noindexmeta tags) - No public links or references in main interface
Public Overview of all approved slideshows
- Group Management: Navigate to
http://localhost/groups- Overview of all approved slideshow collections
- Launch slideshow mode from any group
- View group statistics and metadata
Data Structure
Data are stored in sqlite database. The structure is as follows:
CREATE TABLE groups (
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id TEXT UNIQUE NOT NULL,
year INTEGER NOT NULL,
title TEXT NOT NULL,
description TEXT,
name TEXT,
upload_date DATETIME NOT NULL,
approved BOOLEAN DEFAULT FALSE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE sqlite_sequence(name,seq);
CREATE TABLE images (
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id TEXT NOT NULL,
file_name TEXT NOT NULL,
original_name TEXT NOT NULL,
file_path TEXT NOT NULL,
upload_order INTEGER NOT NULL,
file_size INTEGER,
mime_type TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (group_id) REFERENCES groups(group_id) ON DELETE CASCADE
);
CREATE INDEX idx_groups_group_id ON groups(group_id);
CREATE INDEX idx_groups_year ON groups(year);
CREATE INDEX idx_groups_upload_date ON groups(upload_date);
CREATE INDEX idx_images_group_id ON images(group_id);
CREATE INDEX idx_images_upload_order ON images(upload_order);
CREATE TRIGGER update_groups_timestamp
AFTER UPDATE ON groups
FOR EACH ROW
BEGIN
UPDATE groups SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
Architecture
Backend (Node.js + Express)
- Multi-upload API:
/api/upload/batch- Handles batch file processing - Groups API:
/api/groups- Retrieves slideshow collections - File Storage: Organized in
/uploaddirectory - Database Storage: sqlite database in
/app/src/data/db/image_uploader.db
Frontend (React + Material-UI)
- Multi-Upload Interface: Drag & drop with preview gallery
- Progress Tracking: Real-time upload status
- Spacebar / Arrow Right: Manually advance to next image
- Slideshow Engine: Fullscreen presentation with automatic progression
- Responsive Design: Mobile and desktop optimized
- Home Button: Return to main upload interface
Storage Architecture
Docker Volume (app-data)
src
└── app
├── src
├── upload
│ ├── ZMmHXzHbqw.jpg
│ ├── tjjnngOmXS.jpg
│ └── ...
└── data
└── db
└── image_uploader.db
Hosting it with Docker
- Frontend: React 17, Material-UI, React Router
- Backend: Node.js, Express, Multer (file handling)
- Containerization: Docker, Docker Compose
- Reverse Proxy: nginx (routing & file serving)[In order to host the project you will need to create a docker-compose file. These files are combining multiple docker images to interact with each other.
- File Upload: Drag & drop with react-dropzone
- Notifications: SweetAlert2
API Endpoints
Upload Operations
POST /api/upload/batch- Upload multiple images with descriptionGET /api/groups- Retrieve all slideshow groupsGET /api/groups/:id- Get specific slideshow group
Moderation Operations (Protected)
GET /moderation/groups- Get all groups pending moderationPOST /groups/:id/approve- Approve a group for public displayDELETE /groups/:id- Delete an entire groupDELETE /groups/:id/images/:imageId- Delete individual image from group
File Access
GET /api/upload/:filename- Access uploaded image files
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
API_URL |
http://localhost:5000 |
Backend API endpoint |
CLIENT_URL |
http://localhost |
Frontend application URL |
Volume Configuration
- Upload Limits: 100MB maximum file size for batch uploads
- Supported Formats: JPG, JPEG, PNG, GIF, WebP
Backup & Restore
Backup slideshow data
docker cp image-uploader-backend:/usr/src/app/src/data/ ./image-uploader-backup-data
Restore slideshow data
docker cp ./image-uploader-backup-data image-uploader-backend:/usr/src/app/src/data
Contributing
Contributions are welcome!
This project extends the original work by vallezw.
Development Setup
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature| Field | Type | Description |#### Changing the URL - Open a Pull Request
License
This project is distributed under the MIT License. See LICENSE for more information.
Acknowledgments
- Original project: Image-Uploader by vallezw