Audiobookshelf is an excellent self-hosted server for audiobooks, podcasts, and ebooks. I decided to integrate this service with S3 as the primary storage layer, as I centralized all my data in Object Storage long ago.
The official example docker-compose.yml provides the standard layout:
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
ports:
- 13378:80
volumes:
- </path/to/audiobooks>:/audiobooks
- </path/to/podcasts>:/podcasts
- </path/to/config>:/config
- </path/to/metadata>:/metadata
environment:
- TZ=America/Toronto
Part I: Docker Volume Plugin Approach
As I documented in a previous article (Paperless-NGX), the Rclone Docker Volume Plugin provides a clean, container-native way to mount S3 storage.
Installation and Volumes
The Plugin must be installed on the host and granted all necessary permissions. This approach ensures the mount is tightly coupled with the container’s lifecycle.
apt-get -y install fuse3
docker plugin install rclone/docker-volume-rclone:amd64 args="-v" --alias rclone --grant-all-permissions
Note: The amd64 architecture should be replaced with arm64 if running on a device like a Raspberry Pi 5.
Configuration (Subpath Mapping)
This setup uses subpath mapping to manage the application directories within a single S3 bucket:
services:
audiobookshelf:
# ... (ports, environment)
volumes:
- type: volume
source: s3
target: /audiobooks
volume:
subpath: audiobooks # Maps /audiobooks directory inside the container to the 'audiobooks' folder in the S3 bucket
# ... (similar mapping for podcasts, metadata)
volumes:
s3:
driver: rclone
driver_opts:
remote: "minio-audiobookshelf:audiobookshelf-jean"
allow_other: "true"
vfs_cache_mode: "full"
Note: The remote value references the [minio-audiobookshelf] section in the /var/lib/docker-plugins/rclone/config/rclone.conf file.
Part II: Alternative – Host-Bind Mount (Systemd Control)
If I prefer external control or need to apply very specific, non-default global Rclone options (like a reduced buffer-size at the plugin level), a host-bind mount is the preferred alternative.
Systemd Multi-Instance Service
I utilize a systemd unit template to manage each bucket mount independently on the host system. This offers more flexibility and makes the mount persistent even during Docker restarts.
# /etc/systemd/system/rclone@.service
[Unit]
Description=rclone - s3 mount for minio %i data
AssertPathExists=/etc/rclone/rclone-%i.conf
...
[Service]
Type=notify
ExecStart=/usr/bin/rclone \
mount minio-%i:%i-jean /srv/%i/ \
... (mount options)
Restart=on-failure
...
[Install]
WantedBy=default.target
Usage: The service is enabled and mounted per bucket, e.g., systemctl enable rclone@audiobookshelf.
Bind Mount into Container
The mounted host path is then bind-mounted into the Docker container:
services:
audiobookshelf:
# ...
volumes:
- type: bind
source: /srv/audiobookshelf/audiobooks # Host path mounted by systemd
target: /audiobooks
# ... (other bind mounts)
Part III: VFS Cache and Performance Tuning
Rclone Tuning Parameters
The key to high performance for streaming media lies in optimizing the Virtual File System (VFS) settings for object storage.
| Setting | Rationale |
vfs_fast_fingerprint: 'true' | Recommended for VFS cache over S3 backends. |
vfs_read_chunk_streams: 8 / vfs_read_chunk_size: 4M | Optimized for high throughput on a self-hosted, high-performance object store (MinIO). |
no_modtime: 'true' | Critical for S3, as reading the modification time requires a separate, unnecessary transaction. |
use-mmap | Uses memory mapping on Unix systems to improve memory efficiency. |
vfs_disk_space_total_size: 1T | Manually sets the total disk space reported by the filesystem (useful when this cannot be read correctly automatically). |
vfs_cache_mode: full | I use this to maximize performance, reducing cache age (72h) and size (20G) for resilience. |
Tailored Settings for Streaming Media
Since Audiobookshelf deals with large, sequentially accessed files (average size 144 MB), the read-ahead setting is incredibly important to prevent buffering during playback.
| Setting | Value | Rationale |
--vfs-read-chunk-size | 64M | Loading large files in few, efficient chunks. |
--vfs-read-ahead | 64M | Crucial for smooth streaming by prefetching the next part of the file. |
--vfs-read-chunk-size-limit | -1 or 2G | Necessary for handling large audiobook files without unnecessary overhead. |
Conclusion and Comparison
Both the Docker Plugin and Systemd Host Mount approaches are viable, but I personally prefer the systemd-based host mount as it offers greater flexibility, control, and separation of concerns—allowing independent management of each mount without affecting other Docker services.
Sources / See Also
- Rclone Documentation. Mount Options and Usage (VFS Cache Modes).
https://rclone.org/commands/rclone_mount/ - systemd Documentation. Using Templates and Instances (Service Management).
https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Templates - Docker Documentation. Docker Volume Plugin Architecture.
https://docs.docker.com/engine/extend/plugins_volume/ - FUSE Project Documentation. Understanding FUSE Filesystems and Permissions.
https://github.com/libfuse/libfuse - MinIO Documentation. Reference Guide for S3 Configuration and Endpoints.
https://min.io/docs/minio/linux/reference/minio-cli/minio-mc-admin-config.html