Deploy Muxarr safely, validate media processing, and provide controlled remote access
Muxarr removes unwanted audio and subtitle tracks, cleans track metadata, and can automate processing alongside Sonarr and Radarr. This guide deploys it with Docker Run, plans persistent storage and permissions, verifies local HTTP access, and completes a conservative first test. It also covers backups, updates, rollback, and troubleshooting. After the local service is reliable and authenticated, we connect it to an HTTP tunnel with Localtonet without inbound router port forwarding or a public IP address.
๐ What's in this guide
What Muxarr does and how the deployment fits together
Muxarr helps administrators remove unnecessary tracks from self-hosted media libraries. Its official website documents unwanted audio and subtitle removal without re-encoding, per-directory profiles, language priorities, track limits, and metadata cleanup. It also describes original-language detection and import automation through optional Arr integrations.
The project documents output validation before replacing an original file and states that a failed operation leaves the original untouched. It specifically identifies mkvpropedit for metadata-only changes that do not require a remux. These are processing safeguards, not a substitute for backups or a guarantee that a profile preserves every track you intended to keep.
The current website does not enumerate a complete supported-extension matrix or every format-specific processing tool. Accordingly, this guide does not promise support for particular MP4-family or WebM extensions or prescribe an internal FFmpeg workflow. Check the documentation for your installed release through the official Muxarr repository, then test representative files before expanding a profile to your library.
/media, /movies, or /tv, separate from application configuration.
Our deployment has three separate responsibilities: Docker runs Muxarr, host storage preserves configuration and media, and Localtonet provides optional remote connectivity. Keeping those responsibilities separate makes failures easier to diagnose and prevents public access from becoming a prerequisite for local setup.
Prerequisites and deployment decisions
The Muxarr website lists images for linux/amd64 and linux/arm64. You need a compatible Docker environment running Linux containers, persistent storage, a browser, and a small collection of copied or independently backed-up media for testing. Keep spare storage available for processing output; the project evidence supplied here does not establish a universal free-space requirement.
For Linux, follow the distribution-specific Docker Engine installation instructions. For Windows or macOS, use Docker Desktop installation guidance and configure access to the directories you intend to mount. NAS installations may require the vendor's supported container package. The commands below use a Bash-compatible shell and Linux-style host paths; adapt paths and shell syntax if administering Docker from another environment.
Verify Docker before proceeding
docker version
docker info
uname -m
docker version should show both client and server information, and docker info should return daemon details without connection or permission errors. Common architecture names are x86_64 for AMD64 and aarch64 or arm64 for ARM64. On Docker Desktop, also confirm the engine is using Linux containers.
Use your host's supported Docker administration method. Do not make the Docker socket broadly accessible to fix a permission error: control of that socket typically grants extensive control over the host. Installing Docker is platform-specific, but the remaining workflow starts from the same verified, working daemon.
Plan configuration, mounts, and identity
Muxarr stores its database and configuration at /config in the current installation example. Bind that destination to a durable host directory. Media uses separate mounts whose container paths you choose. Stable container paths matter because profiles and integration mappings can refer to them even if host storage later moves.
| Setting | Purpose | Planning guidance |
|---|---|---|
/config | Database and application configuration | Use persistent storage and include it in pre-update backups. |
| Media mounts | Files scanned and processed | Expose only intended directories through stable container paths. |
PUID and PGID | Filesystem identity | The website lists defaults of 888; set IDs appropriate to your host permissions. |
UMASK | Permissions on newly written files | The documented default is 022; 002 is the project's group-writable example. |
TZ | Application timezone | The documented default is UTC; choose the appropriate timezone. |
| Published port | Web-interface reachability | Select loopback, a specific host address, or all interfaces deliberately. |
On Linux, identify the account whose filesystem access you intend to use:
id -u
id -g
id
Use the numeric results for PUID and PGID only if that account has the intended access. The value 1000 in the example is not universal. Configuration must be writable; media processing requires the relevant directory and file permissions, not merely permission to list a library.
Choose where port 8183 listens
The project's -p 8183:8183 mapping normally publishes container port 8183 on all host interfaces. This can expose Muxarr to other LAN devices independently of Localtonet. For a Localtonet client installed directly on the Docker host, prefer a loopback-only binding when no LAN access is needed:
-p 127.0.0.1:8183:8183
A client running on another device cannot reach the Docker host through its own 127.0.0.1. In that layout, publish Muxarr on a reachable host address and test it from the client device. The same distinction applies if the client runs in a separate container: container loopback is not host loopback. This guide's simplest layout installs our client directly on the Docker host.
Begin with a small copied test collection. Keep independent media backups and configuration backups. Do not mount an entire host filesystem or grant world-writable permissions merely to avoid planning ownership and groups.
Install Muxarr with Docker Run
The official Docker Run installation consists of a container command, followed by a separately described first-run wizard. Directory preparation and diagnostic checks below are operational guidance, not additional steps attributed to the project's installation procedure.
Prepare host directories
Replace these placeholders before executing commands. Create configuration storage, but use the actual existing media location rather than accidentally creating an empty substitute:
mkdir -p /path/to/muxarr/config
ls -ld /path/to/muxarr/config /path/to/your/media
Check ownership and permissions. If media lives on network storage, confirm the share is mounted before starting the container. Otherwise, Docker may bind an empty local directory, and the library will appear empty. For the first deployment, point the media source at your test collection instead of the full library.
Run the Muxarr container
Use the project's Docker Run command with your timezone, numeric IDs, persistent configuration path, and media path. Select the intended port binding before executing it.
docker run -d \
--name=muxarr \
-e TZ=Europe/Amsterdam \
-e PUID=1000 \
-e PGID=1000 \
-p 8183:8183 \
-v /path/to/muxarr/config:/config \
-v /path/to/your/media:/media \
--restart unless-stopped \
ghcr.io/kirovair/muxarr:latest
The command above preserves the published all-interface example. For the same-host Localtonet layout, replace its port line with -p 127.0.0.1:8183:8183. Do not run both variants under the same container name. Add separate media mounts only when needed, keeping each destination stable.
If group-writable output is intentional, add -e UMASK=002. This affects the permission mask for files Muxarr writes; it does not repair existing ownership, add group membership, or override network-storage restrictions.
Docker cannot change an existing container's published port mapping in place. To change it later, preserve and back up persistent data, then recreate the container with the reviewed run command. Keep a private copy of that command so future updates do not depend on reconstructing every option from memory.
ghcr.io/kirovair/muxarr:latest can identify different software after a new publication. Review the project's releases through its official repository and record the actual image used before updates. A tag, a local image ID, and a registry digest serve different purposes, explained below.
Verify the container and local HTTP service
Verify Docker state, storage, and HTTP independently. A running container is not proof that the application is ready, and a web page is not proof that the correct library was mounted.
Inspect status, logs, mounts, and ports
docker ps -a --filter name=muxarr
docker inspect -f '{{.State.Status}}' muxarr
docker logs --tail 100 muxarr
docker inspect -f '{{json .Mounts}}' muxarr
docker port muxarr
docker inspect -f '{{.Config.Image}}' muxarr
The state should be running, without recurring startup failures. Confirm the configuration source maps to /config, the media source is your test library, and port 8183 uses the intended host binding. Follow live logs with docker logs --follow muxarr while reproducing a problem, then interrupt the log viewer normally. Review logs for private paths or credentials before sharing them.
Use an HTTP GET, not a HEAD-only probe
From the Docker host, run:
curl --silent --show-error --output /dev/null \
--connect-timeout 5 --max-time 15 \
--write-out 'HTTP status: %{http_code}\n' \
http://127.0.0.1:8183/
printf 'curl exit code: %s\n' "$?"
This sends a normal GET while discarding the body. It reports the HTTP status and displays connection errors. A connection refusal or timeout produces a nonzero curl exit code, usually with status 000. A received HTTP response can still be an application error: this command intentionally does not treat all HTTP error statuses as transport failures.
A 2xx response usually indicates successful retrieval; a 3xx may redirect to setup or login. A 401 or 403 demonstrates HTTP reachability but requires investigation of authentication or authorization. A 5xx means the service is reachable but unhealthy. Open the browser to confirm the expected page, assets, and login behavior instead of accepting any status as proof of readiness.
If the Localtonet client runs elsewhere, execute the same check on that device with the Docker host's reachable address:
curl --silent --show-error --output /dev/null \
--connect-timeout 5 --max-time 15 \
--write-out 'HTTP status: %{http_code}\n' \
http://docker-host-address:8183/
printf 'curl exit code: %s\n' "$?"
Replace the placeholder. If this test fails, correct the binding, routing, or permitted host-network access before creating the tunnel. Do not use curl -I as the only check: it sends HEAD, which an application may handle differently from browser GET requests.
Complete first-run configuration and test a profile
Open http://127.0.0.1:8183 on the Docker host, or the verified reachable host address. The following four actions preserve the first-run order published on the Muxarr website.
Set a username and password
The project marks credentials as optional. For this remote-access workflow, configure strong, unique credentials before publishing the interface.
Optionally connect Sonarr and Radarr
Connect them for original-language detection and webhook automation, or skip integration while validating standalone operation.
Create a profile
Select media directories using paths visible inside the container and configure language rules for the test collection.
Scan, preview, and queue files
Scan the limited library, inspect proposed changes, and queue a copied or backed-up file before allowing broader processing.
Review rules against actual tracks
Muxarr documents language priorities, ordering, per-language track limits, and choices between best quality and smallest size. Choose rules for the collection rather than copying a generic profile. Preview commentary tracks, forced subtitles, hearing-impaired subtitles, undefined language tags, and regional variants carefully. Metadata can be incomplete or misleading.
After processing, play the result in your normal media player. Check primary audio, required subtitles, seeking, duration, and access from other library applications. Output validation cannot determine whether a removed commentary track was important to you.
Verify permissions after processing
Inspect the resulting file's owner, group, and permissions on the host. Confirm that applications responsible for renaming or moving media can still do so. A group-writable umask only helps when the group identity and directory permissions are consistent across the workflow.
Check numeric IDs, directory ownership, group access, mount mode, and network-storage rules. Reading a file does not prove the container can create output or replace it. Grant only the access needed for the directories being processed.
Application authentication and transport security also solve different problems. Localtonet provides a public HTTPS address for the HTTP tunnel; Muxarr credentials control application access. Neither replaces least-privilege host storage or an independent backup.
Optional Sonarr and Radarr integration
The Muxarr feature and setup descriptions confirm optional Sonarr and Radarr connections and a configurable automation delay so tools such as Bazarr can finish first. Start with manual scanning and processing before adding import automation.
The available primary material does not establish a complete field-by-field integration procedure or webhook payload. Use the interface and documentation matching your installed version for those details. Likewise, this guide does not assert a statistics API route or authentication-header contract without verified API documentation. Do not build an integration around an assumed endpoint.
Use addresses reachable from the container
A service address that works in the host browser may not work inside Muxarr. In particular, localhost inside the container refers to that container. Use the service address appropriate to your container network, and keep Arr API keys out of screenshots, URLs, shell history, and support messages.
Keep filesystem paths consistent
Separate containers can see the same file under different paths. If Sonarr reports a location different from Muxarr's mount destination, configure the supported path mapping so it resolves to the actual file inside Muxarr. An authenticated integration can still fail because a reported file does not exist at the translated path.
Test one imported file: confirm the Arr application emits the event, Muxarr receives it, the mapped path resolves, the intended profile applies, and any delay has elapsed. Inspect the processed result before enabling unattended processing across the production queue. There is no need to expose Sonarr or Radarr publicly merely to connect them internally.
Backups, updates, image pinning, and rollback
The container is replaceable; configuration and media are not. Save your run command, mount layout, permission choices, and image identity alongside a protected backup. Stop processing before storage maintenance or an update, and avoid interrupting active media work when possible.
Routine container operations
docker stop muxarr
docker start muxarr
docker restart muxarr
docker ps -a --filter name=muxarr
docker logs --tail 100 muxarr
Use these commands individually as needed. The unless-stopped restart policy supports restarting the container after eligible daemon or host restarts, except when explicitly stopped. It does not replace monitoring or post-restart verification.
Make a consistent configuration backup
For a simple file-level backup, stop Muxarr before archiving its configuration directory. Create the archive outside that directory:
docker stop muxarr
tar -czf muxarr-config-pre-update.tar.gz -C /path/to/muxarr/config .
tar -tzf muxarr-config-pre-update.tar.gz
Use a unique archive name for each update rather than overwriting the only known-good copy. If this is routine backup rather than an update, restart with docker start muxarr afterward. Protect the archive because configuration may contain credentials. Store another copy independently of the host, and test restoration with ownership and permissions preserved. Media requires a separate backup strategy.
Record the image actually used by the container
IMAGE_ID=$(docker inspect -f '{{.Image}}' muxarr)
printf '%s\n' "$IMAGE_ID"
docker image inspect "$IMAGE_ID" --format '{{json .RepoDigests}}'
docker inspect muxarr > muxarr-container-inspect.json
Inspect the running container's image ID, not merely the current local latest tag, which may already point elsewhere. Keep inspection output private because it contains environment values and operational details.
| Identifier | Meaning | Operational use |
|---|---|---|
Tag such as :latest | A mutable name pointing to an image | Convenient for discovery, but not a reproducible deployment identity. |
| Local image ID | Docker's identifier for the locally stored image configuration | Can recreate a container while that image remains available locally; it is not interchangeable with a registry digest. |
| Repository digest | A content-addressed registry reference using @sha256:โฆ | Can pin a registry pull or run to the recorded manifest rather than a moving tag. |
If RepoDigests contains the appropriate reference, copy that complete repository-and-digest string into your deployment record. To pin a run, replace the image argument with the actual recorded reference, not a fabricated digest. Registry availability and the selected platform still matter. If no digest is recorded, preserve the local image explicitly instead of assuming a tag will recover it.
An additional local recovery measure is an image archive:
docker image save -o muxarr-image-pre-update.tar "$IMAGE_ID"
Use a unique filename and retain it with the matching configuration backup. Restore an image archive with docker image load -i muxarr-image-pre-update.tar. An image archive contains software, not your bind-mounted configuration or media.
Update and validate
Review the current release notes through the official repository. With processing stopped, the pre-update backup complete, and the previous image recorded or archived:
docker pull ghcr.io/kirovair/muxarr:latest
docker rm muxarr
The removal command assumes the container is already stopped. Recreate it with your saved Docker Run command, preserving the configuration host directory, all media destinations, environment values, and selected port binding. Pulling a new image alone never changes an existing container.
Repeat container, logs, mount, GET, login, profile, and copied-file checks. Keep automation and public access disabled until acceptance testing succeeds. Retain the previous image and backup until you are satisfied with the updated deployment.
A new release may migrate configuration or database state. Unless backward compatibility is explicitly established, pair the older image with its pre-update configuration backup. Image rollback cannot restore media tracks already removed after the update.
For rollback, stop the failed version and preserve its current configuration separately for diagnosis. Restore the pre-update archive into a clean configuration directory with the correct ownership, rather than merging it blindly into migrated state. Recreate the previous image with the original mounts and bindings, then repeat local verification before reconnecting automation or the tunnel.
Handle older /data installations cautiously
The official site's migration note says older /data mounts remain supported and describes changing the container destination from /data to /config while keeping the same host folder. Its documented switch does not copy data. This is a mount-destination change, not evidence that database downgrades are universally safe.
Before switching, inspect the actual mounts, stop the container, back up the existing appdata directory, and confirm it contains the expected state. Recreate the container with that same host directory mapped to /config; keep media container paths unchanged. Verify credentials, profiles, scans, and integrations afterward.
If the expected host directory is empty, do not remove the old container. Determine where that installed version actually stored state. Only if inspection confirms the data is inside its /data directory, a recovery copy can be made to a separate backup location:
docker stop muxarr
docker cp muxarr:/data/. /path/to/recovery-copy/
Inspect and independently back up that copy before proceeding. Do not assume every older version uses the same layout, or that pointing a downgraded image at newly migrated data is safe. Use release-specific guidance and the matching pre-update backup when compatibility is uncertain.
Provide remote HTTP access with Localtonet
Once Muxarr works locally and requires authentication, our client can connect it to a Localtonet relay through an outbound connection. The resulting HTTP tunnel provides a public HTTPS address without inbound router port forwarding, a public IP address, or VPN setup. Standard HTTP tunneling is not a VPN and does not replace application authorization.
The workflow below follows our supported client, device, relay, configuration, start, and stop lifecycle. Use the HTTP tunnel documentation for current platform-specific installation instructions and dashboard presentation. Client installation commands differ by operating system; this guide does not invent a universal installer.
Install and run our client
Use the Localtonet client for your operating system on the Docker host or another authorized device that can reach the verified Muxarr endpoint.
Authenticate and select the device
Use its device-specific token through the supported client workflow. Keep the token private and select the device that can actually reach Muxarr.
Select an available relay
Choose a currently available server or region from the dashboard rather than copying a hardcoded server code.
Create the HTTP configuration
Set the local target to the verified address and host port. For a client installed directly on the Docker host with the loopback mapping, use 127.0.0.1 and 8183. Select an available HTTP process type.
Start and use the tunnel
Press Start. Creating a configuration does not start it. Open the assigned public URL only after the device is connected and the tunnel is running.
Stop or delete it when finished
End public exposure when remote access is no longer needed. The endpoint works only while the selected client is connected and the tunnel is running.
Random Sub Domain, Custom Sub Domain, and Custom Domain process types serve the same target content through public HTTPS. Availability may vary by plan or current product configuration. Follow current documentation for custom-domain DNS rather than guessing records.
Verify the public access boundary
Test the assigned HTTPS URL from a separate network, such as a mobile connection with Wi-Fi disabled. Use a private browser session to confirm that unauthenticated visitors cannot reach administrative content. Then sign in and perform non-destructive navigation checks. Verify logout as well; an already authenticated browser is not a meaningful anonymous-access test.
Keep API keys, device tokens, backups, and inspection files private. Maintain least-privilege mounts and current software. Apply suitable access restrictions in your application or network design, and follow organizational policies. If only trusted devices need access and a public URL is unnecessary, consider a private-network approach instead; our VPN Manager is separate from standard HTTP tunneling.
HTTPS protects the browser-facing connection, but does not decide who may administer Muxarr. Do not start public exposure until application authentication is configured and tested. Stop the tunnel during uncertain updates, recovery, or access-control failures.
Troubleshoot from the local service outward
The container exits or repeatedly restarts
Run docker ps -a --filter name=muxarr and docker logs --tail 200 muxarr. Check configuration permissions, architecture compatibility, storage availability, and database errors. Confirm Docker itself works with docker info. If startup fails immediately, review placeholder paths and shell line-continuation syntax.
Port 8183 is already allocated
Inspect running containers with docker ps, then use your operating system's listener-inspection tool for host processes. Stop the conflicting service or choose another host port while retaining container port 8183. For example, a loopback mapping of 127.0.0.1:8184:8183 requires browser and Localtonet targets to use host port 8184.
The browser reports connection refused or timeout
Repeat the GET check in the local-verification section and inspect docker port muxarr. Connection refusal usually indicates no listener at the selected address and port; a timeout can indicate routing or filtering. A loopback-only binding cannot be reached through the host's LAN address. Check from the actual Localtonet client device, not just another browser.
The library is empty
Inspect mount sources and confirm network storage was mounted before startup. Profiles must use container paths such as /media, not host paths. An unintentionally created empty host directory can look like a valid mount while containing no media.
Scanning succeeds but processing fails
Read access is not write access. Check PUID, PGID, directory permissions, read-only mounts, available disk space, and network-storage restrictions. Reproduce with a copied file while watching logs. Avoid unrestricted permissions as a permanent workaround.
Another application cannot access processed files
Inspect output ownership, group, and permissions. Review the umask and shared-group design. Changing the umask alone cannot fix a mismatched group or inaccessible parent directory.
Arr integration connects but imports are not processed
First establish that manual processing works. Then check event delivery, mapped file existence, profile selection, and any configured delay. Successful API authentication does not validate filesystem path mapping. Inspect both applications' logs without publishing keys or private library details.
The tunnel is connected but Muxarr is unreachable
Test the exact target address and port from the selected client device. Client connectivity to our relay and client connectivity to Muxarr are separate checks. Remember that loopback belongs to the device or container performing the request.
The public URL stops working
Check Muxarr state, local GET response, Localtonet client connectivity, tunnel status, and the assigned URL in that order. A created but stopped tunnel must be started. Test from an external network and use the public HTTPS address, not the private Docker address. Router port forwarding is not required for this workflow.
Frequently asked questions
Which architectures and port does Muxarr use?
The official website lists Linux AMD64 and ARM64 images. Its Docker example publishes container TCP port 8183 as host port 8183. You can choose a different host port while retaining the container port.
Should I use loopback-only port publication?
Use it when the Localtonet client runs directly on the Docker host and LAN access is unnecessary. A client on another device needs a reachable host address, not its own loopback address.
Does Muxarr re-encode video?
The project describes unwanted-track removal without re-encoding and metadata-only changes through mkvpropedit without remuxing. Verify format compatibility for your installed release and test representative media rather than assuming every extension follows an identical processing path.
Are Sonarr and Radarr required?
No. They are optional integrations for original-language detection and import automation. You can configure profiles, scan, preview, and process a library without connecting them.
Is keeping the previous image enough for rollback?
No. Preserve the image identity or image archive, the complete run configuration, and a matching pre-update configuration backup. Database migrations may prevent the old image from using new state. Media changes require separate media backups.
Must I immediately change an older /data mount?
The current project website says older /data mounts remain supported. Its switch to /config keeps the same host folder and changes the container destination. Inspect and back up the actual installation first; mount compatibility does not guarantee database downgrade compatibility.
Why verify locally before starting Localtonet?
Local verification separates container, mount, permission, and HTTP problems from tunnel configuration. A tunnel cannot make a stopped or unreachable application healthy. Test from the actual client device before publishing it.
Does creating a tunnel activate it, and do I need port forwarding?
You must press Start after creating the tunnel. Our client establishes an outbound connection, so inbound router port forwarding is unnecessary. The public endpoint works only while the selected client is connected and the tunnel is running.
Connect your verified Muxarr service with Localtonet
After Docker, local GET checks, authentication, media permissions, and a copied-file processing test succeed, create an HTTP tunnel to the verified Muxarr endpoint. Keep backups independent and stop public exposure when it is no longer needed.
Get Started Free โ