A modern, multilingual, self-hosted web application for managing your personal home library. Track books across multiple locations, scan book covers with AI, manage writers and publishers, lend books to friends, and generate reports β all from a responsive mobile-friendly interface.
- Scan book covers with your phone camera to extract title and author
- Scan back pages to extract ISBN, publisher, and publication year
- Powered by Google Gemini Flash Vision AI (free tier β 1,500 scans/day)
- Supports Arabic calligraphy, French, and English book covers
- Falls back to Tesseract OCR if no API key configured
- Editable results β correct OCR output before searching/adding
- Automatically searches your library for matches
- One-tap "Add Book" with pre-filled details from scan
- Full CRUD for your book collection
- Search by title, author, genre, language, year
- Filter by read status, borrowed status, location
- ISBN lookup via Open Library API
- Assign books to specific shelves (Address β Room β Shelf)
- Link books to publishers from your registry
- Mark books as read/unread
- Manage multiple physical addresses (Home, Office, Summer House, etc.)
- Set a primary location for your library
- Create rooms within each address (Living Room, Study, etc.)
- Create shelves within each room with capacity tracking
- Full hierarchy: Address β Rooms β Shelves β Books
- Visual tree view of your entire library layout
- Book count per location/room/shelf
- Dedicated publisher/edition house registry
- Multilingual names (English, Arabic, French)
- Contact info: address, city, country, phone, email, website
- Link publishers to books
- View book count per publisher
- Dedicated writers/authors registry
- Multilingual names (English, Arabic, French)
- Nationality, birth/death year, biography
- Select writers when adding a book (dropdown + manual entry)
- View book count per writer
- Create, edit, and delete genres
- Multilingual genre names (English, Arabic, French)
- Select genres when adding books
- Lend books to friends with due dates
- Track overdue books with alerts
- Mark books as returned
- Full lending history per book
- Dashboard with reading statistics
- Reports by genre, author, year, location
- Language distribution visualization
- Export to CSV and PDF
- Role-based access control (Admin, User, Viewer)
- Create/disable/delete users
- JWT-based authentication
- Update profile information (name, username, email)
- Change password with strength validation
- View account info and role
- Automatic daily database backups (2:00 AM)
- Manual backup creation
- Download and manage backup files
- Secure
.pgpassauthentication (no env var exposure)
- English π¬π§
- Arabic πΈπ¦ (with full RTL support)
- French π«π·
- Language switcher in the UI, preference saved per user
- Hamburger menu navigation on mobile
- Touch-friendly card layouts
- Camera capture directly from phone
- Optimized for phone-first usage
- Rate limiting on login (5/15min) and registration (3/hr)
- CORS restricted to configured origin
- Content Security Policy headers
- JWT with 8-hour expiry
- No hardcoded secrets β fails fast if env not set
- Container resource limits
- Password policy enforcement (10+ chars with complexity)
- Command injection prevention
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend β
β Vue.js 3 + Vite + Tailwind CSS β
β (nginx:alpine) β
β Port 3000 β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β HTTP API calls
βββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β Backend β
β PHP 8.3 + Apache + Tesseract OCR + GD β
β Custom REST API + Gemini Vision β
β Port 8080 β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β PostgreSQL protocol
βββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β Database β
β PostgreSQL 16 Alpine β
β Port 5432 β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
- Docker or Podman with Compose support
- (Optional) Google Gemini API Key for AI book scanning (free)
-
Clone the repository
git clone https://github.com/XKlibure/home-library.git cd home-library -
Configure environment
cp .env.example .env # Edit .env β generate strong passwords: # DB_PASSWORD, JWT_SECRET, APP_KEY (see .env.example for instructions)
For AI book scanning, add your free Gemini key:
GEMINI_API_KEY=your-key-from-aistudio.google.com
-
Build and start
docker compose up -d --build
Or with Podman:
podman compose up -d --build
-
Access the application
Service URL Frontend http://localhost:3000 Backend API http://localhost:8080/api -
Login
Field Value Username adminPassword Admin1234!β οΈ Change this password immediately via Settings page!
To use the scanner from your phone on the same network:
# In .env, set your computer's LAN IP:
API_URL=http://192.168.1.x:8080/api
CORS_ORIGIN=http://192.168.1.x:3000Then rebuild frontend: docker compose up -d --build frontend
home-library/
βββ docker-compose.yml
βββ .env.example
βββ sonar-project.properties
βββ CONTRIBUTING.md
βββ LICENSE
βββ docker/
β βββ Dockerfile.frontend # Vue.js multi-stage build
β βββ Dockerfile.backend # PHP 8.3 + Apache + Tesseract + GD
β βββ Dockerfile.db # PostgreSQL + init script
β βββ Dockerfile.backup # Backup cron service
β βββ nginx.conf # Frontend nginx + security headers
β βββ apache.conf # Backend Apache vhost
β βββ init.sql # Database schema (10 tables)
β βββ backup-cron.sh # Automated backup script
βββ backend/
β βββ composer.json
β βββ public/index.php # Entry point + CORS + security headers
β βββ routes/api.php # 50+ API routes
β βββ app/
β βββ Config/Database.php
β βββ Controllers/
β β βββ AuthController.php
β β βββ BooksController.php
β β βββ WritersController.php
β β βββ GenresController.php
β β βββ PublishersController.php # NEW
β β βββ LocationsController.php # NEW
β β βββ ScanController.php # NEW (AI Vision)
β β βββ LendingController.php
β β βββ ReportsController.php
β β βββ UsersController.php
β β βββ BackupController.php
β βββ Middleware/
β β βββ AuthMiddleware.php
β β βββ AdminMiddleware.php
β β βββ UserMiddleware.php # NEW
β β βββ RateLimiter.php # NEW
β βββ Router.php
βββ frontend/
β βββ package.json
β βββ vite.config.js
β βββ tailwind.config.js
β βββ index.html
β βββ src/
β βββ main.js
β βββ App.vue # Responsive nav + hamburger menu
β βββ i18n/ # en.js, ar.js, fr.js
β βββ router/index.js # 15 routes with guards
β βββ services/api.js # Axios + token expiry check
β βββ store/ # auth.js, toast.js
β βββ views/
β βββ LoginView.vue
β βββ DashboardView.vue
β βββ BooksView.vue
β βββ BookFormView.vue
β βββ BookDetailView.vue
β βββ ScanBookView.vue # NEW (camera + AI)
β βββ WritersView.vue
β βββ GenresView.vue
β βββ PublishersView.vue # NEW
β βββ LocationsView.vue # NEW (hierarchy)
β βββ LendingView.vue
β βββ ReportsView.vue
β βββ SettingsView.vue # NEW (profile + password)
β βββ UsersView.vue
β βββ BackupView.vue
βββ .github/
βββ workflows/sonarqube.yml
βββ ISSUE_TEMPLATE/
βββ bug_report.md
βββ feature_request.md
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/login |
Login (rate limited) |
| POST | /api/auth/register |
Register (rate limited) |
| GET | /api/auth/me |
Get current user |
| PUT | /api/auth/profile |
Update profile info |
| PUT | /api/auth/password |
Change password |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/scan/cover |
Scan front cover (AI + OCR) |
| POST | /api/scan/back |
Scan back page (AI + OCR) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/books |
List books (paginated, filterable) |
| GET | /api/books/{id} |
Get book details + lending history |
| POST | /api/books |
Create book |
| PUT | /api/books/{id} |
Update book |
| DELETE | /api/books/{id} |
Delete book |
| POST | /api/books/{id}/toggle-read |
Toggle read status |
| POST | /api/books/isbn-lookup |
Lookup by ISBN (Open Library) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/publishers |
List publishers (searchable) |
| GET | /api/publishers/{id} |
Get publisher details |
| POST | /api/publishers |
Create publisher (admin) |
| PUT | /api/publishers/{id} |
Update publisher (admin) |
| DELETE | /api/publishers/{id} |
Delete publisher (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/locations/tree |
Full hierarchy for dropdowns |
| GET | /api/locations |
List all addresses |
| GET | /api/locations/{id} |
Get address + rooms + shelves |
| POST | /api/locations |
Create address (admin) |
| PUT | /api/locations/{id} |
Update address (admin) |
| DELETE | /api/locations/{id} |
Delete address (admin) |
| GET | /api/locations/{id}/rooms |
List rooms in address |
| POST | /api/rooms |
Create room (admin) |
| PUT | /api/rooms/{id} |
Update room (admin) |
| DELETE | /api/rooms/{id} |
Delete room (admin) |
| GET | /api/rooms/{id}/shelves |
List shelves in room |
| POST | /api/shelves |
Create shelf (admin) |
| PUT | /api/shelves/{id} |
Update shelf (admin) |
| DELETE | /api/shelves/{id} |
Delete shelf (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/writers |
List all writers |
| GET | /api/writers/{id} |
Get writer + books |
| POST | /api/writers |
Create writer (admin) |
| PUT | /api/writers/{id} |
Update writer (admin) |
| DELETE | /api/writers/{id} |
Delete writer (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/genres |
List all genres |
| POST | /api/genres |
Create genre (admin) |
| PUT | /api/genres/{id} |
Update genre (admin) |
| DELETE | /api/genres/{id} |
Delete genre (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/lending |
List lending records |
| POST | /api/lending |
Lend a book |
| PUT | /api/lending/{id} |
Update lending record |
| POST | /api/lending/{id}/return |
Mark as returned |
| DELETE | /api/lending/{id} |
Delete record |
| GET | /api/lending/overdue |
Get overdue books |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/reports/summary |
Dashboard stats |
| GET | /api/reports/by-genre |
Books by genre |
| GET | /api/reports/by-author |
Books by author |
| GET | /api/reports/by-year |
Books by year |
| GET | /api/reports/by-location |
Books by location |
| GET | /api/reports/export/csv |
Export CSV |
| GET | /api/reports/export/pdf |
Export PDF |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users |
List users |
| PUT | /api/users/{id} |
Update user |
| DELETE | /api/users/{id} |
Delete user |
| POST | /api/backup/create |
Create backup |
| GET | /api/backup/list |
List backups |
| GET | /api/backup/download/{file} |
Download backup |
| DELETE | /api/backup/{file} |
Delete backup |
# Stop
docker compose down
# Reset database (fresh start)
docker compose down -v && docker compose up -d --build
# View logs
docker compose logs -f backend
# Rebuild single service
docker compose up -d --build frontend
# Access from phone (set your LAN IP in .env first)
API_URL=http://192.168.1.x:8080/api docker compose up -d --build frontendThis application is security-hardened against the OWASP Top 10:
| Feature | Status |
|---|---|
| SQL Injection protection (PDO prepared statements) | β |
| XSS prevention (Vue.js auto-escaping + htmlspecialchars) | β |
| CORS restricted to configured origin | β |
| JWT authentication with 8h expiry | β |
| Rate limiting (login: 5/15min, register: 3/hr) | β |
| Password policy (10+ chars, uppercase, lowercase, number) | β |
| Role-based access control (Admin/User/Viewer) | β |
| Security headers (CSP, X-Frame-Options, etc.) | β |
| No hardcoded secrets (fails fast if env not set) | β |
| Command injection prevention (escapeshellarg) | β |
| Container resource limits (memory/CPU) | β |
| Database port not exposed by default | β |
| Secure backup file permissions (chmod 600) | β |
| Request timeout (30s default, 60s for scans) | β |
| Token expiry check on frontend | β |
| Generic error messages (no stack traces to client) | β |
See Security Notes below for production deployment checklist.
- Generate strong secrets in
.env(see.env.example) - Change default admin password immediately
- Set
APP_DEBUG=false - Configure
CORS_ORIGINto your frontend domain - Deploy behind HTTPS reverse proxy (nginx/Caddy/Traefik)
- Database port is NOT exposed by default β
- Optionally disable open registration (see
CONTRIBUTING.md)
| Layer | Technology |
|---|---|
| Frontend | Vue.js 3, Vite 5, Tailwind CSS 3, Pinia, Vue Router, Vue I18n, Axios |
| Backend | PHP 8.3, Apache, Custom Router, Firebase PHP-JWT, DomPDF, Tesseract OCR |
| AI Vision | Google Gemini Flash (free tier) |
| Database | PostgreSQL 16 (10 tables) |
| Containerization | Docker / Podman Compose |
| Web Server | Nginx Alpine (frontend), Apache (backend) |
| CI/CD | GitHub Actions + SonarQube |
| Backup | pg_dump + cron + gzip |
Contributions are welcome! See CONTRIBUTING.md for guidelines.
- π Report a Bug
- π‘ Request a Feature
- π Translate β Copy
frontend/src/i18n/en.jsto add a new language
This project is licensed under the MIT License. You are free to use, modify, and distribute this software.