ebook2audiobook Docker & Self-Hosted Deployment

GitHub

Generate audiobooks from e-books, voice cloning & 1158+ languages!

19,653 stars Python Python 1 file ยท ~4,830 tokens #audiobook#audiobooks#chinese#colab-notebook#docker#english#epub#gradio
RAW Compose
1. Pull Image (DOCKERHUB) docker pull athomasson2/ebook2audiobook
2. Docker Run (1-Click Launch) docker run -d --name ebook2audiobook -p 7860:7860 --restart always athomasson2/ebook2audiobook:${DEVICE_TAG:-cpu}
3. Podman Run podman run -d --name ebook2audiobook -p 7860:7860 --restart always athomasson2/ebook2audiobook:${DEVICE_TAG:-cpu}
4. Skopeo Inspect (Zero-Pull Manifest) skopeo inspect docker://docker.io/athomasson2/ebook2audiobook:${DEVICE_TAG
5. ORAS Pull (OCI Artifact) oras pull athomasson2/ebook2audiobook:${DEVICE_TAG:-cpu}
6. Compose Deployment docker compose up -d
docker-compose.yml
Download .yml
# docker-compose.yml โ€” universal across cpu / cuda / rocm / xpu (+ jetson),
# on both amd64 and arm64. Pick the accelerator with --profile.
#
# LOCAL BUILD ONLY โ€” the app image is never pulled from a registry:
# `pull_policy: never` means `up` uses the local image or fails loudly. The
# image is produced by ebook2audiobook.command --script_mode build_docker
# (DOCKER_MODE=compose runs `docker compose build` against the build: block
# below). Only the FROM base (python:<ver>-slim-trixie) is fetched remotely.
#
# The build context is the WHOLE repo, not just the Dockerfile: the Dockerfile
# does `COPY . /app` and then runs
#   ./ebook2audiobook.command --script_mode build_docker --docker_device "$DOCKER_DEVICE_STR"
# so this file only works from the root of a full checkout, never from a
# directory holding a lone downloaded Dockerfile.
#
#   docker compose                       --profile cpu    up
#   DEVICE_TAG=cu130    docker compose   --profile cuda   up
#   DEVICE_TAG=jetson51 docker compose   --profile jetson up
#   DEVICE_TAG=rocm     docker compose   --profile rocm   up
#   (add HSA_OVERRIDE_GFX_VERSION=x.y.z in front when the launcher printed one)
#   DEVICE_TAG=xpu      docker compose   --profile xpu    up
#
# Requires Compose V2 (the `docker compose` plugin), NOT the legacy
# `docker-compose` v1 โ€” only V2 honors deploy.resources.devices outside Swarm
# and `pull_policy`. Do NOT use `pull_policy: build` here: it re-builds on
# every `up`, and `COPY . /app` invalidates the cache for the expensive
# build_docker layer on any source change.
#
# Architecture (amd64 vs arm64) is NOT a profile: it is the host you build on
# plus the matching DEVICE_TAG. There is deliberately no `platform:` key here โ€”
# a hardcoded linux/amd64 default would silently drag a local build through
# qemu on the Jetson. Export DOCKER_DEFAULT_PLATFORM yourself (needs buildx +
# binfmt) if you really want to cross-build.
#
# Confirm a profile expands (and that extends merged) before running it:
#   DEVICE_TAG=rocm docker compose --profile rocm config

services:
  # --- shared base: exists only for extends, never runs (dummy _base profile)
  ebook2audiobook-base:
    image: athomasson2/ebook2audiobook:${DEVICE_TAG:-cpu}
    pull_policy: never
    build:
      context: .
      dockerfile: Dockerfile
      args:
        APP_VERSION: ${APP_VERSION:-26.10.1}
        DEVICE_TAG: ${DEVICE_TAG:-cpu}
        # A null value means "resolve from the environment at build time, and
        # if unset leave the Dockerfile default alone". These are exactly the
        # vars build_docker_image() in ebook2audiobook.command exports. Without
        # them the Dockerfile keeps its own defaults โ€” DOCKER_DEVICE_STR is
        # cuda/cu130/x86_64 โ€” so a --profile cpu build would still resolve the
        # cuda wheel set.
        PYTHON_VERSION:
        DOCKER_DEVICE_STR:
        DOCKER_PROGRAMS_STR:
        CALIBRE_INSTALLER_URL:
        ISO3_LANG:
        INSTALL_RUST:
    working_dir: /app
    entrypoint: ["bash", "ebook2audiobook.command", "--script_mode", "full_docker"]
    tty: true
    stdin_open: true
    ports:
      - "7860:7860"
    volumes:
      - ./ebooks:/app/ebooks:rw
      - ./audiobooks:/app/audiobooks:rw
      - ./models:/app/models:rw
      - ./voices:/app/voices:rw
      - ./tmp:/app/tmp:rw
    restart: unless-stopped
    profiles: [_base]

  # --- CPU: no device wiring at all -----------------------------------------
  ebook2audiobook-cpu:
    extends:
      service: ebook2audiobook-base
    profiles: [cpu]

  # --- NVIDIA discrete (amd64 dGPU, or arm64 SBSA) --------------------------
  # Needs the nvidia-container-toolkit installed on the host.
  ebook2audiobook-cuda:
    extends:
      service: ebook2audiobook-base
    profiles: [cuda]
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  # --- NVIDIA Jetson / Tegra (arm64 L4T) ------------------------------------
  # Uses the nvidia runtime (set "default-runtime": "nvidia" in
  # /etc/docker/daemon.json, or rely on this runtime: line). The deploy.devices
  # path above does NOT work on Tegra โ€” Jetson goes through the runtime.
  ebook2audiobook-jetson:
    extends:
      service: ebook2audiobook-base
    profiles: [jetson]
    runtime: nvidia
    environment:
      NVIDIA_VISIBLE_DEVICES: all
      NVIDIA_DRIVER_CAPABILITIES: all
    group_add:
      - video

  # --- AMD ROCm -------------------------------------------------------------
  ebook2audiobook-rocm:
    extends:
      service: ebook2audiobook-base
    profiles: [rocm]
    environment:
      # Set by the launcher's run hint when the host needs a gfx override
      # (e.g. HSA_OVERRIDE_GFX_VERSION=10.3.0 for gfx1031/gfx1032). Empty default
      # rather than a bare null: some podman-compose versions render null as
      # NAME=None, and ROCr treats an empty value exactly like an unset one.
      HSA_OVERRIDE_GFX_VERSION: ${HSA_OVERRIDE_GFX_VERSION:-}
    devices:
      - /dev/kfd
      - /dev/dri
    group_add:
      - video
      - "${RENDER_GID:-44}"

  # --- Intel XPU (oneAPI / IPEX) --------------------------------------------
  ebook2audiobook-xpu:
    extends:
      service: ebook2audiobook-base
    profiles: [xpu]
    devices:
      - /dev/dri
    group_add:
      - "${RENDER_GID:-44}"