Server guides · Setup
Audiobookshelf reverse proxy: Nginx, Caddy and HTTPS setup
Put Audiobookshelf behind Nginx, Caddy, Nginx Proxy Manager, Apache, HAProxy or Traefik with HTTPS and WebSockets, plus fixes for 413 and socket errors.
A reverse proxy gives your Audiobookshelf server an HTTPS address for listening outside your home network. A VPN such as Tailscale is another option if you don’t want a public address.
The examples below assume the proxy runs on the same host as Audiobookshelf and reaches it at port 13378. In a separate Docker container, localhost means the proxy container itself: use a shared Docker network and the Audiobookshelf service name and container port instead, such as audiobookshelf:80. Point your hostname’s DNS to the proxy and configure its certificate before connecting remotely.
The one thing every config has in common: WebSocket support is required. A WebSocket is the live connection Audiobookshelf uses to send updates to the web app and phone apps. Without it you get “Socket failed to connect”.
Two more things matter for every proxy:
- Tell Audiobookshelf the visitor used HTTPS. The proxy does this with the
X-Forwarded-Protoheader. Audiobookshelf uses it to build OpenID sign-in links and to mark its sign-in cookie as secure. Caddy and Traefik send it on their own; the Nginx, Apache and HAProxy examples below set it. - Allow big enough requests. Uploads through the web app need a large limit. Phone apps can send several offline listening sessions in one request, and a low limit can refuse it with a 413 error. Audiobookshelf itself accepts these up to 10 MB.
Caddy (the easy option)
If you don’t already have a preference, use Caddy. It handles SSL certificates automatically and the config is short:
# Caddy and Audiobookshelf are on the same host.
audiobookshelf.yourdomain.com {
reverse_proxy localhost:13378
}
That’s the entire config. Caddy handles SSL via Let’s Encrypt, WebSocket proxying, and HTTP/2 automatically.
Nginx
server {
listen 443 ssl;
server_name audiobookshelf.yourdomain.com;
ssl_certificate /path/to/certificate;
ssl_certificate_key /path/to/key;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_pass http://localhost:13378;
proxy_redirect http:// https://;
client_max_body_size 10240M;
}
}
The Upgrade and Connection headers are the WebSocket bits. The large client_max_body_size allows uploading audiobook files through the web UI, and covers offline listening sent from phones. Nginx’s own default is 1 MB.
Nginx Proxy Manager
If you’re running Nginx Proxy Manager (common on home servers):
- Add a new Proxy Host
- Set your domain name
- Forward to your server’s IP on port 13378
- Enable Websockets Support. This is the toggle that trips people up
- Under SSL, enable Force SSL and HTTP/2
- If uploads or offline syncing fail with a 413 error, add
client_max_body_size 10240M;in the host’s Advanced tab
Nginx Proxy Manager already sends X-Forwarded-Proto, but it can send it as http, https. Audiobookshelf before v2.30.0 didn’t understand that value, so OpenID sign-in failed with “Invalid callback URL - must be same-origin” (#4609). v2.30.0 fixed it. If you use OpenID behind Nginx Proxy Manager, update Audiobookshelf rather than adding your own header.
Apache
Requires mod_ssl, mod_proxy, mod_proxy_http, mod_proxy_wstunnel, mod_rewrite and mod_headers:
<VirtualHost *:443>
ServerName audiobookshelf.yourdomain.com
SSLEngine on
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ProxyPass / http://localhost:13378/
ProxyPassReverse / http://localhost:13378/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://localhost:13378/$1" [P,L]
SSLCertificateFile /path/to/cert
SSLCertificateKeyFile /path/to/key
</VirtualHost>
On Apache 2.4.47+, there’s a simpler syntax:
<VirtualHost *:443>
ServerName audiobookshelf.yourdomain.com
SSLEngine on
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost on
ProxyPass / http://localhost:13378/ upgrade=websocket
ProxyPassReverse / http://localhost:13378/
SSLCertificateFile /path/to/cert
SSLCertificateKeyFile /path/to/key
</VirtualHost>
HAProxy
frontend my_frontend
mode http
bind :443 ssl crt-list /path/to/cert.crt_list alpn h2,http/1.1
acl is_audiobookshelf hdr_beg(host) -i audiobookshelf
use_backend audiobookshelf_backend if is_audiobookshelf
backend audiobookshelf_backend
mode http
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
timeout tunnel 1h
server audiobookshelf 127.0.0.1:13378
HAProxy upgrades WebSocket connections by itself in mode http. The timeout tunnel line keeps them open; without it, HAProxy’s normal timeouts can close the live connection early. HAProxy’s WebSocket guide has more.
Traefik
Traefik works with standard Docker labels. Let Audiobookshelf handle CORS (the rules for which websites may send requests to it) itself. If login shows “Unknown Error” after you added CORS header middleware (accessControlAllowMethods, accessControlAllowOriginList, accessControlMaxAge), remove it and try again.
Pangolin
Pangolin can protect a resource with its own sign-in (SSO, a password or a PIN). That’s a web page, and apps can’t fill it in, so app sign-in and the live connection fail behind it. Leave Pangolin’s sign-in off for Audiobookshelf, or add a Bypass Auth rule for it. Audiobookshelf still asks for its own username and password.
The same goes for a separate sign-in page in front of the whole site, such as Authelia or Authentik forward auth: apps can’t get past it. Remove it or bypass it for Audiobookshelf, and use Audiobookshelf’s own OpenID sign-in if you want single sign-on.
Running under a subfolder
If you want to run Audiobookshelf at yourdomain.com/audiobookshelf instead of a subdomain, use the path /audiobookshelf. That’s the path the standard Audiobookshelf builds use, so other folder names don’t work with the normal Docker image or packages. Why Audiobookshelf adds /audiobookshelf to your URL explains the path and what apps need.
Verify it works
After setting up your reverse proxy:
- Open
https://audiobookshelf.yourdomain.comin a browser - Log in and test playback. In browser developer tools, check the Network WebSocket request for a successful upgrade; playback alone does not prove that connection works.
- In SoundLeaf, use the full URL including
https://to connect
If playback or live updates fail, inspect the failed request and proxy logs before changing settings. WebSocket headers are one possible cause; a proxy that can’t reach Audiobookshelf, a certificate error or denied request can also break playback.
Troubleshooting
”Socket failed to connect”
The app couldn’t open its live connection. The usual fix is WebSocket support in the proxy, as shown above; server reachability and certificate errors can cause it too. The socket troubleshooting guide goes through each proxy and the less common causes.
Streams fail but downloads work
A download asks for a book’s files once. Streaming makes many requests while you listen: pieces of the file as you play and seek, and for some formats a stream the server prepares under the /hls path. So a proxy can let downloads through and still break streaming. Check that:
- The proxy forwards the whole site to Audiobookshelf, not only some paths.
- No sign-in layer or access rule sits in front of some paths and not others.
- The proxy log shows what happened to the failing request. The status and error message show whether the proxy or Audiobookshelf refused it.
One user with Nginx Proxy Manager reported streaming started working after they turned off HTTP/2 on the SSL tab. That’s a single report, so try it after the checks above.
”413 Payload Too Large” or “Request Entity Too Large”
The request was bigger than a limit allows. Two common cases:
- Uploading a book in the web app. Raise the proxy’s body size limit, like
client_max_body_size 10240M;in Nginx. - Offline listening doesn’t reach the server. Phone apps can send several offline listening sessions in one request when they reconnect. After a lot of offline listening, that batch can be bigger than a small proxy limit. Raise the limit to at least 10 MB.
Look at where the 413 comes from. If the proxy’s error log shows it refused the request for its size, raise the proxy limit. If Audiobookshelf’s own log shows a PayloadTooLargeError, the request reached the server and was too big for it. That case is tracked in #4755.
Behind Cloudflare, uploads have their own cap of 100 MB per request on the Free and Pro plans; see the Cloudflare Tunnel guide.
”Invalid callback URL - must be same-origin”
Audiobookshelf only sends you back to an address on the same site it thinks you’re visiting. Behind a proxy, this often happens when it thinks you used http when you used https. Make sure your proxy sends X-Forwarded-Proto and passes the original hostname, and update Audiobookshelf to v2.30.0 or newer if you use Nginx Proxy Manager. More OpenID errors are in OpenID sign-in errors.
Signed out again and again
For repeated login prompts, use the token and session troubleshooting guide. A dropped live connection and an expired sign-in need different fixes. SoundLeaf can also keep separate local and remote server addresses.
The protocol details are documented in Nginx’s WebSocket guide and Caddy’s reverse_proxy reference.