# 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:-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}"