
Build a protected subtitle coordination service, verify it on your LAN, and expose only the dashboard you intend to use
Subarr is a self-hosted coordination layer for subtitle workflows involving services such as Sonarr, Radarr, Bazarr, subgen, Plex, Jellyfin, and Tautulli. This guide starts with the deployment itself: choosing an official Docker Compose security tier, preparing persistent storage, configuring integrations, starting the service, and testing the dashboard locally. Only after the installation is working and authentication has been verified do we connect the HTTP dashboard through Localtonet. The result is a practical remote-access workflow that does not require inbound router port forwarding, firewall changes, a VPN, or a public IP address.
📋 What's in this guide
What Subarr does and where Localtonet fits
Subarr stands beside the applications in an existing subtitle stack rather than replacing them. Bazarr remains responsible for finding and downloading subtitles, while subgen handles transcription. Subarr coordinates the wider workflow by evaluating subtitle coverage, identifying actionable gaps, measuring provider results, deciding when transcription is worthwhile, and presenting the resulting information through its web dashboard.
The service can work with Sonarr and Radarr libraries, Bazarr subtitle activity, subgen transcription, and Tautulli playback information. It can also request a targeted refresh from Plex or Jellyfin after a subtitle lands so that the media server can recognize the new sidecar without waiting for a scheduled library scan. A mixed Plex and Jellyfin household can configure both integrations.
Subarr does more than trust media metadata. Its documented workflow probes files before treating a missing subtitle as an actionable gap. Files that have not yet been examined remain visible as analyzing rather than being silently discarded or incorrectly queued. It can also perform calibrated audio-language detection using multiple chunks from a file and expose the result through its coverage workflow.
These capabilities mean the dashboard has meaningful control over a media automation environment. Depending on the selected deployment tier and configured integrations, Subarr may hold API keys, write subtitle sidecars into the media library, initiate downstream actions, or read selected container metadata. Remote access is therefore useful, but it should be added only after authentication, storage permissions, and integration scope have been reviewed.
/data.
An HTTP tunnel transports requests to the local dashboard. It does not make an unauthenticated application safe merely by placing it behind a public URL. Confirm that Subarr presents a login screen and rejects unauthenticated access before starting the tunnel.
Prerequisites and deployment decisions
This guide uses the project’s official Docker Compose deployment templates. Before beginning, prepare a machine that can run Docker containers and reach the media applications that Subarr will integrate with. Docker Compose must be available through the docker compose command. You also need a persistent location for Subarr’s own data and access to the media library if Subarr will write subtitle sidecars.
Record the host user and group identifiers that own the data directory and media files. The hardened deployment guidance uses PUID and PGID so the non-root container process can operate with an appropriate host identity. Do not choose arbitrary identifiers. Use the values belonging to the account that should own Subarr’s data and that has the required access to the media library.
On a Linux host, the following commands display the current user’s numeric identifiers:
id -u
id -g
You should also know the absolute host path to the media library. The official environment example names this setting MEDIA_ROOT. Use the real path already mounted on the Docker host. Do not substitute an example path unless it accurately represents your storage.
If Sonarr, Radarr, Bazarr, Tautulli, or related services run as containers on the same Docker host, identify the user-owned bridge network that connects them. The official production templates refer to this external network as media-stack, but the template documentation explicitly says to rename it to match the network already used by your deployment.
If you do not already have a shared bridge network and attaching the existing media containers to one is appropriate for your architecture, the documented example creates it with:
docker network create media-stack
Creating a network alone is not enough. The relevant existing containers must also join it. Changing networks can affect name resolution and connectivity, so inspect the current media stack before editing a working deployment. If the applications are on different hosts or use a networking mode that cannot join the shared bridge, Subarr can instead use reachable host addresses and published ports.
The path used for SUBARR_DB_PATH, whose documented default is /data, must point to a dedicated Subarr data volume or directory. Never point the database path at the media library. Subarr treats its data directory and the media mount as different ownership domains, and the container may reconcile ownership of its own data directory during startup.
Checklist before installation
- A functioning Docker Engine installation with Docker Compose.
- A dedicated persistent directory or volume for Subarr application data.
- The numeric user and group IDs that should run the container.
- The absolute host path to the media library.
- Write permission to the media location if Subarr will create subtitle sidecars there.
- Reachable URLs and API keys for manually configured integrations.
- The name of the existing Docker network, if container-name discovery will be used.
- A current Localtonet client installed later on the Subarr host or another device that can reach it.
Choose the appropriate Subarr permission tier
The official deployment template directory provides three production-oriented Compose tiers. They differ mainly in what Subarr can inspect automatically during onboarding. The best fit depends on whether you prefer manual setup, metadata-based discovery, or API-key extraction from mounted configuration files.
| Tier | Template | What Subarr can access | Operational tradeoff |
|---|---|---|---|
| Tier 1 | tier1-no-docker.compose.yaml |
No Docker daemon access. Integration URLs and API keys are entered manually. | Smallest discovery-related blast radius, with more manual onboarding. |
| Tier 2 | tier2-socket-proxy.compose.yaml |
Read-only container metadata exposed through a restricted Docker socket proxy. | Automatic URL and version discovery while API keys remain manually supplied. |
| Tier 3 | tier3-config-mounts.compose.yaml |
Tier 2 metadata plus selected read-only configuration-directory mounts. | Can extract integration API keys, but exposes more sensitive configuration to Subarr. |
Tier 1: maximum isolation from Docker
Tier 1 is the simplest security boundary to reason about. Subarr receives no Docker socket access, so it cannot use the daemon to discover nearby services. You provide each integration URL and API key yourself. This tier is also appropriate when Subarr and the rest of the media stack are on different hosts.
Manual configuration requires more work, but it avoids making Docker metadata available to the application. For a remotely accessible dashboard, Tier 1 is a strong baseline when automatic discovery is not important.
Tier 2: restricted metadata discovery
Tier 2 adds a hardened Docker socket proxy. Subarr talks to that proxy rather than mounting the Docker socket directly. The documented proxy policy exposes only the metadata endpoints needed for container lists, network lists, image information, and ping. It does not permit Subarr to start, stop, restart, kill, or pause containers, execute commands in them, pull images, build images, mount volumes, read logs, or inspect Docker secrets and swarm state.
This tier can prefill service URLs by matching container images against known media applications. API keys still have to be entered manually. It provides a middle ground between manual setup and broad configuration access.
Tier 3: read-only configuration mounts
Tier 3 adds read-only mounts for selected application configuration directories. This can allow Subarr to obtain API keys from Bazarr, Sonarr, Radarr, or Tautulli configuration files. The convenience comes with a clear security cost: a process able to read those mounted files can also read the credentials they contain.
Every such configuration mount must retain its read-only :ro mode. Subarr does not require write access to those configuration directories. The templates permit per-integration opt-in, so an administrator can omit a mount and enter that service’s key manually.
The documented Tier 2 and Tier 3 designs use a restricted socket proxy. Replacing that boundary with a direct Docker socket mount would materially expand the application’s control over the host and would no longer represent the documented hardened design.
Install Subarr with Docker Compose

The steps below use an official production template instead of constructing a Compose file from memory. This avoids guessing container paths, capabilities, health checks, network declarations, or supporting-service settings that can change as the project evolves.
Download the Subarr repository
Clone the public repository and enter its deployment template directory. This provides the maintained Compose templates and matching environment example.
Copy the selected production template
Choose Tier 1, Tier 2, or Tier 3 based on the permission model above. Copy that file to compose.yaml in a dedicated stack directory rather than editing the upstream template in place.
Create and edit the environment file
Copy .env.example to .env. Set the timezone, host user and group identifiers, and the absolute media-library path. Add tier-specific integration or configuration paths only when they apply.
Review images, volumes, capabilities, and networks
Use a specific tested image tag instead of :latest for a hardened deployment. Confirm that the data volume is dedicated to Subarr, media access matches the intended read or write behavior, Tier 3 configuration mounts are read-only, and the external network name matches your stack.
Validate the rendered Compose configuration
Run docker compose config from the stack directory. Review the rendered result for unresolved variables, unexpected host paths, accidental writable mounts, and incorrect network names before creating containers.
Start the deployment
Run docker compose up -d. Compose creates or updates the services and returns control to the terminal while the containers continue in the background.
The repository can be downloaded with:
git clone https://github.com/coaxk/subarr.git
cd subarr/deploy/templates
Create a separate stack directory, copy the chosen template into it, and copy the accompanying environment example. The following example selects Tier 1. Replace the destination with the location where you maintain Compose applications:
mkdir -p ~/subarr-stack
cp tier1-no-docker.compose.yaml ~/subarr-stack/compose.yaml
cp .env.example ~/subarr-stack/.env
cd ~/subarr-stack
If you choose Tier 2 or Tier 3, copy the corresponding official filename instead. Do not combine fragments from different tiers without understanding how the proxy, networks, mounts, and environment settings work together.
Configure the environment
Open .env with your preferred text editor. The maintained example identifies these general settings:
TZ=your_timezone
PUID=your_numeric_user_id
PGID=your_numeric_group_id
MEDIA_ROOT=/absolute/host/path/to/media
These are placeholders, not literal production values. Use a valid timezone for the host environment, the IDs obtained from id -u and id -g, and the real absolute media path.
Tier 1 requires manual integration details. The environment example includes variables for integration URLs and API keys, including Bazarr, Sonarr, Radarr, and Tautulli settings. Enter only real internal service addresses that the Subarr container can reach. Never commit the completed .env file to a source repository or paste it into support messages.
Tier 2 and Tier 3 can use the setup wizard’s discovery behavior, so integration URL and key variables may be optional depending on the selected integration and tier. Tier 3 also requires host paths for the configuration directories that you deliberately permit Subarr to read.
Pin container images
Basic installation examples may use ghcr.io/coaxk/subarr:latest, but the hardened deployment instructions explicitly advise against relying on :latest. Pin a specific image version that you have selected and tested. The same principle applies to the Docker socket proxy image in Tier 2 or Tier 3.
The supplied evidence identifies version 2.5.1 as the latest release at the time it was captured, but release status can change. Confirm the current project release and its published container tag before editing the template. We do not assume a registry tag when the exact tag is not established by the available installation evidence.
Validate and start
docker compose config
docker compose up -d
docker compose ps
The validation command renders the effective configuration without starting the stack. Examine it carefully because environment substitution can turn a small typographical error into an incorrect host mount. After startup, docker compose ps should show the expected services rather than containers repeatedly restarting.
If startup fails, inspect service output:
docker compose logs
docker compose logs --tail=200
Logs can contain paths, hostnames, or integration information. Remove secrets before sharing any excerpt.
Complete first-run onboarding and secure the account
Once the service is running, open the documented local endpoint from the Docker host:
http://localhost:9922
Current Subarr 2.x documentation describes authentication as enabled by default and presents a one-time login setup on first launch. Create the administrator account using a unique password that is not shared with Sonarr, Radarr, Bazarr, the Docker host, or your Localtonet account.
Some deployment-template text captured from the project states that authentication is off until SUBARR_USER and SUBARR_PASS are supplied, while the current main README states that authentication has been on by default since version 2.0. This is version-sensitive and the two pieces of project material are inconsistent. Treat the running behavior as authoritative for your installation: open a private browser session and confirm that an unauthenticated request is redirected to login or otherwise rejected. Do not start a public tunnel until that test succeeds.
Existing installations that already define SUBARR_USER and SUBARR_PASS, or an application API key, are documented to retain that authentication path during a 2.x upgrade. The project also documents SUBARR_AUTH_DISABLED=1 for environments where an authenticating reverse proxy is intentionally responsible for access control.
Do not disable built-in authentication merely because Localtonet provides the transport. If you deliberately delegate authentication to another component, verify that no alternative route can reach Subarr without passing through that component.
Configure integrations deliberately
Tier 1 users enter every integration address and API key manually. Tier 2 can discover selected service URLs and versions from restricted Docker metadata, but keys still require manual entry. Tier 3 can obtain keys from the configuration directories that were explicitly mounted read-only.
Confirm each suggested URL before accepting it. Container-to-container addresses often differ from browser addresses. For example, a browser may use a host port while containers on a shared bridge network use the target container’s network name and internal service port. Use the address that is reachable from inside the Subarr deployment.
Configure only the integrations you actually use. A Plex-only household does not need Jellyfin credentials, and a Jellyfin-only household does not need Plex access. Subarr can be pointed at both when the environment includes both systems.
Current project behavior can derive library path prefixes from the locations reported by Plex and Jellyfin, reducing the need for manual path-prefix mapping. Explicit environment variables still take precedence when configured, so remove stale overrides if they conflict with the storage layout reported by the media server.
Review optional behavior
Forced subtitles for foreign-language scenes are documented as disabled by default. When enabled, Subarr performs local language identification and can produce a forced subtitle covering relevant segments instead of transcribing an entire title. Enable this only after reviewing its rule settings and observing results against representative media.
Automatic subtitle re-timing, tuning behavior, scheduled library walks, provider decisions, and aftercare can all affect downstream work. Start conservatively. Confirm integration connectivity and coverage analysis before enabling broad automated actions across a large library.
Verify Subarr locally before remote exposure
A container marked as running is not sufficient verification. Test the actual HTTP service, authentication boundary, storage, and integration reachability while the dashboard remains local.
Open the local dashboard
Visit http://localhost:9922 on the Docker host. If using another LAN device, use the Docker host address only if the Compose port publication permits LAN access.
Test the unauthenticated state
Use a private browser window with no existing session. Confirm that the application requires authentication and does not reveal dashboard or API content anonymously.
Check persistent state
Complete a controlled configuration change, restart the Compose stack, and verify that the setting and administrator account remain present. This confirms that application data is using persistent storage.
Inspect health and integrations
Review the Health page and test each configured service. Resolve unreachable URLs, rejected API keys, and media-path problems before enabling wider automation.
Perform a limited workflow test
Use a small, known media sample to confirm analysis, subtitle handling, sidecar permissions, and media-server refresh behavior. Avoid beginning with an unrestricted library-wide operation.
Restart the stack with:
docker compose restart
docker compose ps
After the restart, sign in again and confirm that the onboarding state did not reset. If configuration disappears, stop and correct the data volume before doing more work.
Subarr supports SQLite storage on NFS or SMB by selecting a journal mode intended to survive network filesystems rather than using WAL there. Even so, the project continues to recommend local disk for the data directory. A media library can live on network storage while the database remains on a dedicated local volume.
A successful login proves only that the web process responds. A controlled test should also confirm media visibility, subtitle sidecar permissions, API access to the selected integrations, and the expected refresh behavior in Plex or Jellyfin.
Connect the Subarr dashboard through Localtonet

After local verification, an HTTP tunnel can make the dashboard reachable without opening an inbound router port. Our client runs on the Subarr host or another device that can reach it and establishes an outbound connection to a Localtonet relay server. The running tunnel then supplies a public HTTPS address that forwards requests to the local HTTP target.
If our client runs directly on the Docker host and the Compose deployment publishes Subarr on the documented local endpoint, the target is normally 127.0.0.1 with port 9922. If the client runs on another device, use an address for the Docker host that is reachable from that device. Test that exact address from the Localtonet client device before creating the tunnel.
Install and run the Localtonet client
Install our client on the Subarr host or on a device that can reach the verified HTTP endpoint. Keep the client running because the tunnel is available only while the selected device is connected and the tunnel itself is running.
Authenticate or select the client device
Use the device-specific token provided by the current Localtonet dashboard. Tokens identify client devices and must not be guessed, embedded in Compose files, committed to source control, or shown in screenshots.
Select an available relay server
Choose a server or region from the values currently available in the dashboard. Availability can vary, so this guide does not hardcode a relay server code.
Create the HTTP tunnel configuration
Select the HTTP tunnel family and point its local target to the reachable Subarr address and port. For a client on the Docker host, use 127.0.0.1 and 9922 after confirming that this local endpoint works.
Choose the HTTP process type
Select Random Sub Domain, Custom Sub Domain, or Custom Domain according to the options available for your account and current configuration. Each process type serves the target through a public HTTPS address. Check current documentation before configuring custom-domain DNS.
Start and test the tunnel
Creating a tunnel does not start it. Press Start, open the assigned public URL in a private browser session, and verify that Subarr requires authentication before any dashboard content is displayed.
The current HTTP tunnel workflow is also described in our Localtonet HTTP tunnel documentation. Use the current dashboard values for device tokens, relay selection, and available process types rather than copying values from another installation.
Subarr can coordinate jobs and communicate with privileged media services. Use a unique administrator password, keep authentication enabled, avoid sharing the tunnel URL publicly, and stop the tunnel when remote access is not needed. Never place integration API keys, Localtonet device tokens, or private service URLs in a public issue or screenshot.
Test from outside the LAN
A valid remote test should use a connection that does not silently fall back to the local network, such as a mobile connection with Wi-Fi disabled. Open the assigned HTTPS URL in a private browser session and confirm the following:
- The URL loads while the Localtonet client and tunnel are running.
- An unauthenticated visitor receives a login challenge rather than dashboard data.
- The administrator can sign in with the expected account.
- Normal dashboard navigation and API-backed views load correctly.
- Logging out invalidates access to protected pages.
- Stopping the tunnel makes the public address unavailable.
Do not treat possession of an obscure URL as authentication. Public addresses can be copied, logged, stored in browser history, or disclosed accidentally. The application login remains the primary access boundary in this workflow.
Routine operation, backups, and updates
Start, stop, and inspect Subarr
docker compose up -d
docker compose stop
docker compose start
docker compose ps
docker compose logs --tail=200
Run these commands from the stack directory containing compose.yaml and .env. Stopping containers preserves their configuration and persistent volume. Removing containers is a different action, and deleting the persistent data volume can remove the database and administrator state.
Back up the dedicated data directory
Back up the persistent location mapped to Subarr’s data directory. The project also stores its LaBSE quality-estimation cache beneath the data directory at .cache/huggingface. Older deployments that mounted a cache beneath /root/.cache should review the current upgrade guidance because the container now runs as a non-root process.
A useful backup policy protects the application database, configuration, and any other persistent state required to rebuild the service. Test restoration separately. A backup that has never been restored is not yet evidence that recovery will work.
Update without losing state
With a pinned image, updating is an intentional operation. Read the release notes, update the image reference to the chosen version, pull it, and recreate the affected services:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
Inspect logs and the Health page after the update. The documented 2.0 release introduced the significant authentication and non-root-container changes. Releases after 2.0 are described as upgrading transparently, but administrators should still keep a current backup and review version-specific notes.
For hardened Compose deployments, the non-root container reconciles ownership of its own data directory at boot. The documented hardened configuration adds the capabilities needed for that operation alongside a general capability drop and uses PUID and PGID matching the owner of the data and media mounts. Preserve the exact capability design in the maintained template rather than reconstructing it from a partial example.
Control the tunnel lifecycle
A Localtonet tunnel exists independently from the Subarr container. Starting Subarr does not automatically start a tunnel unless you have separately arranged the supported Localtonet client lifecycle. Likewise, creating a tunnel in the dashboard does not mean it is running.
Start the tunnel when remote access is required and stop it when the dashboard should return to local-only access. Deleting a tunnel removes its configuration, while stopping it preserves the configuration for later use. The public endpoint works only while the selected client device remains connected and that tunnel is running.
Troubleshooting common setup and access problems
The dashboard does not open at localhost:9922
Begin with docker compose ps. If the Subarr service is restarting or exited, inspect its logs. Common categories include an invalid environment value, an unavailable host mount, permission failure on the data directory, incorrect network declaration, or a port conflict.
Confirm that the effective Compose configuration publishes the intended service and that another process is not already using the host port. Do not change the documented port in one location while leaving Localtonet pointed at the old value.
Subarr starts but loses its settings after restart
This usually indicates that the application data directory is not backed by the intended persistent mount. Review the rendered output from docker compose config, locate the volume mapped to the container’s dedicated data path, and confirm that it points to stable storage.
Never solve this by redirecting the database into the media tree. Correct the dedicated data mount instead.
The container reports permission errors
Check ownership of the host data directory and media library. Compare it with the configured PUID and PGID. Subarr needs appropriate access to its own data, and subtitle-sidecar operations require the intended permissions on the media location.
Avoid making the entire library world-writable. Correct the service account, group membership, ownership, or narrowly scoped permissions instead.
Subarr cannot reach Sonarr, Radarr, or Bazarr
Verify the URL from the perspective of the Subarr container. A loopback address such as localhost inside a container refers to that container, not automatically to another service or the Docker host. When applications share a user-defined bridge network, use the appropriate container network name and service port. When they run elsewhere, use a host address reachable from the container.
Also confirm that the target service accepts the supplied API key and that no stale explicit environment variable overrides a value discovered by the wizard.
Tier 2 discovery does not find containers
Confirm that the socket proxy is healthy, its required metadata endpoints remain enabled, and Subarr can reach it on the internal network. Do not broaden the proxy policy indiscriminately. If discovery remains unsuitable, Tier 1 manual configuration is a valid alternative and avoids Docker metadata access.
Tier 3 cannot extract an API key
Check that the correct host configuration directory is mounted at the path expected by the maintained template and that the mount remains read-only. Verify that the host account permits the container process to read it. A manual key entry is safer than making an entire configuration tree writable.
The Localtonet public URL is unavailable
Verify the dependencies in order:
- Subarr responds locally at the target address and port.
- The device running our client can reach that exact target.
- The Localtonet client is connected using the intended device token.
- The configured relay selection is currently available.
- The HTTP tunnel has been started, not merely created.
If our client runs in a different network namespace or on another machine, 127.0.0.1 will refer to that client device rather than the Docker host. Use a reachable LAN address in that arrangement and protect the LAN route appropriately.
The public URL works but authentication is missing
Stop the tunnel immediately. Recheck the installed Subarr version and authentication settings. Test in a private browser window to eliminate an existing session. If authentication was intentionally delegated to a reverse proxy, confirm that the Localtonet target cannot route around that proxy.
The project documents recovery options for a locked-out administrator, including an authentication-reset environment setting and a container CLI reset command. Because changing environment settings can alter the security boundary, use the current project guidance for the installed version and remove temporary reset settings after access is restored.
Media on NFS or SMB causes database warnings
Keep the media library and application database concerns separate. Current Subarr versions can select a safer SQLite journal mode when the data directory is on NFS or SMB, but local storage for /data remains the project recommendation. Moving only the dedicated application data to local disk can resolve database-storage concerns without moving the media library.
Frequently asked questions
What local port does Subarr use?
The documented local web endpoint is http://localhost:9922. When our Localtonet client runs on the Docker host, an HTTP tunnel can target 127.0.0.1 and port 9922, provided that exact endpoint has already been verified locally.
Does Localtonet require router port forwarding?
No. Our client establishes an outbound connection to a Localtonet relay server. This lets the running tunnel provide a public URL without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.
Is Subarr authentication enabled by default?
Current 2.x README material states that authentication is enabled by default and that first launch presents administrator setup. An older or inconsistent deployment-template note says authentication must be enabled with credential environment variables. Because those statements conflict, verify the behavior of the exact image you deploy. A private browser session must receive a login challenge before you expose the service.
Which Subarr deployment tier is safest?
Tier 1 exposes the least Docker-related information because it provides no Docker daemon access and requires manual integration setup. Tier 2 exposes restricted read-only metadata through a socket proxy. Tier 3 additionally exposes selected configuration files read-only so keys can be extracted. Choose the least privilege that still supports the onboarding experience you need.
Should I use the latest Subarr image tag?
The hardened deployment guidance says not to rely on :latest. Select a specific published version, review its release notes, test it, and update intentionally. Apply the same pinning principle to the Docker socket proxy used by Tier 2 or Tier 3.
Can Subarr use both Plex and Jellyfin?
Yes. Current project documentation describes support for configuring Plex, Jellyfin, or both. When a subtitle lands, Subarr can request a targeted refresh from the owning media-server item so the subtitle appears without waiting for a scheduled scan.
Can I keep Subarr data on an NFS or SMB share?
Current versions account for network filesystems by selecting a SQLite journal mode intended to avoid unsafe WAL behavior there. The project still recommends keeping the dedicated Subarr data directory on local disk. The media library itself can remain on network storage.
Does creating a Localtonet tunnel make it immediately available?
No. A created tunnel must be started. It remains available only while the selected Localtonet client device is connected and the tunnel is running. You can later stop it to preserve the configuration or delete it when it is no longer needed.
Connect your verified Subarr dashboard with Localtonet
Finish the local installation, confirm that authentication protects the dashboard, and then create an HTTP tunnel to the verified Subarr endpoint. Our outbound tunnel workflow gives you remote HTTPS access without opening an inbound router port.
Get Started Free →