Skip to content

Calibre-Web

Description / nameInput element
Your domain name

Overview

Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database.


Info

Calibre and Calibre-web do NOT need to be on the same server. But you do need to have a local copy of the Calibre metadata.db and a path to the books for calibre-web to operate.

Deployment

sb install sandbox-calibre-web

Usage

Visit https://calibre-web.iYOUR_DOMAIN_NAMEi.

Basics

  • Default admin login:
Username: admin
Password: admin123

Change the default log in details immediately.

  • Unrar is included by default and needs to be set in the Calibre-Web admin page (Basic Configuration:External Binaries) with a path of /usr/bin/unrar.

  • Automatic ebook conversion via Calibre converter is included. Enable it in the Calibre-Web admin page (Basic Configuration:External Binaries) by setting the Path to Calibre E-Book Converter to /usr/bin/ebook-convert.

  • The kepubify ebook conversion tool (MIT License) to convert epub to kepub is included. In the Calibre-Web admin page (Basic Configuration:External Binaries) set the Path to Kepubify E-Book Converter to /usr/bin/kepubify.

  • Book cover thumbnails will improve browsing speed but they aren't generated by default. Enable them on the Calibre-Web admin page by either schedule a task (Edit Scheduled Task Settings) or running it manually (Refresh Thumbnail Cover Cache).

Useful docker commands

Shell access whilst the container is running:
docker exec -it calibre-web /bin/bash
To monitor the logs of the container in realtime:
docker logs -f calibre-web
Container version number:
docker inspect -f '{{ index .Config.Labels "build_version" }}' calibre-web
Image version number:
docker inspect -f '{{ index .Config.Labels "build_version" }}' linuxserver/calibre-web

SK's Calibre-Web Usage Tips

SMTP Email Server Setup

A useful function of Calibre-Web is sending ebooks by email. Therefore, you need to set up SMTP e-mail server settings.

I am using Google to host the email for my domain name. In my case, after trial and error, I found it most reliable to go into my Google control panel, go to the SMTP settings, and whitelist my server’s IP address without authentication. Now, I can send email from any Saltbox app that supports it (Ombi, Tautelli, Organizr, and Calibre-Web) with no troubles. These settings can be found under Apps > Google Workspace > Settings for Gmail > Routing and the setting you need to add or change is SMTP relay service. or just search SMTP in the search bar at the top of the Google admin console, and find SMTP relay service from there.

Hostname: smtp-relay.gmail.com, Port:  25,  SSL: No
Kindle Setup

There is a nice benefit to using a Kindle. When you send a “personal document” (book) to your Kindle account, it will automatically download to the specific device tied to the email address you use. Even though it’s called a document, it goes into your regular library and looks just like any book you may have purchased, including the cover. In addition, that book is available on any other device or app tied to your account, so you can read the same book on your phone, a Kindle Paperwhite, and an iPad. Amazon’s WhisperSync feature will bookmark your most recent page in the background, so if you switch devices it will ask if you want to update to the most recent page read.

If you (or your users) want to have books sent directly to a Kindle from Calibre-Web email, then there are additional one-time setup steps for each user.

  • Tell Amazon to accept books sent from your website
  • Go to
  • On the top navigation bar, go to Account & Lists. In the dropdown, click on Your Content and Devices.
  • Towards the top of the white section, in the middle, click on Preferences
  • Scroll down to Personal Document Settings. Click the title to open up that section of the page.
  • Under Approved Personal Document E-mail List, click the link for "Add a new approved e-mail address"
  • In the popup, add @yourdomain.tld and save. Done!

    Before closing the website, you might want to grab your device email address for the next step. Under the Send-to-Kindle E-Mail Settings, copy the email address where you want the books sent by default.

  • Add your Kindle email address to your profile on books.yourdomain.tld

  • Once logged in, on the top ride side, click your name to open your profile
  • Add your kindle email address and save
  • Your Kindle email address will be something like name_79@kindle.com. Every Kindle device and mobile app has its own unique address, however, you can send to any of your devices and it will still be available on all of them. You can find this email address either in the Settings of the device/app, or copy it from the Devices page

Info

Kindle has started sending verification emails on every document sent if your Kindle's email is the one they generated for you. While you are on your settings page, go ahead and make up a new Kindle email address.

Enjoy!

Advanced Method of Library Storage

Since only the metadata.db file has to be local, you can keep the metadata.db file in /mnt/local/Media/Books as RW and the actual book files in teamdrive:Books as RO and mergerfs them together. Use the latest rclone --vfs-cache-mode=full and related cloud-seeding settings for your teamdrive mount so that it does not get laggy. Have a script that copies the metadata.db file regularly to the local disk, and leave the books in the cloud.

If this paragraph does not make sense to you, then please do not try it.

Role Defaults

Use the Inventory to customize variables. (1)

  1. Example override

    calibre_web_name: "custom_value"
    

    Avoid overriding variables ending in _default

    When overriding variables that end in _default (like calibre_web_docker_envs_default), you replace the entire default configuration. Future updates that add new default values will not be applied to your setup, potentially breaking functionality.

    Instead, use the corresponding _custom variable (like calibre_web_docker_envs_custom) to add your changes. Custom values are merged with defaults, ensuring you receive updates.

calibre_web_name
# Type: string
calibre_web_name: calibre-web
calibre_web_role_web_subdomain
# Type: string
calibre_web_role_web_subdomain: "{{ calibre_web_name }}"
calibre_web_role_web_domain
# Type: string
calibre_web_role_web_domain: "{{ user.domain }}"
calibre_web_role_web_port
# Type: string
calibre_web_role_web_port: "8083"
calibre_web_role_web_url
# Type: string
calibre_web_role_web_url: "{{ 'https://' + (lookup('role_var', '_web_subdomain', role='calibre_web') + '.' + lookup('role_var', '_web_domain', role='calibre_web')
                           if (lookup('role_var', '_web_subdomain', role='calibre_web') | length > 0)
                           else lookup('role_var', '_web_domain', role='calibre_web')) }}"
calibre_web_role_dns_record
# Type: string
calibre_web_role_dns_record: "{{ lookup('role_var', '_web_subdomain', role='calibre_web') }}"
calibre_web_role_dns_zone
# Type: string
calibre_web_role_dns_zone: "{{ lookup('role_var', '_web_domain', role='calibre_web') }}"
calibre_web_role_dns_proxy
# Type: bool (true/false)
calibre_web_role_dns_proxy: "{{ dns_proxied }}"
calibre_web_role_traefik_sso_middleware
# Type: string
calibre_web_role_traefik_sso_middleware: ""
calibre_web_role_traefik_middleware_default
# Type: string
calibre_web_role_traefik_middleware_default: "{{ traefik_default_middleware }},kobo-sync-headers"
calibre_web_role_traefik_middleware_custom
# Type: string
calibre_web_role_traefik_middleware_custom: ""
calibre_web_role_traefik_certresolver
# Type: string
calibre_web_role_traefik_certresolver: "{{ traefik_default_certresolver }}"
calibre_web_role_traefik_enabled
# Type: bool (true/false)
calibre_web_role_traefik_enabled: true
calibre_web_role_themepark_enabled
# Options can be found at https://github.com/themepark-dev/theme.park
# Type: bool (true/false)
calibre_web_role_themepark_enabled: false
calibre_web_role_themepark_theme
# Type: string
calibre_web_role_themepark_theme: "{{ global_themepark_theme }}"
calibre_web_role_themepark_domain
# Type: string
calibre_web_role_themepark_domain: "{{ global_themepark_domain }}"

Container

calibre_web_role_docker_container
# Type: string
calibre_web_role_docker_container: "{{ calibre_web_name }}"

Image

calibre_web_role_docker_image_pull
# Type: bool (true/false)
calibre_web_role_docker_image_pull: true
calibre_web_role_docker_image_repo
# Type: string
calibre_web_role_docker_image_repo: "lscr.io/linuxserver/calibre-web"
calibre_web_role_docker_image_tag
# Type: string
calibre_web_role_docker_image_tag: "latest"
calibre_web_role_docker_image
# Type: string
calibre_web_role_docker_image: "{{ lookup('role_var', '_docker_image_repo', role='calibre_web') }}:{{ lookup('role_var', '_docker_image_tag', role='calibre_web') }}"

Envs

calibre_web_role_docker_envs_default
# Type: dict
calibre_web_role_docker_envs_default:
  PUID: "{{ uid }}"
  PGID: "{{ gid }}"
  TZ: "{{ tz }}"
  CACHE_DIR: "/cache/"
  USE_CONFIG_DIR: "true"
  DOCKER_MODS: linuxserver/mods:universal-calibre
calibre_web_role_docker_envs_theme
# Type: dict
calibre_web_role_docker_envs_theme:
  DOCKER_MODS: "linuxserver/mods:universal-calibre|ghcr.io/themepark-dev/theme.park:calibre-web"
  TP_DOMAIN: "{{ lookup('role_var', '_themepark_domain', role='calibre_web') }}"
  TP_THEME: "{{ lookup('role_var', '_themepark_theme', role='calibre_web') }}"
calibre_web_role_docker_envs_custom
# Type: dict
calibre_web_role_docker_envs_custom: {}

Volumes

calibre_web_role_docker_volumes_default
# Type: list
calibre_web_role_docker_volumes_default:
  - "{{ lookup('role_var', '_paths_location', role='calibre_web') }}:/calibre-web"
  - "{{ lookup('role_var', '_paths_location', role='calibre_web') }}/config:/config"
  - "{{ lookup('role_var', '_paths_location', role='calibre_web') }}/cache:/cache"
  - "/mnt/unionfs/Media/Books:/books"
calibre_web_role_docker_volumes_custom
# Type: list
calibre_web_role_docker_volumes_custom: []

Labels

calibre_web_role_docker_labels_default
# Type: dict
calibre_web_role_docker_labels_default:
  traefik.http.middlewares.kobo-sync-headers.headers.customrequestheaders.X-Scheme: "https"
calibre_web_role_docker_labels_custom
# Type: dict
calibre_web_role_docker_labels_custom: {}

Hostname

calibre_web_role_docker_hostname
# Type: string
calibre_web_role_docker_hostname: "{{ calibre_web_name }}"

Networks

calibre_web_role_docker_networks_alias
# Type: string
calibre_web_role_docker_networks_alias: "{{ calibre_web_name }}"
calibre_web_role_docker_networks_default
# Type: list
calibre_web_role_docker_networks_default: []
calibre_web_role_docker_networks_custom
# Type: list
calibre_web_role_docker_networks_custom: []

Restart Policy

calibre_web_role_docker_restart_policy
# Type: string
calibre_web_role_docker_restart_policy: unless-stopped

State

calibre_web_role_docker_state
# Type: string
calibre_web_role_docker_state: started

The following advanced options are available via create_docker_container but are not defined in the role. See: docker_container module

Resource Limits

calibre_web_role_docker_blkio_weight
# Type: int
calibre_web_role_docker_blkio_weight:
calibre_web_role_docker_cpu_period
# Type: int
calibre_web_role_docker_cpu_period:
calibre_web_role_docker_cpu_quota
# Type: int
calibre_web_role_docker_cpu_quota:
calibre_web_role_docker_cpu_shares
# Type: int
calibre_web_role_docker_cpu_shares:
calibre_web_role_docker_cpus
# Type: string
calibre_web_role_docker_cpus:
calibre_web_role_docker_cpuset_cpus
# Type: string
calibre_web_role_docker_cpuset_cpus:
calibre_web_role_docker_cpuset_mems
# Type: string
calibre_web_role_docker_cpuset_mems:
calibre_web_role_docker_kernel_memory
# Type: string
calibre_web_role_docker_kernel_memory:
calibre_web_role_docker_memory
# Type: string
calibre_web_role_docker_memory:
calibre_web_role_docker_memory_reservation
# Type: string
calibre_web_role_docker_memory_reservation:
calibre_web_role_docker_memory_swap
# Type: string
calibre_web_role_docker_memory_swap:
calibre_web_role_docker_memory_swappiness
# Type: int
calibre_web_role_docker_memory_swappiness:
calibre_web_role_docker_shm_size
# Type: string
calibre_web_role_docker_shm_size:

Security & Devices

calibre_web_role_docker_cap_drop
# Type: list
calibre_web_role_docker_cap_drop:
calibre_web_role_docker_cgroupns_mode
# Type: string
calibre_web_role_docker_cgroupns_mode:
calibre_web_role_docker_device_cgroup_rules
# Type: list
calibre_web_role_docker_device_cgroup_rules:
calibre_web_role_docker_device_read_bps
# Type: list
calibre_web_role_docker_device_read_bps:
calibre_web_role_docker_device_read_iops
# Type: list
calibre_web_role_docker_device_read_iops:
calibre_web_role_docker_device_requests
# Type: list
calibre_web_role_docker_device_requests:
calibre_web_role_docker_device_write_bps
# Type: list
calibre_web_role_docker_device_write_bps:
calibre_web_role_docker_device_write_iops
# Type: list
calibre_web_role_docker_device_write_iops:
calibre_web_role_docker_devices
# Type: list
calibre_web_role_docker_devices:
calibre_web_role_docker_devices_default
# Type: string
calibre_web_role_docker_devices_default:
calibre_web_role_docker_groups
# Type: list
calibre_web_role_docker_groups:
calibre_web_role_docker_privileged
# Type: bool (true/false)
calibre_web_role_docker_privileged:
calibre_web_role_docker_security_opts
# Type: list
calibre_web_role_docker_security_opts:
calibre_web_role_docker_user
# Type: string
calibre_web_role_docker_user:
calibre_web_role_docker_userns_mode
# Type: string
calibre_web_role_docker_userns_mode:

Networking

calibre_web_role_docker_dns_opts
# Type: list
calibre_web_role_docker_dns_opts:
calibre_web_role_docker_dns_search_domains
# Type: list
calibre_web_role_docker_dns_search_domains:
calibre_web_role_docker_dns_servers
# Type: list
calibre_web_role_docker_dns_servers:
calibre_web_role_docker_domainname
# Type: string
calibre_web_role_docker_domainname:
calibre_web_role_docker_exposed_ports
# Type: list
calibre_web_role_docker_exposed_ports:
calibre_web_role_docker_hosts
# Type: dict
calibre_web_role_docker_hosts:
calibre_web_role_docker_hosts_use_common
# Type: bool (true/false)
calibre_web_role_docker_hosts_use_common:
calibre_web_role_docker_ipc_mode
# Type: string
calibre_web_role_docker_ipc_mode:
calibre_web_role_docker_links
# Type: list
calibre_web_role_docker_links:
calibre_web_role_docker_network_mode
# Type: string
calibre_web_role_docker_network_mode:
calibre_web_role_docker_pid_mode
# Type: string
calibre_web_role_docker_pid_mode:
calibre_web_role_docker_ports
# Type: list
calibre_web_role_docker_ports:
calibre_web_role_docker_uts
# Type: string
calibre_web_role_docker_uts:

Storage

calibre_web_role_docker_keep_volumes
# Type: bool (true/false)
calibre_web_role_docker_keep_volumes:
calibre_web_role_docker_mounts
# Type: list
calibre_web_role_docker_mounts:
calibre_web_role_docker_storage_opts
# Type: dict
calibre_web_role_docker_storage_opts:
calibre_web_role_docker_tmpfs
# Type: list
calibre_web_role_docker_tmpfs:
calibre_web_role_docker_volume_driver
# Type: string
calibre_web_role_docker_volume_driver:
calibre_web_role_docker_volumes_from
# Type: list
calibre_web_role_docker_volumes_from:
calibre_web_role_docker_volumes_global
# Type: bool (true/false)
calibre_web_role_docker_volumes_global:
calibre_web_role_docker_working_dir
# Type: string
calibre_web_role_docker_working_dir:

Monitoring & Lifecycle

calibre_web_role_docker_auto_remove
# Type: bool (true/false)
calibre_web_role_docker_auto_remove:
calibre_web_role_docker_cleanup
# Type: bool (true/false)
calibre_web_role_docker_cleanup:
calibre_web_role_docker_force_kill
# Type: string
calibre_web_role_docker_force_kill:
calibre_web_role_docker_healthcheck
# Type: dict
calibre_web_role_docker_healthcheck:
calibre_web_role_docker_healthy_wait_timeout
# Type: int
calibre_web_role_docker_healthy_wait_timeout:
calibre_web_role_docker_init
# Type: bool (true/false)
calibre_web_role_docker_init:
calibre_web_role_docker_kill_signal
# Type: string
calibre_web_role_docker_kill_signal:
calibre_web_role_docker_log_driver
# Type: string
calibre_web_role_docker_log_driver:
calibre_web_role_docker_log_options
# Type: dict
calibre_web_role_docker_log_options:
calibre_web_role_docker_oom_killer
# Type: bool (true/false)
calibre_web_role_docker_oom_killer:
calibre_web_role_docker_oom_score_adj
# Type: int
calibre_web_role_docker_oom_score_adj:
calibre_web_role_docker_output_logs
# Type: bool (true/false)
calibre_web_role_docker_output_logs:
calibre_web_role_docker_paused
# Type: bool (true/false)
calibre_web_role_docker_paused:
calibre_web_role_docker_recreate
# Type: bool (true/false)
calibre_web_role_docker_recreate:
calibre_web_role_docker_restart_retries
# Type: int
calibre_web_role_docker_restart_retries:
calibre_web_role_docker_stop_timeout
# Type: int
calibre_web_role_docker_stop_timeout:

Other Options

calibre_web_role_docker_capabilities
# Type: list
calibre_web_role_docker_capabilities:
calibre_web_role_docker_cgroup_parent
# Type: string
calibre_web_role_docker_cgroup_parent:
calibre_web_role_docker_commands
# Type: list
calibre_web_role_docker_commands:
calibre_web_role_docker_create_timeout
# Type: int
calibre_web_role_docker_create_timeout:
calibre_web_role_docker_entrypoint
# Type: string
calibre_web_role_docker_entrypoint:
calibre_web_role_docker_env_file
# Type: string
calibre_web_role_docker_env_file:
calibre_web_role_docker_labels_use_common
# Type: bool (true/false)
calibre_web_role_docker_labels_use_common:
calibre_web_role_docker_read_only
# Type: bool (true/false)
calibre_web_role_docker_read_only:
calibre_web_role_docker_runtime
# Type: string
calibre_web_role_docker_runtime:
calibre_web_role_docker_sysctls
# Type: list
calibre_web_role_docker_sysctls:
calibre_web_role_docker_ulimits
# Type: list
calibre_web_role_docker_ulimits:
calibre_web_role_autoheal_enabled
# Enable or disable Autoheal monitoring for the container created when deploying
# Type: bool (true/false)
calibre_web_role_autoheal_enabled: true
calibre_web_role_depends_on
# List of container dependencies that must be running before the container start
# Type: string
calibre_web_role_depends_on: ""
calibre_web_role_depends_on_delay
# Delay in seconds before starting the container after dependencies are ready
# Type: string (quoted number)
calibre_web_role_depends_on_delay: "0"
calibre_web_role_depends_on_healthchecks
# Enable healthcheck waiting for container dependencies
# Type: string ("true"/"false")
calibre_web_role_depends_on_healthchecks:
calibre_web_role_diun_enabled
# Enable or disable Diun update notifications for the container created when deploying
# Type: bool (true/false)
calibre_web_role_diun_enabled: true
calibre_web_role_dns_enabled
# Enable or disable automatic DNS record creation for the container
# Type: bool (true/false)
calibre_web_role_dns_enabled: true
calibre_web_role_docker_controller
# Enable or disable Saltbox Docker Controller management for the container
# Type: bool (true/false)
calibre_web_role_docker_controller: true
calibre_web_role_docker_image_repo
# Type: string
calibre_web_role_docker_image_repo:
calibre_web_role_docker_image_tag
# Type: string
calibre_web_role_docker_image_tag:
calibre_web_role_docker_volumes_download
# Type: bool (true/false)
calibre_web_role_docker_volumes_download:
calibre_web_role_paths_location
# Type: string
calibre_web_role_paths_location:
calibre_web_role_themepark_addons
# Type: string
calibre_web_role_themepark_addons:
calibre_web_role_themepark_app
# Type: string
calibre_web_role_themepark_app:
calibre_web_role_themepark_domain
# Type: string
calibre_web_role_themepark_domain:
calibre_web_role_themepark_theme
# Type: string
calibre_web_role_themepark_theme:
calibre_web_role_traefik_api_endpoint
# Type: dict/omit
calibre_web_role_traefik_api_endpoint:
calibre_web_role_traefik_api_middleware
# Type: string
calibre_web_role_traefik_api_middleware:
calibre_web_role_traefik_api_middleware_http
# Type: string
calibre_web_role_traefik_api_middleware_http:
calibre_web_role_traefik_autodetect_enabled
# Enable Traefik autodetect middleware for the container
# Type: bool (true/false)
calibre_web_role_traefik_autodetect_enabled: false
calibre_web_role_traefik_certresolver
# Type: string
calibre_web_role_traefik_certresolver:
calibre_web_role_traefik_crowdsec_enabled
# Enable CrowdSec middleware for the container
# Type: bool (true/false)
calibre_web_role_traefik_crowdsec_enabled: false
calibre_web_role_traefik_error_pages_enabled
# Enable custom error pages middleware for the container
# Type: bool (true/false)
calibre_web_role_traefik_error_pages_enabled: false
calibre_web_role_traefik_gzip_enabled
# Enable gzip compression middleware for the container
# Type: bool (true/false)
calibre_web_role_traefik_gzip_enabled: false
calibre_web_role_traefik_middleware_http
# Type: string
calibre_web_role_traefik_middleware_http:
calibre_web_role_traefik_middleware_http_api_insecure
# Type: bool (true/false)
calibre_web_role_traefik_middleware_http_api_insecure:
calibre_web_role_traefik_middleware_http_insecure
# Type: bool (true/false)
calibre_web_role_traefik_middleware_http_insecure:
calibre_web_role_traefik_priority
# Type: string
calibre_web_role_traefik_priority:
calibre_web_role_traefik_robot_enabled
# Enable robots.txt middleware for the container
# Type: bool (true/false)
calibre_web_role_traefik_robot_enabled: true
calibre_web_role_traefik_tailscale_enabled
# Enable Tailscale-specific Traefik configuration for the container
# Type: bool (true/false)
calibre_web_role_traefik_tailscale_enabled: false
calibre_web_role_traefik_wildcard_enabled
# Enable wildcard certificate for the container
# Type: bool (true/false)
calibre_web_role_traefik_wildcard_enabled: true
calibre_web_role_web_domain
# Type: string
calibre_web_role_web_domain:
calibre_web_role_web_fqdn_override
# Override the Traefik fully qualified domain name (FQDN) for the container
# Type: list
calibre_web_role_web_fqdn_override:

Example Override

calibre_web_role_web_fqdn_override:
  - "{{ traefik_host }}"
  - "calibre_web2.{{ user.domain }}"
  - "calibre_web.otherdomain.tld"

Note: Include {{ traefik_host }} to preserve the default FQDN alongside your custom entries

calibre_web_role_web_host_override
# Override the Traefik web host configuration for the container
# Type: string
calibre_web_role_web_host_override:

Example Override

calibre_web_role_web_host_override: "Host(`{{ traefik_host }}`) || Host(`{{ 'calibre_web2.' + user.domain }}`)"

Note: Use {{ traefik_host }} to include the default host configuration in your custom rule

calibre_web_role_web_http_port
# Type: string (quoted number)
calibre_web_role_web_http_port:
calibre_web_role_web_http_scheme
# Type: string ("http"/"https")
calibre_web_role_web_http_scheme:
calibre_web_role_web_http_serverstransport
# Type: dict/omit
calibre_web_role_web_http_serverstransport:
calibre_web_role_web_scheme
# URL scheme to use for web access to the container
# Type: string ("http"/"https")
calibre_web_role_web_scheme:
calibre_web_role_web_serverstransport
# Type: dict/omit
calibre_web_role_web_serverstransport:
calibre_web_role_web_subdomain
# Type: string
calibre_web_role_web_subdomain: