Build a persistent audiobook and podcast server, verify it locally, then connect it to the internet without router port forwarding
Audiobookshelf is an open-source, self-hosted server for organizing and streaming audiobooks and podcasts. In this guide, we install it using the officially recommended Docker method, configure persistent storage, verify the local web interface, and cover routine upgrades and troubleshooting. After the local server works correctly, we show how to create a Localtonet HTTP tunnel for remote access. Because Audiobookshelf requires WebSocket connectivity, the final verification includes testing both ordinary HTTP requests and WebSocket-dependent application behavior.
๐ What's in this guide
Why self-host Audiobookshelf?
Audiobookshelf is a self-hosted audiobook and podcast server with a browser-based client. It can stream audio, maintain progress for individual users, synchronize progress across devices, organize multiple libraries, download podcast episodes, and manage metadata and cover images. Its multi-user model also supports custom permissions, which is useful when a household or small group shares one server without sharing a single user account.
Self-hosting gives the server direct access to media stored on hardware you control. Your audiobook and podcast directories can remain on your workstation, home server, or another storage device that the Docker host can access. Audiobookshelf then indexes those mounted directories and presents them through its web client and supported applications.
The installation has two distinct networking stages. First, Audiobookshelf must run correctly as a local service. Second, if remote access is required, that working local endpoint can be published through an HTTP tunnel. Keeping these stages separate makes problems easier to diagnose. A tunnel cannot correct an inaccessible container, an incorrect volume path, a missing library, or an application that has not started successfully.
/config and /metadata directories keep the database, migrations, metadata, images, logs, and backups outside the disposable container filesystem.
Audiobookshelf also supports features such as metadata and cover-art retrieval, chapter editing, metadata backups, podcast feeds, bulk uploads, a Progressive Web App, basic ebook support, and open RSS feeds. Available behavior can change between releases, so application-specific options should always be reviewed after an upgrade.
Complete the Docker installation and confirm that the Audiobookshelf web interface works from the local machine first. This establishes a known-good local endpoint and prevents container, storage, and tunnel problems from becoming mixed together.
Prerequisites for this installation
Docker is the recommended installation method in the Audiobookshelf installation documentation. This guide uses Docker Compose because it keeps the image, port, volume, environment, and restart settings in one readable file. It also makes later upgrades repeatable.
Before beginning, prepare a machine that can remain powered on whenever the library should be available. It needs enough local storage for the application data and media you intend to serve, plus permission to read the media directories and write to the configuration and metadata directories.
Required software and access
- Docker installed and running on the host.
- The Docker Compose command available as
docker compose. - Permission to create directories and start containers.
- Host directories for Audiobookshelf configuration and metadata.
- One or more directories containing audiobooks, podcasts, or other media that Audiobookshelf will index.
- Local access to TCP port
13378, unless you deliberately choose a different external host port. - For the remote-access stage, the Localtonet client installed on a device that can reach the Audiobookshelf service.
Confirm that Docker and Docker Compose are available before creating the deployment:
docker --version
docker compose version
The exact Docker installation procedure depends on the operating system and distribution. This article does not substitute an unverified package command because package names, repositories, service-management commands, and supported Docker versions vary. Install Docker using the procedure appropriate for your host, start the Docker service where required, and then rerun the two checks above.
Choose a deployment location
Create a dedicated deployment directory for the Compose file. The actual location is your choice. Inside or alongside that deployment directory, decide where the persistent configuration and metadata will live. Media can be stored elsewhere, provided the Docker host can access it reliably.
Avoid putting temporary files, the SQLite database, and media into the container's writable layer. Containers are intended to be replaceable. Data that exists only inside a removed container may be lost when the container is recreated.
Audiobookshelf stores its SQLite database in the /config mount. The project documentation requires this directory to be directly accessible on the same machine that runs the server. Storing the database on a network share can cause poor performance and eventual database corruption. Media directories may follow a different storage design, but /config should remain local to the Docker host.
Plan ports, storage, and image versions
A reliable deployment begins with understanding what each Docker mapping does. Audiobookshelf listens on port 80 inside the container. The official Docker example publishes that internal service on host port 13378. This results in a local endpoint such as http://localhost:13378 when the browser and Docker are on the same machine.
In a Docker port mapping, the value on the left is the host port and the value on the right is the container port. If port 13378 is already occupied, change only the external value on the left. Do not change the container-side port from 80 unless current Audiobookshelf documentation specifically directs you to do so.
| Container path or setting | Purpose | Operational guidance |
|---|---|---|
/config |
SQLite database and database migration scripts | Use persistent storage located directly on the Docker host. Do not put this mount on network storage. |
/metadata |
Book metadata, cover and author images, logs, and backups | Use a persistent writable directory and include it in your backup plan. |
/audiobooks |
Example in-container path for audiobook media | Map it to the host directory containing audiobooks. You may choose another container path if you configure the library consistently. |
/podcasts |
Example in-container path for podcast media | Map it to the host directory intended for podcast content and downloads. |
13378:80 |
Publishes container port 80 on host port 13378 | Use host port 13378 by default, or change only the left-hand value if it conflicts with another service. |
TZ |
Sets the container time zone | Replace the example value with the correct time zone for the deployment. |
Each mount point should be a separate directory and should not be contained inside another mount point. For example, do not make the configuration directory a child of a directory that is also mounted into the container as a separate volume. Overlapping mounts make file visibility and backup behavior difficult to reason about.
Select an image tag
Audiobookshelf publishes several Docker image tag styles. The right choice depends on whether you prefer automatic movement to the newest stable release, a deliberately pinned version, or pre-release testing.
| Tag style | Behavior | Best fit |
|---|---|---|
:latest |
Points to the most recent stable release when the image is pulled | General installations that intentionally follow stable releases |
:#.#.# |
Selects a specific released version | Deployments that require controlled, reviewed upgrades |
:edge |
Updates for commits to the master branch and may contain newly introduced behavior | Testing new changes and reporting issues, rather than conservative production use |
This guide follows the official minimal example and uses :latest. If predictable change control is more important, replace latest with a specific released version and update that value intentionally during each upgrade. Do not copy an old example version without first deciding whether that is the version you actually want to operate.
Install Audiobookshelf with Docker Compose
The following workflow uses the project's documented Compose structure. Replace every host-side placeholder with a real absolute path on your Docker host. The paths on the right side of each volume mapping are the locations visible inside the container.
Create the host directories
Prepare separate directories for configuration, metadata, audiobooks, and podcasts. The configuration and metadata directories must be writable by the container. The media directories must be readable, and the podcast directory may also need write access when Audiobookshelf downloads episodes there.
Create the Compose file
In the deployment directory, create a file named docker-compose.yml. Add the service definition below, then replace the placeholder host paths and example time zone. Keep the container paths unless you have a deliberate library layout and understand how those paths will be selected in Audiobookshelf.
Validate the Compose configuration
Run docker compose config from the directory containing the file. This catches YAML formatting errors and shows the resolved Compose configuration before a container is created.
Pull the Audiobookshelf image
Run docker compose pull. Docker downloads the image selected by the tag in the Compose file. Pulling separately makes image-download failures visible before startup.
Start the service
Run docker compose up --detach. Detached mode starts the container in the background. The documented unless-stopped restart policy allows Docker to restart it after an ordinary host or Docker restart unless an operator has explicitly stopped it.
Inspect status and startup logs
Use docker compose ps to check the container state and docker compose logs to inspect startup output. Resolve port, path, permission, or image errors before opening the service to remote users.
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
ports:
- 13378:80
volumes:
- </path/to/config>:/config
- </path/to/metadata>:/metadata
- </path/to/audiobooks>:/audiobooks
- </path/to/podcasts>:/podcasts
environment:
- TZ=America/Toronto
restart: unless-stopped
Replace </path/to/config>, </path/to/metadata>, </path/to/audiobooks>, and </path/to/podcasts> with paths that exist on your host. Replace America/Toronto with the appropriate time zone. Do not leave angle-bracket placeholders in the file.
Then run the deployment commands from the same directory:
docker compose config
docker compose pull
docker compose up --detach
docker compose ps
docker compose logs
If you need additional media libraries, add additional volume mappings. Audiobookshelf permits as many or as few extra media mounts as your design requires. Give each one a distinct host directory and a distinct in-container path.
Do not add PUID or GUID expecting Audiobookshelf to change its runtime identity. The documented method for running the container as another user is the Compose user directive, such as user: 1000:1000. Only use a user mapping after verifying that the selected numeric user and group can access every required host directory.
Docker CLI alternative
Docker Compose is easier to review and maintain, but the official installation documentation also provides a direct Docker command. Replace all path placeholders and the example time zone before running it:
docker pull ghcr.io/advplyr/audiobookshelf
docker run -d \
-p 13378:80 \
-v /path/to/config:/config \
-v /path/to/metadata:/metadata \
-v /path/to/audiobooks:/audiobooks \
-v /path/to/podcasts:/podcasts \
--name audiobookshelf \
-e TZ="America/Toronto" \
ghcr.io/advplyr/audiobookshelf:latest
On Windows, the documented command must be entered as one line after removing the backslash line continuations. Host path syntax also depends on the shell and Docker environment, so use paths that Docker can access rather than copying Unix-style placeholders literally.
Verify Audiobookshelf locally
Local verification should cover more than whether the container appears in a process list. Confirm that the container is running, the HTTP interface responds, persistent directories are writable, and mounted media can be selected from inside Audiobookshelf.
Check the container state
docker compose ps
docker compose logs --tail 100
The service should remain running rather than repeatedly restarting or exiting. Read the application logs for actionable path, database, permission, or startup errors. A restart loop usually indicates a local deployment problem and should be fixed before configuring a tunnel.
Open the browser interface
From the Docker host, open:
http://localhost:13378
If the browser is on another machine in the same local network, use the Docker host's reachable local address with port 13378. Whether that connection is allowed depends on the host firewall, Docker networking, and local network policy. Do not disable the entire firewall merely to make the service reachable. Add only the access needed for the intended local clients.
Complete the setup flow presented by the installed Audiobookshelf version. The supplied evidence does not establish the exact labels or sequence of every first-run screen, so this guide does not invent them. Use unique credentials, then create libraries that point to the in-container media paths you mounted, such as /audiobooks and /podcasts.
Test the actual media workflow
- Confirm that the intended mounted directories are visible when creating or editing a library.
- Scan the library and verify that expected media appears.
- Open an item and begin playback.
- Pause and resume to confirm the application is functioning beyond its landing page.
- If multiple users are required, create and test them through the current application interface with appropriate permissions.
- Restart the container and verify that the configured users, libraries, metadata, and progress remain available.
The restart test is especially important. If data disappears after recreation or restart, the volume mappings are incorrect, inaccessible, or pointing to temporary locations.
docker compose restart
docker compose ps
docker compose logs --tail 100
Audiobookshelf's source-development workflow documents localhost:3333 for its default development client and localhost:3000 for a separate live-reloading client. Those ports belong to source-development workflows. The documented Docker installation in this guide publishes the container on host port 13378.
Operate, back up, and upgrade Audiobookshelf
A self-hosted media server needs a repeatable operating routine. At minimum, know how to view logs, stop and start the service, update the image, and protect the persistent data.
Common Docker Compose operations
docker compose ps
docker compose logs
docker compose logs --tail 100
docker compose restart
docker compose stop
docker compose start
docker compose down
docker compose up --detach
docker compose down removes the Compose-managed container and network, but the bind-mounted host directories remain outside the container. Avoid adding volume-removal options unless you understand exactly which storage Docker will delete.
Upgrade the container
The documented Compose upgrade sequence pulls the selected image, stops and removes the existing container, and creates a new container from the updated image:
docker compose pull
docker compose down
docker compose up --detach
After the upgrade, inspect the status and logs, then repeat a playback test:
docker compose ps
docker compose logs --tail 100
If the Compose file uses a fixed version tag, update that tag to the intended release before pulling. If it uses :latest, pulling retrieves the image currently associated with the stable tag. Review application release notes and maintain recoverable copies of persistent data before significant upgrades.
Back up persistent data
The /config mount contains the SQLite database and migration information. The /metadata mount contains metadata, images, logs, and backups. Both should be included in the host's backup strategy. Media directories should also be protected according to how replaceable the source files are.
The exact snapshot or file-copy method depends on the host filesystem, backup product, and storage design. For a consistent external backup, avoid copying a database while it is being changed unless the chosen backup method is designed for that purpose. A simple conservative approach is to stop the service during the copy window, back up the persistent host directories, and start it again. Validate restoration procedures on a separate test location rather than assuming that the existence of backup files guarantees recovery.
Avoid noisy container health checks
Audiobookshelf does not recommend health checks unless external monitoring is already in place. Continuously pinging the server and restarting it after a failed check is generally redundant when a restart policy is configured, and it can add unnecessary log noise. If a health check is deliberately implemented, note that the Audiobookshelf container includes wget but not curl.
Enable remote access with Localtonet
Once http://localhost:13378 works on the Docker host, remote access can be added as a separate layer. With Localtonet, the client application establishes an outbound connection to one of our relay servers. This provides a public URL without requiring inbound router port forwarding, firewall-wide changes, VPN setup, or a public IP address.
An HTTP tunnel is the relevant tunnel family because Audiobookshelf exposes a browser-based HTTP service. The Localtonet client must run on the Docker host or on another device that can reach the host and port selected as the local target.
Audiobookshelf explicitly requires a WebSocket connection. A working login page is not sufficient proof that the complete application works through a public endpoint. The tunnel path must preserve the HTTP upgrade used by WebSockets. Current Localtonet behavior and options can change by client version, so confirm WebSocket compatibility in the current HTTP tunnel documentation or dashboard and complete the functional tests below before relying on the public URL.
For the current product workflow and available options, consult the Localtonet HTTP tunnel documentation. Do not copy a relay server code, authentication token, domain setting, or endpoint from someone else's configuration.
Install and run the Localtonet client
Install the Localtonet application on the Docker host or another device that can reach the Audiobookshelf endpoint. Keep the client running whenever the remote address should remain available.
Authenticate or select the client device
Use the device-specific authentication token provided through your Localtonet account. Treat the token as a secret. Do not place it in this Compose file, application logs, screenshots, public repositories, or shared instructions.
Select an available relay server
Choose a relay server or region currently available in the Localtonet dashboard. Available server codes and regions should be taken from the current product interface rather than hardcoded from an article.
Create an HTTP tunnel
Create an HTTP tunnel and set its local target to the Audiobookshelf address reachable from the Localtonet client. When both run on the same machine and the documented Docker port is used, that target is typically local IP 127.0.0.1 and port 13378. If the client runs on another device, use the Docker host address that the client can actually reach.
Start the tunnel
Creating a tunnel does not start it. Use the Start control after reviewing the target. The assigned public HTTPS address becomes usable only while the selected client device is connected and the tunnel is running.
Test the assigned public address
Open the assigned public URL from a network outside the server's LAN. Sign in, browse a library, start playback, seek within an item, and confirm that progress-related behavior works. These functional checks are important because Audiobookshelf requires WebSockets in addition to ordinary HTTP traffic.
HTTP tunnels may use a generated subdomain, a selected subdomain where supported, or a custom domain. The available process types are Random Sub Domain, Custom Sub Domain, and Custom Domain, and each serves the same local content through a public HTTPS address. Availability can depend on the current product configuration or plan. Custom-domain DNS instructions should be taken from current Localtonet documentation rather than guessed.
Verify the remote path independently
Do not test only from a device that might still be using the local address. Disable Wi-Fi on a phone or use another external network, then open the assigned public URL. A complete test should include authentication, library navigation, playback, seeking, and any client behavior that depends on real-time updates.
If the page loads but interactive features fail, inspect the browser developer console and Audiobookshelf logs for failed WebSocket upgrades or repeated reconnect attempts. Also confirm that the tunnel targets the service directly and that no additional reverse proxy between the tunnel client and Audiobookshelf is stripping upgrade headers.
Secure the Audiobookshelf deployment
Publishing a private media server creates an internet-reachable login surface. Treat remote access as a deliberate security decision, not merely a connectivity setting. Use the smallest practical exposure, maintain the application, and stop the tunnel when remote access is no longer required.
The Docker example publishes host port 13378. Control local reachability with deliberate host and network rules instead of broad firewall disablement. If only the Localtonet client on the Docker host needs local access, there is usually no reason to make the service generally available to untrusted local networks. Exact binding and firewall configuration varies by operating system and is outside the verified project-specific evidence supplied for this guide.
Keep the administrative account for administration. If family members or other users only need playback access, use Audiobookshelf's multi-user permissions to avoid granting unnecessary control. Review users periodically and remove access that is no longer required.
Troubleshooting common installation and access problems
The container exits or repeatedly restarts
Start with the current container state and logs:
docker compose ps
docker compose logs --tail 200
Check for malformed YAML, an unavailable image, inaccessible host paths, permission failures, or a port conflict. Run docker compose config again after editing the Compose file.
Port 13378 is already in use
Change only the external side of the port mapping. For example, select an unused host port while retaining container port 80. Then use that new host port in the local browser address and Localtonet tunnel target. The exact replacement port is a local administrative choice, so this guide does not guess which port is available on your host.
A mounted library appears empty
Verify that the left side of the volume mapping points to the intended host directory. Then verify that Audiobookshelf is configured to use the right-side container path, such as /audiobooks. Confirm that the container can read the files and that mount points do not overlap.
Directory structure and folder names are important to Audiobookshelf's media organization. If files are visible but identified incorrectly, review the library's directory organization and media metadata rather than repeatedly recreating the container.
Settings disappear after recreation
This normally indicates that /config or /metadata was not mapped to the intended persistent host directory, or that the mapping changed between starts. Compare the active Compose configuration with the actual directories, and check whether those directories contain the expected application data.
The web page works locally but not through Localtonet
Confirm that the Localtonet client device can open the exact local target independently of the tunnel. Verify the target IP address and port, confirm that the client is connected, and confirm that the tunnel has been started. Remember that creating a tunnel alone does not make it active.
The remote login page loads but playback or updates fail
Audiobookshelf requires WebSocket connectivity. A partially working page can indicate that ordinary HTTP requests succeed while the WebSocket upgrade does not. Test from an external network, inspect browser errors, inspect Audiobookshelf logs, and confirm current Localtonet HTTP tunnel compatibility. If another reverse proxy is present, check its documented WebSocket settings as well.
An upgrade reports a missing /index.js module
Audiobookshelf documents Error: Cannot find module '/index.js' as a common problem when some container managers cache an old version during an update. Recreate the container from the newly pulled image. In Synology Container Manager, the documented remedy is to stop and reset the container. In Portainer, recreate the container or stack.
Resetting or recreating a container removes files that exist only inside its disposable filesystem. Verify the /config, /metadata, and media mappings before using a reset or recreation operation.
Frequently asked questions
What port does Audiobookshelf use with Docker?
The documented Docker example runs Audiobookshelf on port 80 inside the container and publishes it as port 13378 on the host using 13378:80. The resulting local address is normally http://localhost:13378 when accessed from the Docker host.
Is Docker the recommended way to install Audiobookshelf?
Yes. Audiobookshelf's installation documentation identifies Docker as the recommended way to run the server. Docker Compose is particularly useful because it records the image, port, volume, environment, and restart configuration in one file.
Can the Audiobookshelf configuration directory be stored on a NAS?
The /config mount should not be stored on network storage. It contains the SQLite database, which Audiobookshelf requires to be directly accessible on the same machine running the server. A network-mounted database may appear to work initially but can suffer poor performance and eventual corruption.
Does Audiobookshelf require WebSockets?
Yes. Audiobookshelf explicitly requires a WebSocket connection. Any tunnel or reverse proxy placed in front of the server must preserve the HTTP upgrade used by WebSockets. Test more than the login page by signing in, navigating libraries, starting playback, seeking, and checking progress-related behavior.
Do I need router port forwarding to access Audiobookshelf with Localtonet?
No. The Localtonet client establishes an outbound connection to our relay server, so the workflow does not require inbound router port forwarding or a public IP address. The selected client must remain connected and the HTTP tunnel must be running for the assigned public address to work.
Should I use the latest, edge, or a versioned Docker image?
Use :latest if you want to follow stable releases when you pull the image. Use a versioned tag when controlled upgrades and repeatable deployments are more important. Use :edge for testing changes from the master branch and reporting issues, not as the conservative default for a production library.
Why does Audiobookshelf use port 3333 or 3000 in some instructions?
Those ports are documented for source-development workflows. Port 3333 is the default development client endpoint, while port 3000 is used by a separate live-reloading client. The recommended Docker deployment described here publishes the application on host port 13378.
Can the Localtonet client run on a different device?
Yes, provided that device can reach the Audiobookshelf host and port. If the client runs on the same host, the target can normally use 127.0.0.1 and the published port. If it runs elsewhere, use an address reachable from that client and allow only the necessary local network access.
Connect your Audiobookshelf server with Localtonet
After Audiobookshelf is running and verified locally, create a Localtonet HTTP tunnel to provide remote access without inbound router port forwarding. Keep the tunnel target private, protect your application credentials, and verify WebSocket-dependent playback behavior from an external network.
Get Started Free โ