import Navbar from '@/components/Navbar'; import Footer from '@/components/Footer'; import DocsLayout from '@/components/docs/DocsLayout'; export const metadata = { title: 'Install Audiobookshelf — DashCaddy Docs', description: 'Install and configure Audiobookshelf via DashCaddy. Self-hosted audiobook and podcast server', }; export default function audiobookshelfDocsPage() { return (
ghcr.io/advplyr/audiobookshelf:latest
Self-hosted audiobook and podcast server
Audiobookshelf ships as a self-contained Docker image that DashCaddy provisions with one click. DashCaddy handles the container lifecycle, DNS record, Caddy reverse-proxy entry, and HTTPS certificate so you can focus on using Audiobookshelf, not installing it.
https://status.sami; configurable via the dashboardHost setting in config.json).POST /api/v1/auth/keys to create one)./media/audiobooks. The deploy form / API payload config.mediaPath must be readable by the container UID (usually 1000).https://status.sami (or your host's dashboard URL).audiobooks), host port (default: 13378), and the media library path./) to pass.{success, containerId, url, message, setupInstructions} — there is no separate status-poll endpoint; the dashboard updates live.Authenticate with an API key (or a JWT minted via POST /api/v1/auth/jwt). Send as X-API-Key: dk_... or Authorization: Bearer <jwt>.
curl -X POST https://status.sami/api/v1/apps/deploy \\
-H "X-API-Key: dk_your_api_key" \\
-H "Content-Type: application/json" \\
-d '{
"appId": "audiobookshelf",
"config": {
"subdomain": "audiobooks",
"port": 13378,
"mediaPath": "/media/audiobooks"
}
}'
The full body schema is in src/utilities/validate.js (Joi schema appDeploy). All config.* fields except subdomain are optional. Notable options:
config.port — host port (1–65535). Defaults to the template's defaultPort.config.mediaPath — host directory to mount as the media library.config.plexClaimToken — Plex claim token (when the upstream service needs one).config.useExisting: true + existingContainerId — attach DashCaddy metadata to an already-running container instead of pulling a new image.config.tailscaleOnly: true — restrict the reverse-proxy entry to your Tailscale network.config.allowedIPs — array of CIDR ranges allowed past the reverse proxy.config.createDns: false — skip DNS record creation (use when the subdomain already resolves).config.resources — {memory, cpus} limits applied to the container.The Intent Router returns a structured intent, not a deployed container. To deploy via AI, send natural language to:
curl -X POST https://status.sami/api/v1/ai/intent \\
-H "X-API-Key: dk_your_api_key" \\
-H "Content-Type: application/json" \\
-d '{ "message": "Deploy Audiobookshelf on my home host and expose it at audiobooks.sami" }'
The response includes intent, action, parameters, and followup — your client (or the MCP server) must then call POST /api/v1/apps/deploy with those parameters to actually provision the container.
For AI agents (Claude Desktop, Hermes, etc.) configure the MCP server (src/mcp/mcp-server.js) with:
DASHCADDY_URL=https://status.sami:3001 # internal API URL, may differ from dashboard URL
DASHCADDY_API_KEY=dk_your_api_key
The server exposes dashcaddy_deploy_app. Note: this tool writes the Caddy route and creates the services.json entry, but it does NOT pull the Docker image or start the container. You must run docker pull ghcr.io/advplyr/audiobookshelf:latest and start the container yourself for the URL to actually serve traffic. For a fully-managed deployment, call POST /api/v1/apps/deploy directly from your agent.
The media mount path you pass as mediaPath in the deploy payload is mounted as /audiobooks inside the container. Bind a host directory containing your media library (movies, TV shows, music, etc.).
chown -R 1000:1000 /media/audiobooks on the host.DashCaddy creates these volume mounts in the container spec:
/opt/audiobookshelf/config:/config/opt/audiobookshelf/metadata:/metadataMEDIA_PATH:/audiobooksAll paths are host paths (left side) mapped into the container (right side). Restarting the container preserves data; reinstalling the template preserves it unless you explicitly pass config.useExisting: false AND wipe the volume. Bind mounts use the host-path conventions above (e.g. /opt/plex/config becomes a bind mount to the host directory of the same path).
None. The container runs with its upstream defaults.
These are baked into the template at deploy time and shipped to the container. The deploy handler does NOT allow overriding them via the API payload — to change them you must edit the template definition in dashcaddy-api/src/docker/app-templates.js.
There is no built-in auto-update — DashCaddy does NOT poll for new image digests. To pull a new version:
docker pull ghcr.io/advplyr/audiobookshelf:latest.docker restart <containerId> (find the ID via GET /api/v1/services or the dashboard).0 0 4 * * * = 04:00 daily).The default backup policy includes the entire /app/data/ directory (services, config, credentials, stats) AND all Docker volumes. Backups are scheduled via backup-config.json — the default schedule is configurable, not "nightly" out of the box. To restore on a fresh host, redeploy the same template and then call POST /api/v1/apps/{appId}/restore with a backup ID from GET /api/v1/backups/history.
Common issues with Audiobookshelf:
mediaPath is readable by the container UID and that the directory contains the file extensions Audiobookshelf indexes.GET /api/v1/dns/records and systemctl status caddy on the host./ is not returning 200. Inspect docker logs <containerId> directly.For layer-by-layer diagnostics, see the Troubleshooting guide.
Template ID: audiobookshelf. Source: dashcaddy-api/src/docker/app-templates.js.