BookLore Docker 설치 가이드: 전자책 라이브러리 관리 시스템




개요

BookLore는 셀프호스팅 전자책 라이브러리 관리 시스템입니다. Calibre의 현대적 대안으로, 아름다운 UI, 자동 메타데이터 수집, Kobo/KOReader 동기화, OPDS 지원, 내장 리더를 제공합니다. “전자책을 위한 Jellyfin”이라고 불립니다.

항목내용
GitHubhttps://github.com/booklore-app/booklore
공식 사이트https://booklore.org
문서https://booklore-app.github.io/booklore-docs
데모https://demo.booklore.org
라이선스AGPL-3.0
GitHub Stars10K+

BookLore란?

왜 BookLore인가?

기존 전자책 관리 도구들의 문제점:

  • Calibre: 강력하지만 UI가 오래됨, 웹 인터페이스 부족
  • Calibre-Web: 기능 제한, 설정 복잡
  • 폴더 기반: 메타데이터 없음, 검색 어려움

BookLore는 이 모든 것을 해결합니다:

✅ 현대적이고 깔끔한 UI
✅ 자동 메타데이터 수집 (Goodreads, Amazon, Google Books)
✅ 내장 EPUB/PDF/CBZ 리더
✅ Kobo & KOReader 동기화
✅ OPDS 서버
✅ 멀티 유저 지원
✅ Magic Shelves (스마트 플레이리스트)
✅ BookDrop 자동 가져오기

핵심 철학

"전자책 라이브러리를 위한 Jellyfin/Plex"
- 아름다운 인터페이스
- 자동화된 메타데이터
- 어디서든 접근 가능
- 프라이버시 보장

주요 기능

📚 라이브러리 관리

기능설명
Libraries책 폴더 경로 기반 라이브러리
Shelves커스텀 책장
Magic Shelves규칙 기반 자동 컬렉션
필터 & 검색빠른 전체 텍스트 검색
시리즈 그룹시리즈 자동 감지 및 그룹화

🧠 메타데이터

기능설명
자동 수집Google Books, Amazon, Goodreads, Hardcover, Open Library
커버 이미지자동 다운로드
설명/리뷰책 설명, 커뮤니티 리뷰
수동 편집모든 메타데이터 직접 편집
ISBN 감지EPUB에서 ISBN 자동 추출

📖 내장 리더

형식지원
EPUB✅ 주석, 하이라이트, 북마크
PDF✅ 스트리밍 읽기
CBZ/CBR✅ 만화/코믹스
MOBI/AZW3
FB2

📱 디바이스 동기화

기능설명
Kobo 동기화Kobo 기기와 라이브러리 동기화
KEPUB 변환EPUB → KEPUB 자동 변환
KOReader 동기화읽기 진행률 양방향 동기화
OPDS모든 OPDS 호환 앱 연결
Komga APIMihon, Komelia 연결

👥 멀티 유저

기능설명
계정 관리관리자/사용자 계정
권한 제어라이브러리별 접근 권한
개인 노트사용자별 개인 메모
읽기 진행사용자별 진행률 추적

📥 BookDrop

기능설명
자동 감지폴더에 파일 드롭
메타데이터 추출파일명/내장 데이터에서 추출
미리보기 & 검토가져오기 전 확인
일괄 가져오기대량 책 추가

🔐 인증

방식설명
로컬 계정기본 JWT 인증
OIDCAuthentik, Authelia, Pocket ID
Remote Auth리버스 프록시 인증

📊 통계 & 차트

기능설명
읽기 통계독서 진행, 완료
Taste Ratings취향 평점
Reading Backlog읽을 책 백로그
Series Progress시리즈 진행률

대안 비교

기능BookLoreCalibre-WebKavitaKomga
대상전자책전자책전자책/만화만화/전자책
UI⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
자동 메타데이터✅ 다중 소스✅ 제한적
내장 리더✅ EPUB/PDF/CBZ
Kobo 동기화
KOReader 동기화
OPDS
Magic Shelves
BookDrop
멀티 유저
설치 난이도쉬움중간쉬움쉬움

선택 가이드

용도추천
전자책 + Kobo/KOReaderBookLore
Calibre 라이브러리 연동Calibre-Web
만화/코믹스 중심Komga, Kavita
라이트노벨/만화 + 전자책Kavita

시스템 요구 사항

항목최소권장
CPU1 코어2+ 코어
RAM1GB2GB+
저장소책 크기에 따라
포트6060
데이터베이스MariaDBMariaDB

Docker 설치

방법 1: 기본 설치

디렉토리 생성:

mkdir -p ~/booklore/{config/mariadb,data,books,bookdrop}
cd ~/booklore

.env 파일:

# Application
APP_USER_ID=1000
APP_GROUP_ID=1000
TZ=Asia/Seoul

# Database
DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
DB_USER=booklore
DB_PASSWORD=ChangeMe_BookLore_2025!

# Storage: LOCAL (default) or NETWORK (NFS/SMB)
DISK_TYPE=LOCAL

# MariaDB
DB_USER_ID=1000
DB_GROUP_ID=1000
MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
MYSQL_DATABASE=booklore

docker-compose.yml:

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      - ./books:/books
      - ./bookdrop:/bookdrop
    environment:
      - TZ=${TZ}
      - APP_USER_ID=${APP_USER_ID}
      - APP_GROUP_ID=${APP_GROUP_ID}
      - DATABASE_URL=${DATABASE_URL}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - DISK_TYPE=${DISK_TYPE}

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=${DB_USER_ID}
      - PGID=${DB_GROUP_ID}
      - TZ=${TZ}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASSWORD}
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

실행:

docker compose up -d

접속: http://localhost:6060

방법 2: 다중 라이브러리

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      # 다중 라이브러리 폴더
      - ./books/fiction:/books/fiction
      - ./books/nonfiction:/books/nonfiction
      - ./books/comics:/books/comics
      - ./bookdrop:/bookdrop
    environment:
      - TZ=Asia/Seoul
      - APP_USER_ID=1000
      - APP_GROUP_ID=1000
      - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
      - DB_USER=booklore
      - DB_PASSWORD=ChangeMe_BookLore_2025!
      - DISK_TYPE=LOCAL

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
      - MYSQL_DATABASE=booklore
      - MYSQL_USER=booklore
      - MYSQL_PASSWORD=ChangeMe_BookLore_2025!
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

방법 3: NFS/SMB 네트워크 스토리지

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      - /mnt/nas/books:/books
      - ./bookdrop:/bookdrop
    environment:
      - TZ=Asia/Seoul
      - APP_USER_ID=1000
      - APP_GROUP_ID=1000
      - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
      - DB_USER=booklore
      - DB_PASSWORD=ChangeMe_BookLore_2025!
      # NFS/SMB 사용 시 필수
      - DISK_TYPE=NETWORK

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
      - MYSQL_DATABASE=booklore
      - MYSQL_USER=booklore
      - MYSQL_PASSWORD=ChangeMe_BookLore_2025!
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

⚠️ DISK_TYPE=NETWORK은 NFS/SMB 사용 시 필수입니다. 파일 재구성 기능이 비활성화되어 데이터 손상을 방지합니다.

방법 4: OIDC 인증 (Authentik)

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      - ./books:/books
      - ./bookdrop:/bookdrop
    environment:
      - TZ=Asia/Seoul
      - APP_USER_ID=1000
      - APP_GROUP_ID=1000
      - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
      - DB_USER=booklore
      - DB_PASSWORD=ChangeMe_BookLore_2025!
      - DISK_TYPE=LOCAL
      # OIDC 설정
      - OIDC_ENABLED=true
      - OIDC_ISSUER=https://auth.example.com/application/o/booklore/
      - OIDC_CLIENT_ID=your-client-id
      - OIDC_CLIENT_SECRET=your-client-secret
      - OIDC_REDIRECT_URI=https://books.example.com/auth/oidc/callback

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
      - MYSQL_DATABASE=booklore
      - MYSQL_USER=booklore
      - MYSQL_PASSWORD=ChangeMe_BookLore_2025!
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

방법 5: Traefik + HTTPS

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    volumes:
      - ./data:/app/data
      - ./books:/books
      - ./bookdrop:/bookdrop
    environment:
      - TZ=Asia/Seoul
      - APP_USER_ID=1000
      - APP_GROUP_ID=1000
      - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
      - DB_USER=booklore
      - DB_PASSWORD=ChangeMe_BookLore_2025!
      - DISK_TYPE=LOCAL
    networks:
      - traefik_network
      - internal
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.booklore.rule=Host(`books.example.com`)"
      - "traefik.http.routers.booklore.entrypoints=websecure"
      - "traefik.http.routers.booklore.tls.certresolver=letsencrypt"
      - "traefik.http.services.booklore.loadbalancer.server.port=6060"

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
      - MYSQL_DATABASE=booklore
      - MYSQL_USER=booklore
      - MYSQL_PASSWORD=ChangeMe_BookLore_2025!
    networks:
      - internal
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  traefik_network:
    external: true
  internal:
    driver: bridge

방법 6: Remote Auth (리버스 프록시 인증)

services:
  booklore:
    image: booklore/booklore:latest
    container_name: booklore
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      - ./books:/books
      - ./bookdrop:/bookdrop
    environment:
      - TZ=Asia/Seoul
      - APP_USER_ID=1000
      - APP_GROUP_ID=1000
      - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore
      - DB_USER=booklore
      - DB_PASSWORD=ChangeMe_BookLore_2025!
      - DISK_TYPE=LOCAL
      # Remote Auth (리버스 프록시 인증)
      - REMOTE_AUTH_ENABLED=true
      - REMOTE_AUTH_HEADER=X-Remote-User
      - REMOTE_AUTH_EMAIL_HEADER=X-Remote-Email

  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: booklore-mariadb
    restart: unless-stopped
    volumes:
      - ./config/mariadb:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
      - MYSQL_DATABASE=booklore
      - MYSQL_USER=booklore
      - MYSQL_PASSWORD=ChangeMe_BookLore_2025!
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

환경 변수

애플리케이션

변수설명기본값
TZ타임존Etc/UTC
APP_USER_ID실행 UID1000
APP_GROUP_ID실행 GID1000
BOOKLORE_PORT웹 포트6060

데이터베이스

변수설명
DATABASE_URLJDBC 연결 문자열
DB_USERDB 사용자
DB_PASSWORDDB 비밀번호

스토리지

변수설명기본값
DISK_TYPELOCAL 또는 NETWORKLOCAL

⚠️ NFS/SMB 사용 시 DISK_TYPE=NETWORK 필수

OIDC

변수설명
OIDC_ENABLEDOIDC 활성화
OIDC_ISSUEROIDC Issuer URL
OIDC_CLIENT_ID클라이언트 ID
OIDC_CLIENT_SECRET클라이언트 시크릿
OIDC_REDIRECT_URI콜백 URI

Remote Auth

변수설명
REMOTE_AUTH_ENABLEDRemote Auth 활성화
REMOTE_AUTH_HEADER사용자명 헤더
REMOTE_AUTH_EMAIL_HEADER이메일 헤더

초기 설정

1) 첫 접속

URL: http://localhost:6060
→ 관리자 계정 생성

2) 라이브러리 추가

  1. Settings → Libraries
  2. Add Library 클릭
  3. 경로 입력 (예: /books 또는 /books/fiction)
  4. Scan Now

3) BookDrop 활용

# 새 책 추가
cp /path/to/new-books/*.epub ~/booklore/bookdrop/

# BookLore가 자동 감지
# UI → BookDrop에서 검토 및 가져오기

4) 메타데이터 설정

Settings → Metadata Providers:

  • Google Books (기본)
  • Amazon
  • Open Library
  • Goodreads (API 키 필요)
  • Hardcover

우선순위 설정 가능


사용 가이드

Magic Shelves (스마트 컬렉션)

예시 규칙:

이름규칙
읽을 책status = "unread"
올해 완독status = "read" AND year = 2025
SF 소설genre = "Science Fiction"
시리즈 미완series != null AND seriesComplete = false

KOReader 동기화

설정:

  1. BookLore: Settings → Integrations → KOReader
  2. API 토큰 생성
  3. KOReader: Settings → Cloud Storage → Custom sync server
  4. URL: https://books.example.com/api/koreader

동기화 내용:

  • 읽기 진행률
  • 북마크
  • 하이라이트

OPDS 연결

OPDS URL:

https://books.example.com/opds

호환 앱:

  • KOReader
  • Moon+ Reader
  • Librera
  • FBReader
  • Thorium Reader

Kobo 동기화

  1. BookLore: Settings → Integrations → Kobo
  2. 동기화 활성화
  3. Kobo 기기에서 BookLore 서버 설정
  4. EPUB → KEPUB 자동 변환

이메일로 책 보내기

  1. Settings → Email
  2. SMTP 설정
  3. 책 상세 페이지 → Share → Send to Email
  4. Kindle 이메일 주소로 전송 가능

백업 및 복원

데이터 구조

~/booklore/
├── config/mariadb/     # MariaDB 데이터
├── data/               # BookLore 앱 데이터 (설정, 메타데이터, 캐시)
├── books/              # 책 파일
└── bookdrop/           # 가져오기 폴더

백업

# 컨테이너 정지
docker compose down

# 전체 백업
tar -czvf booklore-backup-$(date +%Y%m%d).tar.gz \
  config/ data/ books/

# 컨테이너 재시작
docker compose up -d

MariaDB 덤프

docker compose exec mariadb mysqldump -u booklore -p booklore > backup.sql

복원

# 백업 해제
tar -xzvf booklore-backup.tar.gz

# 컨테이너 시작
docker compose up -d

업데이트

cd ~/booklore

# 백업 먼저!
tar -czvf booklore-backup-$(date +%Y%m%d).tar.gz config/ data/

# 최신 이미지
docker compose pull

# 재시작
docker compose down
docker compose up -d

# 로그 확인
docker compose logs -f booklore

트러블슈팅

권한 오류

# UID/GID 확인
id

# .env에서 설정
APP_USER_ID=1000
APP_GROUP_ID=1000

NFS/SMB 파일 이동 실패

environment:
  - DISK_TYPE=NETWORK

메타데이터 수집 안 됨

  • Settings → Metadata Providers 확인
  • 네트워크 연결 확인
  • API 키 필요한 경우 (Goodreads 등)

데이터베이스 연결 실패

# MariaDB 상태 확인
docker compose logs mariadb

# healthcheck 확인
docker compose ps

이미지 태그

태그설명
latest최신 안정 버전
v1.x.x특정 버전

활용 사례

1. 개인 전자책 라이브러리

목적: 전자책 체계적 관리

  • 소설, 비소설, 기술서 라이브러리 분리
  • 자동 메타데이터로 깔끔한 정리
  • 내장 리더로 어디서든 읽기
  • 읽기 진행률 추적

2. KOReader + BookLore

목적: 이북 리더 연동

  • KOReader로 읽기
  • 진행률 자동 동기화
  • OPDS로 무선 다운로드
  • 여러 기기에서 이어 읽기

3. Kobo 전자책 관리

목적: Kobo 기기 활용

  • Kobo와 라이브러리 동기화
  • EPUB → KEPUB 자동 변환
  • 표지/메타데이터 전송
  • Kobo 내장 리더 진행률 동기화

4. 가족 라이브러리

목적: 가족 공유

  • 멀티 유저 계정
  • 라이브러리별 권한
  • 개인 책장, 읽기 진행
  • 아이들 콘텐츠 분리

5. 만화/코믹스 + 전자책

목적: 통합 라이브러리

  • EPUB, PDF, CBZ 모두 지원
  • 시리즈 자동 그룹화
  • Magic Shelf로 미완 시리즈 추적
  • Komga 앱 (Mihon) 연결

마무리

BookLore는 전자책 라이브러리의 새로운 표준입니다. Calibre의 복잡함 없이, 현대적인 UI와 강력한 기능으로 전자책을 관리할 수 있습니다.

핵심 장점

장점설명
현대적 UI2025년에 걸맞은 깔끔한 인터페이스
자동 메타데이터Google, Amazon, Goodreads 연동
Kobo/KOReader이북 리더 양방향 동기화
OPDS모든 리딩 앱 연결
Magic Shelves스마트 자동 컬렉션
BookDrop드래그 앤 드롭 가져오기
내장 리더EPUB/PDF/CBZ 브라우저 읽기
멀티 유저가족/팀 공유

이런 분께 추천

전자책을 체계적으로 관리하고 싶은 분
Calibre UI가 마음에 안 드는 분
Kobo나 KOReader를 사용하는 분
어디서든 전자책에 접근하고 싶은 분
가족과 전자책을 공유하고 싶은 분
"전자책용 Jellyfin"을 찾는 분



댓글 남기기