Tự host Chaptarr quản lý audiobook trên VPS
Readarr đã dừng ngày 27/6/2025. Dựng Chaptarr bằng Docker Compose, đặt đúng PUID và PGID, rồi xử lý lỗi metadata khi quản lý audiobook, ebook.
Chaptarr là gì và vì sao người dùng Readarr cần nó
Chaptarr là một fork của Readarr, dùng để quản lý audiobook và ebook trong một instance duy nhất. Nó theo dõi các bản phát hành mới, gửi chúng đến download client, sau đó đổi tên kết quả và sắp xếp chúng vào library. Chaptarr không phát nội dung, vì vậy bạn cần kết hợp nó với một player như Audiobookshelf.
Readarr đã ngừng hoạt động vào ngày 27 June 2025. Thông báo của chính nhóm Servarr nêu rõ lý do: metadata của dự án đã không còn sử dụng được, còn nỗ lực của cộng đồng để chuyển sang Open Library bị đình trệ. Repository đã được lưu trữ. Vì vậy, các bộ sưu tập ebook và audiobook không còn một trình quản lý được duy trì, và Chaptarr đã tiếp nhận công việc này. Nó giữ cách tổ chức mà bạn đã quen thuộc từ Sonarr và Radarr (indexer, download client, quality profile, root folder), đồng thời bổ sung khả năng xử lý audiobook: sắp xếp theo narrator, quản lý nhiều edition của cùng một tựa đề, hỗ trợ M4B và MP3 được chia theo chapter, và chuyển đổi MP3 sang M4B.
Hướng dẫn này sử dụng image tag chaptarr/chaptarr:0.9.925, là bản phát hành mới nhất vào ngày 9 August 2026. Tính đến ngày 11 October 2026, bản phát hành mới nhất là 0.9.965, được phát hành vào ngày 27 September 2026. Các bước bên dưới chỉ được kiểm thử trên 0.9.925, nên các file vẫn giữ tag đó; hãy đọc release note trước khi chuyển sang bản mới hơn. Chaptarr tự xác định là beta software. Hãy đọc phần bảo trì ở gần cuối trước khi trỏ nó vào một library mà bạn không thể thay thế.
Những gì cần chuẩn bị trước khi bắt đầu
Một VPS đang chạy Docker và Compose plugin, cùng đủ dung lượng đĩa cho thư viện. Audiobook thường có dung lượng lớn. Nếu quá trình import không thể dùng hardlink, hệ thống sẽ giữ 2 bản sao của một file trong một khoảng thời gian. Phần volume bên dưới giải thích vấn đề này. Nếu Docker chưa được cài trên máy, hãy bắt đầu với Cài đặt và chạy Docker trên VPS rồi quay lại.
Hiện tại, Chaptarr chỉ được phát hành dưới dạng Docker image. Native support đang trong quá trình phát triển, một bản build Windows thử nghiệm đã được lên kế hoạch, và không có distribution package. Container lưu database trong /config dưới dạng SQLite theo mặc định. Container cũng có thể dùng PostgreSQL server bên ngoài thông qua các biến môi trường Chaptarr__Postgres__* nếu bạn đã chạy sẵn một server như vậy. SQLite là lựa chọn phù hợp cho một người dùng trên một máy chủ.
Service Compose cho Chaptarr
Service này được thêm vào một stack hiện có. Cấu hình cố định theo một tag đã phát hành, chỉ publish web UI trên loopback và tham gia network mà download client của bạn đang dùng.
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: trueDòng external: true có nghĩa là “network này đã tồn tại, hãy kết nối service vào đó”. Dùng cấu hình này khi Prowlarr và torrent client nằm trong một Compose project khác, vì nếu không, file Compose thứ hai sẽ tự tạo một network riêng biệt. Khi đó Chaptarr sẽ không thể resolve qbittorrent bằng tên. Lấy tên thực tế bằng docker network ls. Nếu stack của bạn đã nằm trong cùng một file, hãy thêm service chaptarr: vào file đó và xóa toàn bộ block networks:. Bố cục đầy đủ được trình bày trong một arr stack đầy đủ với Docker Compose, còn quy tắc đặt tên được trình bày trong cách Compose resolve network và tên service.
Tự tạo thư mục config, sau đó khởi động service.
mkdir -p ./config
sudo chown 1000:1000 ./config
docker compose up -d
docker compose ps
docker compose logs -f chaptarrdocker compose ps phải hiển thị container ở trạng thái Up. Container có trạng thái Restarting đã khởi động thất bại và đang được thử lại. Nguyên nhân gần như luôn nằm ở thư mục config. Log sẽ dừng cuộn khi ứng dụng bắt đầu lắng nghe trên port 8789.
PUID, PGID và thư mục Docker tạo dưới quyền root
Chaptarr mặc định dùng PUID=99 và PGID=100 nếu bạn không đặt các biến này. Đây là các giá trị của unRAID. Trên một Ubuntu VPS thông thường, chúng trỏ đến một user không hữu ích, nên các file được tạo với owner mà tài khoản đăng nhập của bạn không thể ghi. Dùng id -u và id -g để xem các giá trị của chính bạn, rồi ghi chúng vào file.
Mọi container cùng thao tác trên các file đó phải dùng cùng một cặp giá trị. Download client ghi vào /srv/media/downloads, Chaptarr chuyển file vào /srv/media/audiobooks, rồi player đọc file tại đó. Nếu download client ghi dưới quyền 1000:1000 còn Chaptarr chạy dưới quyền 99:100, thao tác import sẽ thất bại. Owner của file không phải yếu tố quyết định. Để tạo, đổi tên hoặc xóa file, cần có quyền ghi trên thư mục chứa file đó. Các thư mục do user 1000 tạo với mode 755 phổ biến sẽ không cho 99:100 quyền ghi. Vì vậy Chaptarr không thể đưa sách vào thư viện hoặc xóa sách khỏi thư mục tải xuống. UMASK=002 khiến các file mới có quyền ghi đối với group. Đây là cấu hình phù hợp khi nhiều container dùng chung một media group. Bảng ánh xạ đầy đủ có trong cách PUID và PGID ánh xạ user của container với các file trên host.
README cảnh báo một lỗi cụ thể và đáng được nhắc lại. Nếu ./config chưa tồn tại khi bạn chạy docker compose up, Docker sẽ tự tạo thư mục đó với owner là root:root. Sau đó container chạy dưới UID 1000 và không thể ghi database của chính nó, nên thoát rồi khởi động lại liên tục. Kiểm tra bằng ls -ln ./config. Lệnh này in owner dưới dạng số thay vì tên. Hai số 0 nghĩa là root đang sở hữu thư mục. Sửa bằng sudo chown -R 1000:1000 ./config rồi khởi động lại container.
Vì sao tách volume audiobook và ebook làm hardlink không hoạt động
Bố cục trên mount /audiobooks, /ebooks và /downloads thành các bind riêng, đúng với lệnh chạy của project. Cách này dễ đọc, nhưng có một chi phí thực tế: hardlink không còn hoạt động.
Hardlink là tên thứ hai trỏ đến cùng một dữ liệu trên disk. Nó không dùng thêm dung lượng và được tạo ngay lập tức, nên họ arr ưu tiên hardlink thay vì copy. Hardlink chỉ hoạt động trong cùng một filesystem. Bên trong container, đây là ba mount point riêng biệt, nên kernel từ chối tạo link ngay cả khi các path trên host nằm trên cùng một disk. Bạn có thể tự kiểm tra.
docker exec chaptarr sh -c 'touch /downloads/linktest && ln /downloads/linktest /audiobooks/linktest'Lệnh sẽ fail với lỗi kết thúc bằng Invalid cross-device link. Đây là kernel từ chối tạo link giữa các mount point, và cũng là lý do chính xác khiến Chaptarr chuyển sang copy file. Bản copy vẫn đúng nhưng chậm hơn, và audiobook sẽ tồn tại hai lần cho đến khi bạn xóa torrent. Bạn sẽ không làm vậy khi vẫn đang seed torrent. Xóa /srv/media/downloads/linktest sau đó.
Để giữ hardlink, hãy mount một thư mục cha duy nhất:
volumes:
- ./config:/config
- /srv/media:/dataSau đó đặt các root folder trong Chaptarr thành /data/audiobooks và /data/ebooks, đồng thời cấp cho download client cùng mount /srv/media:/data để cả hai container nhìn thấy một path giống hệt nhau. Trước tiên, xác nhận phía host chỉ dùng một filesystem: df -h /srv/media/downloads /srv/media/audiobooks phải in cùng một giá trị trong cột Filesystem cho cả hai path. Các giá trị khác nhau nghĩa là hai disk khác nhau, và không có bố cục mount nào có thể tạo hardlink giữa chúng. Phần so sánh bind mount với named volume cho media trình bày trade-off giữa cách này và named storage.
Truy cập giao diện web mà không public ra Internet
Dòng port bind vào 127.0.0.1 có lý do. ufw deny 8789 không bảo vệ được port Docker đã publish, vì Docker tự ghi các rule NAT (network address translation) vào một chain mà kernel xử lý trước chain của ufw. Vì vậy, traffic được forward trước khi rule của bạn được kiểm tra. Hành vi này thường gây nhầm lẫn, và được giải thích trong lý do port Docker đã publish bỏ qua rule ufw. Bind vào loopback sẽ loại bỏ hoàn toàn vấn đề này.
Truy cập UI qua SSH tunnel từ máy của bạn:
ssh -N -L 8789:127.0.0.1:8789 you@your-serverGiữ tunnel đang chạy rồi mở http://127.0.0.1:8789 trong trình duyệt. Thiết lập authentication ngay lần chạy đầu tiên. Chỉ sau đó bạn mới nên cân nhắc đặt reverse proxy có TLS (transport layer security) phía trước. Khi phải tunnel vào ba hoặc bốn công cụ như vậy và dùng một password riêng cho từng công cụ, cách gọn hơn là đặt proxy phía sau một server single sign-on tự host như Authentik, để một lần đăng nhập áp dụng cho mọi app và một lần revoke sẽ vô hiệu hóa tất cả.
Kết nối indexer và download client
Chaptarr sử dụng các giao thức chuẩn của hệ sinh thái arr cho indexer và download client. Vì vậy, Prowlarr đẩy indexer vào Chaptarr giống như với Sonarr, còn các client torrent và usenet thông thường kết nối mà không cần xử lý đặc biệt.
Có một thiết lập khiến gần như mọi người đều gặp lỗi. Khi Chaptarr yêu cầu hostname của download client, không nhập localhost hoặc 127.0.0.1. Bên trong container, địa chỉ đó trỏ về chính container hiện tại. Vì vậy, Chaptarr sẽ cố kết nối đến port 8080 của chính nó và báo lỗi không thể kết nối. Hãy dùng tên container qbittorrent cùng port 8080. Xác nhận cả hai container nằm trên cùng một network bằng docker network inspect arr. Lệnh này liệt kê tên của mọi container đang được kết nối.
Nếu download client chạy qua một VPN container bằng network_mode: "service:gluetun", nó không có tên riêng trên network vì dùng chung network namespace của Gluetun. Hãy truy cập nó qua gluetun trên port mà Gluetun expose. Cách thiết lập này và cấu hình routing tương ứng được trình bày trong định tuyến download client qua Gluetun.
Chi phí thực sự khi chuyển từ Readarr
Chaptarr không tương thích với các nguồn metadata của Readarr. Chaptarr phân giải tên sách, tác giả và các ấn bản qua pipeline riêng trên nhiều provider, nên các identifier mà Readarr đã lưu không có ý nghĩa ở đây. Không có cách import database hoặc nâng cấp trực tiếp.
Với library hiện có, các file vẫn an toàn nhưng settings thì không được giữ lại. Quy trình này không tác động đến dữ liệu đã có trên disk. Bạn thêm một root folder, chạy library import, rồi Chaptarr đối chiếu các file tìm được với metadata riêng của nó. Những phần bạn phải tự dựng lại gồm quality profile, naming format, settings của indexer và client, cùng mọi kết quả đối chiếu sai mà Chaptarr đưa ra. Library lớn sẽ cần kiểm tra và sửa thủ công, vì vậy hãy dành cả buổi tối thay vì chỉ mười phút.
Hãy thực hiện theo thứ tự này. Dừng container Readarr nhưng giữ lại config volume để vẫn có thể xem settings cũ trong lúc nhập lại. Trỏ Chaptarr vào một folder nhỏ trước và kiểm tra kết quả đối chiếu rồi mới import toàn bộ. Chỉ xóa container cũ sau khi bạn đã thấy mọi thứ ổn.
Có một chi tiết về quyền riêng tư bạn nên biết trước khi quét toàn bộ library: các truy vấn metadata được gửi đến api2.chaptarr.com. README cho biết những request này có thể chứa provider ID, nội dung tìm kiếm, loại media, tag và tên file, đồng thời không chứa full path, danh tính người dùng hoặc credential. Tên file rời khỏi server của bạn. Đây là hành vi bình thường của metadata service, nhưng bạn vẫn nên chủ động quyết định có chấp nhận hay không.
Audiobook phát cho trình phát
Chaptarr quản lý file. Việc phát file là nhiệm vụ của chương trình khác. Audiobookshelf thường được dùng cùng vì nó theo dõi vị trí đang nghe trên nhiều thiết bị và có ứng dụng cho điện thoại. Image chính thức của nó là ghcr.io/advplyr/audiobookshelf:latest. Ví dụ Compose trong tài liệu của Audiobookshelf publish host port 13378 vào container port 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-stoppedMount cùng host path mà Chaptarr ghi file vào, rồi thêm /audiobooks làm library trong web UI. Bản import mới sẽ xuất hiện sau lần scan tiếp theo.
Nếu bạn đã chạy Jellyfin, có thể thêm folder này làm library trong đó để phát file. Tuy nhiên, chức năng resume với một file audiobook dài thường kém hơn so với audiobook server chuyên dụng. Cách cấu hình Jellyfin được trình bày trong chạy Jellyfin làm media server trên VPS. Với phần ebook, chuyển /srv/media/ebooks cho một ứng dụng đọc. Chaptarr hoàn tất nhiệm vụ khi file đã được đặt tên và lưu đúng thư mục.
Rủi ro bảo trì: giấy phép, runtime và tag thay đổi nhanh
Chaptarr được cấp phép theo GPL-3.0. Bản quyền thuộc về các cộng tác viên của Chaptarr, cùng một phần mã từ đội Servarr. Vì vậy, mã nguồn vẫn mở và bất kỳ ai cũng có thể fork lại nếu maintainer này dừng phát triển. Chaptarr xây dựng trên .NET 10, là bản long-term support hiện tại của runtime tính đến tháng 8 năm 2026. Điều này có nghĩa nền tảng được hỗ trợ trong nhiều năm thay vì vài tháng. Cả hai yếu tố đều quan trọng khi đánh giá liệu dự án này còn tồn tại vào năm sau hay không.
Số phiên bản thay đổi rất nhanh. Bản 0.9.925 được phát hành ngày 9 tháng 8 năm 2026, và có thêm 5 bản phát hành trong 7 tuần tiếp theo. Mọi bản phát hành đến 0.9.958 đều được đánh dấu là pre-release. Bản 0.9.965, phát hành ngày 27 tháng 9 năm 2026, là bản đầu tiên được đánh dấu là full release. Hãy pin một tag cụ thể. Dùng latest có thể khiến một docker compose pull không cần giám sát tự động cập nhật qua vài phiên bản trong một tuần. Một fork còn mới như vậy cũng có thể thay đổi API giữa các bản phát hành, làm hỏng mọi script hoặc dashboard bạn viết dựa trên API đó. Pin phiên bản là thói quen nên áp dụng cho mọi dự án còn mới mà bạn tự host. Vì lý do đó, hướng dẫn chạy openGym làm trình theo dõi bài tập tự host cũng deploy từ một git tag cố định.
Hãy backup trước mỗi lần upgrade, sau đó upgrade một cách có chủ đích.
docker compose stop chaptarr
sudo tar czf chaptarr-config-backup.tgz ./config
docker compose start chaptarrdocker compose pull chaptarr
docker compose up -d chaptarrDự án báo cáo không có sự cố mất dữ liệu nào trong khoảng 6 tháng với hơn 11000 người dùng. Tuy vậy, dự án vẫn khuyến nghị duy trì backup và không trỏ ứng dụng vào thư viện mà bạn không thể chấp nhận bị mất. Hãy nghiêm túc thực hiện cả hai khuyến nghị này. Sao chép archive cấu hình ra khỏi server. Một bản backup nằm trên cùng disk với dữ liệu mà nó bảo vệ không phải là backup. Một tarball duy nhất này đủ dùng chỉ vì Chaptarr lưu state trong một file SQLite duy nhất tại /config. Nếu có dữ liệu nằm trên database server riêng, bạn cũng phải dump database đó. Đây là cách bước backup được thực hiện khi tự host Chatwoot trên VPS cùng dữ liệu Postgres và các file đã upload.
Các tình huống lỗi và chuỗi bạn sẽ thấy
Container khởi động lại liên tục. docker compose ps hiển thị Restarting. Chạy ls -ln ./config. Hai số 0 trong các cột owner có nghĩa là Docker đã tạo thư mục dưới quyền root, nên user của container không thể ghi database của nó. Chạy sudo chown -R 1000:1000 ./config.
Import không bao giờ hoàn tất và file vẫn nằm trong thư mục downloads. Chaptarr có thể đọc file đã tải xuống nhưng không thể ghi vào library. So sánh ls -ln /srv/media/audiobooks với PUID và PGID của bạn. Thư mục thuộc về một UID khác, hoặc thuộc về group của bạn nhưng không cho phép group ghi, sẽ khiến thao tác di chuyển thất bại. UMASK=002 ngăn trường hợp thứ hai đối với file mới.
Dung lượng disk tăng gấp đôi sau mỗi lần import. Không tạo được hardlink nên file đã bị sao chép. Chạy phép kiểm tra ln trong phần volumes. Lỗi kết thúc bằng Invalid cross-device link xác nhận nguyên nhân này; dùng một mount point chung là cách khắc phục.
Download client không kết nối được. Bạn đã nhập localhost làm host. Bên trong container, đó chính là Chaptarr. Hãy dùng tên container và kiểm tra docker network inspect arr để xác nhận cả hai container đều được liệt kê.
Compose từ chối khởi động service. Bind for 127.0.0.1:8789 failed: port is already allocated có nghĩa là một tiến trình khác đang giữ cổng này. Tìm tiến trình đó bằng sudo ss -lntp | grep 8789.
Trình duyệt hoàn toàn không hiển thị gì. Khi cổng được bind vào 127.0.0.1, laptop của bạn không có gì để kết nối qua Internet. Đây là hành vi đúng theo thiết kế. Trước tiên hãy mở SSH tunnel.
FAQ
Tôi có thể chuyển thư viện Readarr sang Chaptarr không?
Không thể chuyển bằng chức năng import. Chaptarr không tương thích với các nguồn metadata của Readarr và sử dụng pipeline provider riêng. Vì vậy, các identifier được Readarr lưu trữ không còn ý nghĩa và không có cách chuyển đổi database. Các file trên disk không bị thay đổi. Bạn thêm lại các path tương tự dưới dạng root folder, chạy library import và để Chaptarr tự đối chiếu các file. Quality profile, naming format, thiết lập indexer và mọi kết quả đối chiếu sai đều phải xử lý thủ công. Vì vậy, hãy thử với một folder nhỏ trước khi import toàn bộ.
Tại sao Chaptarr không thể ghi vào folder audiobook của tôi?
User trong container không có quyền ghi vào thư mục đó, thường vì container chạy bằng UID khác với UID của user sở hữu thư mục. Khi các biến này chưa được thiết lập, Chaptarr dùng giá trị mặc định PUID=99 và PGID=100. Đây là các giá trị của unRAID và không đúng trên Ubuntu VPS thông thường. Đặt chúng thành id -u và id -g của bạn, dùng cùng cặp giá trị này trên download client, rồi đặt UMASK=002 để các file mới vẫn cho phép group ghi. Kiểm tra ownership bằng ls -ln trên thư mục library. Lệnh này in ra các số thay vì tên, nên bạn có thể so sánh.
Tại sao dung lượng disk tăng gấp đôi sau khi import?
Chaptarr đã copy file vì không thể tạo hardlink cho file đó. Mount /downloads và /audiobooks dưới dạng các bind riêng khiến chúng trở thành các mount point riêng bên trong container. Kernel sẽ từ chối tạo hardlink giữa các mount point và trả về Invalid cross-device link. Hãy mount một thư mục cha, chẳng hạn /srv/media:/data, rồi dùng /data/downloads và /data/audiobooks bên trong app. Cả hai path cũng phải nằm trên cùng một filesystem của host. df -h xác nhận điều này.
Chaptarr có phát audiobook của tôi không?
Không. Chaptarr tìm, tải xuống, đổi tên và sắp xếp file. Playback do một chương trình riêng đảm nhiệm. Audiobookshelf thường được dùng cùng Chaptarr vì có thể nhớ vị trí phát trên nhiều thiết bị. Hãy dùng image chính thức ghcr.io/advplyr/audiobookshelf:latest và mount cùng path audiobook trên host. Jellyfin cũng có thể phát các file này nếu bạn thêm folder làm library, nhưng khả năng resume kém hơn với audiobook dài chỉ gồm một file.
Chạy Chaptarr trên library quan trọng có an toàn không?
Chaptarr là phần mềm beta từ một fork còn mới. Chính dự án cũng nêu rõ điều này, đồng thời báo cáo không có sự cố mất dữ liệu nào trong khoảng sáu tháng với hơn mười một nghìn người dùng. Các điểm đáng tin cậy là giấy phép GPL-3.0, cho phép tiếp tục fork code, và nền tảng .NET 10, một runtime hỗ trợ dài hạn tính đến tháng 8 năm 2026. Hãy pin một image tag chính xác như 0.9.925 thay vì latest, backup /config trước mỗi lần upgrade và lưu archive đó ngoài server.