Audiobookshelf behind Caddy

Verified · Caddy 2.8

Config + gotchas checked against the official Audiobookshelf docs and the issues people actually hit · 2026-06-07

A Caddy reverse-proxy setup for Audiobookshelf, with automatic HTTPS on audiobooks.example.com. Copy it, swap the domain — the gotchas that trip people up are solved below.

New to reverse proxies? Start with the Caddy + Docker guide.

Caddyfile
# Caddyfile for Audiobookshelf
# Replace audiobooks.example.com with your real domain. Caddy issues TLS automatically.

audiobooks.example.com {
	encode zstd gzip
	reverse_proxy audiobookshelf:13378
}

Replace audiobooks.example.com with your domain. Your DNS A record must already point at the server.

Gotchas

What trips people up

Login or e-books fail when Audiobookshelf is served on a sub-path like /audiobookshelf.

Give it its own subdomain (audiobooks.example.com), not a sub-path. Sub-path hosting needs extra URL-rewrite handlers and still breaks the e-book reader, which requests API paths without the prefix.

OIDC / SSO login fails with "No session" or a redirect_uri mismatch behind the proxy.

The app must see the request as HTTPS. This Caddyfile reverse-proxies straight to the container (no http:// scheme prefix), so X-Forwarded-Proto stays https. Note some browsers (Firefox bounce-tracking protection) drop the OIDC session cookie on the provider round-trip — keep the auth provider on the same parent domain where possible.

Deploy

How to deploy

  1. Create the shared proxy network once: `docker network create proxy`.
  2. Start the stack: `docker compose up -d`.
  3. Point audiobooks.example.com at the server; Caddy issues the cert on first request (ports 80/443 reachable).

Runnable

Full runnable stack

Audiobookshelf + Caddy + the shared network, in one compose file — so it runs on the first try, not after you stitch the proxy in yourself. Save the Caddyfile above next to it.

docker-compose.yml (app + Caddy)
# docker-compose.yml — Audiobookshelf + Caddy, ready to run.
# Pin caddy to a digest for production: caddy:2.8-alpine@sha256:<digest>
# 1. Save the Caddyfile above as ./Caddyfile
# 2. docker network create proxy
# 3. docker compose up -d
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:2.35.1@sha256:1eef6716183c52abafe5405e7d6be8390248ecd59c7488c44af871757ac8fc4d
    restart: unless-stopped
    environment:
      PORT: "13378"
      TZ: ${TZ}
    volumes:
      - audiobookshelf-config:/config
      - audiobookshelf-metadata:/metadata
      - ${AUDIOBOOKS_PATH}:/audiobooks
      - ${PODCASTS_PATH}:/podcasts
    networks:
      - default
      - proxy
  caddy:
    image: caddy:2.8-alpine
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      - proxy
volumes:
  audiobookshelf-config: {}
  audiobookshelf-metadata: {}
  caddy-data: {}
  caddy-config: {}
networks:
  proxy:
    external: true

Full Audiobookshelf stack (compose + env + docs)