72 lines
2.0 KiB
Markdown
72 lines
2.0 KiB
Markdown
# Book Cover Images Setup
|
|
|
|
HXBooks now supports book cover images using static file storage with nginx/caddy for production.
|
|
|
|
## Architecture
|
|
|
|
**Development**: Flask serves covers via `/media/covers/<filename>` route
|
|
**Production**: nginx serves covers directly from filesystem for optimal performance
|
|
|
|
## File Structure
|
|
|
|
```
|
|
/app/
|
|
├── src/hxbooks/static/ # App assets (CSS, JS) -> served at /static/
|
|
├── media/covers/ # Book covers -> served at /media/
|
|
└── instance/ # Database, config
|
|
```
|
|
|
|
## Production Deployment
|
|
|
|
### Docker Setup
|
|
```bash
|
|
# Build and run with nginx + gunicorn
|
|
docker-compose up --build
|
|
|
|
# Or build manually
|
|
docker build -f Dockerfile.production -t hxbooks .
|
|
docker run -p 8080:80 -v ./media:/app/media -v ./instance:/app/instance hxbooks
|
|
```
|
|
|
|
### nginx Configuration
|
|
- Static files: nginx serves `/static/` and `/media/` directly
|
|
- Dynamic requests: proxied to gunicorn on port 8080
|
|
- Proper caching headers for performance
|
|
|
|
## Cover Image Features
|
|
|
|
### CLI
|
|
```bash
|
|
# Import with cover download (default)
|
|
hxbooks book import "9780123456789"
|
|
|
|
# Skip cover download
|
|
hxbooks book import "9780123456789" --no-cover
|
|
```
|
|
|
|
### Web Interface
|
|
- Book cards display covers when available
|
|
- Fallback to book emoji for books without covers
|
|
- Google Books API integration provides cover URLs
|
|
|
|
## Storage Details
|
|
|
|
- **Images downloaded from**: Google Books API (thumbnail/smallThumbnail)
|
|
- **Filename format**: `book_{id}.{extension}`
|
|
- **Security**: HTTP URLs converted to HTTPS
|
|
- **Fallback**: graceful handling if download fails
|
|
- **Database**: `cover_image_path` field stores relative filename
|
|
|
|
## Performance
|
|
|
|
**nginx serves static files directly** (bypassing Python completely):
|
|
- ✅ ~1ms response time for images
|
|
- ✅ Proper browser caching
|
|
- ✅ Gzip compression
|
|
- ✅ No Python memory usage for images
|
|
|
|
vs. database BLOB storage through Python:
|
|
- ❌ ~50-200ms response time
|
|
- ❌ Limited caching options
|
|
- ❌ High memory usage
|
|
- ❌ Database file bloat |