Storage Mapping
OpenNVR writes recordings to a directory that is mounted into its containers. This build has no in-app storage settings page — you choose where recordings land by mapping a host path into the containers with a Docker volume, then let MediaMTX write segments there.
[!NOTE] Storage mapping is a deployment task done on the host (in
docker-compose.yml/.env), not from the web UI. It requires shell access to the machine running the stack. Retention (auto-delete) is configured separately in Media Server Config via the Retention (Delete After) field.

What you can do here
- Map recordings to a dedicated disk, NAS, or RAID array instead of the default folder.
- Verify that segments are actually being written to your target.
- Understand the on-disk layout so you can migrate or back up recordings.
How the mapping works
Both the mediamtx and opennvr-core services mount the same host directory to /app/recordings inside the container. The host side is driven by the RECORDINGS_PATH variable:
services:
opennvr-core:
volumes:
- ${RECORDINGS_PATH:-./recordings}:/app/recordings
mediamtx:
volumes:
- ${RECORDINGS_PATH:-./recordings}:/app/recordings
When RECORDINGS_PATH is unset it defaults to ./recordings (a folder next to docker-compose.yml). The container-side path is fixed — opennvr-core also carries these environment values:
| Variable | Example | Notes |
|---|---|---|
RECORDINGS_PATH |
/mnt/nas/nvr_recordings |
Host directory to store recordings; set in .env or the shell |
RECORDINGS_HOST_BASE |
${RECORDINGS_PATH:-./recordings} |
Host base path (informational) |
RECORDINGS_CONTAINER_BASE |
/app/recordings |
Where the volume is mounted inside the container |
RECORDINGS_BASE_PATH |
/app/recordings |
Base path the recorder writes under |
Map recordings to a dedicated path
-
Stop the stack:
docker compose down -
Set
RECORDINGS_PATHto your host directory. The simplest way is your.envfile:# .env RECORDINGS_PATH=/mnt/nas/nvr_recordings(Windows example:
RECORDINGS_PATH=D:/Surveillance/Recordings)Or edit the
volumesentry directly indocker-compose.ymlfor bothopennvr-coreandmediamtx:- /mnt/nas/nvr_recordings:/app/recordings -
Make sure the host directory exists and the container user can read/write it.
-
Start the stack again:
docker compose up -d
[!WARNING] Map the same host path into both
opennvr-coreandmediamtx.mediamtxwrites the segments;opennvr-corereads them back for playback. If the two point at different directories, recordings won’t play back.
Verify writes
Once a camera is recording, confirm segments are landing on your target by listing the directory inside the running container:
docker compose exec opennvr-core ls -lah /app/recordings
Recordings are organized per camera and date. Each recording path follows the pattern cam-<id>/%Y/%m/%d/%H-%M-%S-%f, so you’ll see subfolders like cam-3/2026/07/10/ fill with segment files. The default retention when recording is enabled is 168h (7 days); change or disable it from Media Server Config → Path Defaults.
[!WARNING] Binding a new empty directory to a running instance means OpenNVR immediately loses access to previously stored video. Migrate existing recordings to the new path first (for example with
rsync) before switching the mount.
📸 Screenshots to capture
Save this to opennvr-site/public/screenshots/ with the exact filename below:
storage-settings.png— a host ordocker compose execfile listing of the mapped recordings directory, showing thecam-<id>/YYYY/MM/DD/segment folder structure.