SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-27

在 VPS 上自架 Chaptarr 管理有聲書與電子書

Readarr 已於 2025 年停止維護。本指南以 Compose 部署 Chaptarr,設定 PUID、PGID,並說明中繼資料失效與有聲書整理方式。

Chaptarr 是什麼,以及 Readarr 使用者為何需要它

Chaptarr 是 Readarr 的分支,可在單一執行個體中管理有聲書與電子書。它會監控新版本,將檔案傳送至下載用戶端,接著重新命名下載結果,並整理至媒體庫。它不會播放任何內容,因此需搭配 Audiobookshelf 等播放器使用。

Readarr 已於 27 June 2025 停止維護。Servarr 團隊發布的公告說明了原因:專案的中繼資料已無法使用,而社群遷移至 Open Library 的工作也陷入停滯。該儲存庫已封存。這使書籍與有聲書收藏失去受維護的管理工具,而 Chaptarr 接手了這項工作。它保留了你在 Sonarr 與 Radarr 中熟悉的架構(索引器、下載用戶端、品質設定檔、根目錄),並加入有聲書處理功能:依講述者整理、管理同一標題的多個版本、支援 M4B 與分章 MP3,以及將 MP3 轉換為 M4B。

本教學使用的映像標籤為 chaptarr/chaptarr:0.9.925,這是 9 August 2026 的最新版本。Chaptarr 將自己定位為 beta 軟體。在將它指向無法替換的媒體庫之前,請先閱讀文末附近的維護章節。

開始前的準備

一台已執行 Docker 與 Compose plugin 的 VPS,以及足夠存放媒體庫的磁碟空間。有聲書通常很大;如果匯入程序無法使用 hard link,檔案會暫時保留兩份,下面的 volume 章節會說明這點。如果 VPS 尚未安裝 Docker,請先參閱 在 VPS 上安裝並執行 Docker,完成後再回來。

Chaptarr 目前僅提供 Docker image。原生 Windows build 已列入開發中,且沒有 distribution package。容器預設會在 /config 使用 SQLite 儲存資料庫;如果你已經執行 PostgreSQL server,也可以透過 Chaptarr__Postgres__* environment variables 使用外部 PostgreSQL server。單一使用者在單一主機上的情況,SQLite 是適合的選擇。

Compose 服務:Chaptarr

此服務可直接加入現有的堆疊。設定會固定使用已發布的標籤,只在 loopback 發布 Web UI,並加入下載用戶端目前使用的網路。

services:
  chaptarr:
    image: chaptarr/chaptarr:0.9.925
    container_name: chaptarr
    environment:
      - PUID=1000
      - PGID=1000
      - UMASK=002
      - TZ=Europe/Berlin
    volumes:
      - ./config:/config
      - /srv/media/audiobooks:/audiobooks
      - /srv/media/ebooks:/ebooks
      - /srv/media/downloads:/downloads
    ports:
      - 127.0.0.1:8789:8789
    restart: unless-stopped
    networks:
      - arr

networks:
  arr:
    external: true

external: true 這一行表示「此網路已存在,將服務連接到該網路」。如果 Prowlarr 與 torrent client 來自不同的 Compose 專案,請使用這項設定;否則第二個 Compose 檔案會建立自己的隔離網路,Chaptarr 將無法依名稱解析 qbittorrent。請從 docker network ls 取得實際名稱。如果您的堆疊原本就位於同一個檔案,請將 chaptarr: 服務加入該檔案,並刪除整個 networks: 區塊。更完整的配置方式請參閱 Docker Compose 下的完整 arr 堆疊,命名規則請參閱 Compose 網路與服務名稱的解析方式

請自行建立設定目錄,然後啟動服務。

mkdir -p ./config
sudo chown 1000:1000 ./config
docker compose up -d
docker compose ps
docker compose logs -f chaptarr

docker compose ps 應顯示容器狀態為 Up。如果容器顯示為 Restarting,表示啟動失敗並正在重試;原因幾乎總是設定目錄造成的。應用程式開始監聽 8789 埠後,日誌就會停止持續捲動。

PUID、PGID,以及 Docker 以 root 建立的目錄

Chaptarr 在未設定時,預設使用 PUID=99PGID=100。這些是 unRAID 的值;在一般的 Ubuntu VPS 上,這些值通常對應不到可用的使用者,因此檔案會由你的登入帳號無法寫入的擁有者持有。使用 id -uid -g 讀取你自己的數值,並將它們填入檔案。

所有存取同一批檔案的容器都需要使用相同的一組值。下載用戶端會寫入 /srv/media/downloads,Chaptarr 將檔案移至 /srv/media/audiobooks,播放器則從該處讀取。如果下載用戶端以 1000:1000 寫入,而 Chaptarr 以 99:100 執行,匯入會失敗,因為 Chaptarr 無法刪除或移動不屬於它的檔案。UMASK=002 會讓新檔案可由群組寫入;當多個容器共用同一個媒體群組時,這正是所需設定。完整對應方式請參閱 PUID 和 PGID 如何將容器使用者對應到主機檔案

README 警告了一個特定陷阱,值得再次說明。如果你執行 docker compose up 時,./config 不存在,Docker 會自動建立該目錄,並由 root:root 擁有。接著容器會以 UID 1000 執行,無法寫入自己的資料庫,因此會不斷結束並重新啟動。使用 ls -ln ./config 檢查;此指令會顯示數字形式的擁有者,而不是名稱。兩個 0 代表由 root 擁有。使用 sudo chown -R 1000:1000 ./config 修正後,再次啟動容器。

上方的配置會將 /audiobooks/ebooks/downloads 分別掛載為獨立的 bind mount,與專案本身的執行命令一致。這種配置容易理解,但有一項實際代價:hardlink 會失效。

hardlink 是磁碟上同一份資料的第二個名稱。不會占用額外空間,而且建立速度立即完成,因此 arr 系列通常偏好使用 hardlink,而不是複製。hardlink 只能在同一個檔案系統內運作。容器內的這些路徑是 3 個獨立的掛載點,因此即使主機上的路徑位於同一顆磁碟,kernel 仍會拒絕建立連結。請自行測試。

docker exec chaptarr sh -c 'touch /downloads/linktest && ln /downloads/linktest /audiobooks/linktest'

命令會失敗,錯誤訊息結尾為 Invalid cross-device link。這表示 kernel 拒絕跨掛載點建立連結,也是 Chaptarr 改為複製檔案的確切原因。複製結果正確,但速度較慢;在移除 torrent 前,有聲書會同時存在 2 份。只要仍在 seeding,就不會移除 torrent。之後請刪除 /srv/media/downloads/linktest

若要保留 hardlink,請改為掛載同一個父目錄:

    volumes:
      - ./config:/config
      - /srv/media:/data

接著將 Chaptarr 內的根資料夾設為 /data/audiobooks/data/ebooks,並讓下載用戶端使用相同的 /srv/media:/data 掛載,確保 2 個容器看到完全相同的路徑。先確認主機端位於同一個檔案系統:df -h /srv/media/downloads /srv/media/audiobooks 的 Filesystem 欄位對兩者必須顯示相同值。不同值表示位於不同磁碟,任何掛載配置都無法跨檔案系統建立 hardlink。這項配置與具名儲存空間之間的取捨,請參閱 媒體使用 bind mount 與具名 volume 的比較

不公開服務即可存取 Web UI

連接埠設定為 127.0.0.1 是有原因的。ufw deny 8789 無法保護已發布的 Docker 連接埠,因為 Docker 會將自己的 NAT(網路位址轉換)規則寫入核心先於 ufw 規則處理的 chain。因此,流量會先被轉送,根本不會套用你的規則。這種行為經常讓人誤判,詳情請參閱已發布的 Docker 連接埠為何會忽略 ufw 規則。綁定至 loopback 可完全避開這個問題。

從自己的電腦透過 SSH tunnel 存取 UI:

ssh -N -L 8789:127.0.0.1:8789 you@your-server

讓 tunnel 持續執行,然後在瀏覽器中開啟 http://127.0.0.1:8789。首次執行時設定驗證。完成這項設定後,才應考慮在前方加入 TLS(傳輸層安全性)反向代理。當你需要透過 tunnel 存取三或四個這類工具,且每個工具都使用不同密碼時,更整齊的做法是將代理放在自架的單一登入伺服器,例如 Authentik後方,讓一次登入涵蓋所有應用程式,撤銷一次即可全部停用。

連接 indexer 與下載用戶端

Chaptarr 支援標準的 arr indexer 與下載用戶端通訊協定,因此 Prowlarr 將 indexer 推送至 Chaptarr 的方式與 Sonarr 相同,常用的 torrent 與 usenet 用戶端也不需特殊處理即可連接。

有一項設定幾乎會讓所有人遇到問題。Chaptarr 要求輸入下載用戶端主機時,不要填入 localhost127.0.0.1。在容器內,該位址指向容器本身,因此 Chaptarr 會嘗試連接自己的 8080 埠,並回報無法連線。請改用容器名稱 qbittorrent,並指定連接埠 8080。使用 docker network inspect arr 確認兩個容器位於同一個 network;此指令會依名稱列出所有已連接的容器。

如果下載用戶端透過 VPN 容器搭配 network_mode: "service:gluetun" 執行,則它在 network 上沒有自己的名稱,因為它共用 Gluetun 的 network namespace。請使用 Gluetun 對外提供的連接埠,並將主機設為 gluetun。相關配置與對應的路由方式,請參閱透過 Gluetun 將下載用戶端經由路由轉送

Readarr 中斷後的影響:實際遷移成本

Chaptarr 不相容於 Readarr 的 metadata source。它會透過自有流程,從多個 provider 解析標題、作者與版本,因此 Readarr 儲存的識別碼在這裡沒有作用。這裡沒有 database import,也沒有可直接套用的升級路徑。

對現有 library 而言,這表示檔案安全,但設定不會保留。這個流程不會碰觸磁碟上現有的內容。你需要新增 root folder、執行 library import,讓 Chaptarr 依照自有 metadata 比對找到的檔案。以下項目必須手動重建:quality profile、命名格式、indexer 與 client 設定,以及 Chaptarr 判斷錯誤的每個比對結果。大型 library 需要手動修正,因此應預留一個晚上的時間,不要只估計十分鐘。

請依照以下順序操作。停止 Readarr container,但保留其 config volume,這樣在重新輸入設定時仍可查閱舊設定。先讓 Chaptarr 指向一個較小的資料夾,確認比對結果後,再匯入全部內容。確認結果符合預期後,才移除舊的 container。

在掃描整個 library 前,還有一項值得了解的隱私細節:metadata lookup 會傳送至 api2.chaptarr.com。README 表示,這些請求可能包含 provider ID、搜尋文字、媒體類型、標籤與檔名,但不包含完整路徑、使用者身分或 credentials。檔名會離開你的伺服器。這是 metadata service 的正常運作方式,但你仍應先刻意決定是否接受。

將有聲書交給播放器

Chaptarr 負責整理檔案。播放檔案是其他程式的工作,而 Audiobookshelf 通常是搭配使用的選擇,因為它能跨裝置追蹤聆聽位置,也提供手機應用程式。其官方映像檔為 ghcr.io/advplyr/audiobookshelf:latest,官方記載的 Compose 範例會將主機的 13378 埠發布至容器的 80 埠。

  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    container_name: audiobookshelf
    ports:
      - 127.0.0.1:13378:80
    volumes:
      - ./abs/config:/config
      - ./abs/metadata:/metadata
      - /srv/media/audiobooks:/audiobooks
    environment:
      - TZ=Europe/Berlin
    restart: unless-stopped

掛載 Chaptarr 寫入檔案的相同主機路徑,然後在 Web UI 中將 /audiobooks 新增為媒體庫。下一次掃描後,就會出現新的匯入內容。

如果你已經執行 Jellyfin,可以在其中將該資料夾新增為媒體庫,Jellyfin 便能播放檔案。不過,對於單一長篇有聲書檔案,其繼續播放位置的處理能力不如專用的有聲書伺服器。相關設定請參閱在 VPS 上將 Jellyfin 用作媒體伺服器。至於電子書部分,請將 /srv/media/ebooks 交給閱讀應用程式;檔案完成命名與歸檔後,Chaptarr 的工作就結束了。

維護風險:授權條款、runtime 與快速變動的 tag

Chaptarr 採用 GPL-3.0 授權,著作權歸 Chaptarr 貢獻者所有,部分程式碼則來自 Servarr 團隊。因此,只要這位維護者停止維護,程式碼仍會保持開放,任何人都能再次建立 fork。截至 August 2026,該專案建置於 .NET 10,也就是目前的 long term support runtime 版本。這表示其基礎支援週期以年計,而不是以月計。如果你要評估這個專案明年是否仍會存在,這兩點都很重要。

版本號變動很快。Release 會以 pre-release 形式發布,而 0.9.925 就在本教學發布當天推出。請固定使用確切的 tag。使用 latest 代表無人值守的 docker compose pull 可能在一週內將版本更新數個版本;此外,這個 fork 的歷史很短,不同 release 之間可能變更 API,導致你針對它撰寫的 script 或 dashboard 無法運作。

每次升級前先備份,並且只在確認後執行升級。

docker compose stop chaptarr
sudo tar czf chaptarr-config-backup.tgz ./config
docker compose start chaptarr
docker compose pull chaptarr
docker compose up -d chaptarr

專案回報在約六個月、超過 11,000 名使用者的期間內沒有資料遺失事件,但仍建議保留備份,且不要將其指向無法承受遺失的資料庫。這兩點都必須確實遵守。將設定檔壓縮檔複製到伺服器外部,因為備份與受保護資料位於同一個磁碟上時,不能算是真正的備份。只有在 Chaptarr 將狀態儲存在 /config 下的單一 SQLite 檔案中時,這個 tarball 才足夠;任何位於獨立資料庫伺服器上的資料,也必須一併匯出資料庫。在 VPS 上自行代管 Chatwoot 並搭配其 Postgres 資料與上傳檔案時,備份步驟就是採用這種形式。

故障模式與實際顯示的字串

容器不斷重新啟動。 docker compose ps 顯示 Restarting。執行 ls -ln ./config。擁有者欄位中的兩個 0 表示 Docker 以 root 建立了該目錄,因此容器使用者無法寫入資料庫。執行 sudo chown -R 1000:1000 ./config

匯入永遠無法完成,檔案仍留在下載目錄。 Chaptarr 可以讀取下載檔案,但無法寫入媒體庫。將 ls -ln /srv/media/audiobooks 與你的 PUIDPGID 進行比較。若目錄由不同的 UID 擁有,或由你的群組擁有但沒有群組寫入權限,檔案就無法移動。UMASK=002 可讓新檔案避免第二種情況。

每次匯入後磁碟使用量都增加一倍。 系統沒有建立 hardlink,因此檔案被複製了。執行 volumes 章節中的 ln 測試。若錯誤以 Invalid cross-device link 結尾,即可確認此問題;使用單一父層掛載即可修正。

下載用戶端無法連線。 你將 localhost 設為主機名稱。在容器內,這代表 Chaptarr 本身。改用容器名稱,並確認 docker network inspect arr 列出這兩個容器。

Compose 拒絕啟動服務。 Bind for 127.0.0.1:8789 failed: port is already allocated 表示該連接埠已由其他程式使用。使用 sudo ss -lntp | grep 8789 找出佔用者。

瀏覽器完全沒有顯示內容。 當連接埠繫結至 127.0.0.1 時,筆記型電腦無法透過網際網路連線到該服務。這是預期行為。請先開啟 SSH tunnel。

FAQ

我可以將 Readarr 媒體庫遷移到 Chaptarr 嗎?

不能直接匯入。Chaptarr 不相容於 Readarr 的中繼資料來源,並使用自己的提供者管線,因此 Readarr 儲存的識別碼沒有意義,也沒有資料庫轉換工具。磁碟上的檔案不會受到影響。將相同路徑新增為根資料夾,執行媒體庫匯入,讓 Chaptarr 自行比對檔案即可。品質設定檔、命名格式、索引器設定及錯誤比對都必須手動處理,因此請先使用一個小資料夾測試,再匯入全部內容。

為什麼 Chaptarr 無法寫入我的有聲書資料夾?

容器使用者不是檔案的擁有者。當這些變數未設定時,Chaptarr 會退回使用 PUID=99PGID=100;這是 unRAID 的值,在一般 Ubuntu VPS 上並不正確。請將它們設為自己的 id -uid -g,並在下載用戶端使用相同的一組值;同時設定 UMASK=002,讓新檔案維持群組可寫入。請在媒體庫目錄上使用 ls -ln 檢查擁有權,因為它會輸出數字而不是名稱,便於比對。

為什麼匯入後磁碟使用量增加一倍?

Chaptarr 無法建立硬連結,因此複製了檔案。將 /downloads/audiobooks 分別作為獨立 bind mount,會使它們在容器內成為不同的掛載點;核心會以 Invalid cross-device link 拒絕跨掛載點建立硬連結。請掛載單一父目錄,例如 /srv/media:/data,再在應用程式內使用 /data/downloads/data/audiobooks。兩個路徑也必須位於同一個主機檔案系統上,可透過 df -h 確認。

Chaptarr 可以播放我的有聲書嗎?

不能。它負責尋找、下載、重新命名及整理檔案,播放則由其他程式處理。Audiobookshelf 是常見的搭配方案,因為它能跨裝置記住播放位置;請使用官方映像 ghcr.io/advplyr/audiobookshelf:latest,並掛載相同的主機有聲書路徑。Jellyfin 也能在將該資料夾新增為媒體庫後播放檔案,但對於單一檔案很長的有聲書,續播功能較弱。

在重要的媒體庫上執行 Chaptarr 安全嗎?

Chaptarr 是年輕分支推出的 beta 軟體,專案本身也明確說明這點;但專案回報約六個月內、超過 eleven thousand 名使用者未發生資料遺失事件。較令人放心的部分包括 GPL-3.0 授權,這讓程式碼可以持續分支,以及 .NET 10 基礎映像;截至 August 2026,.NET 10 是長期支援執行階段。請固定使用確切的映像標籤,例如 0.9.925,不要使用 latest;每次升級前備份 /config,並將該封存檔存放在伺服器之外。