OpenMediaVault Docker Compose Setup: The OMV 8 Plugin Route
OpenMediaVault Docker Compose setup on OMV 8: the omv-extras plugin, shared folder layout, Docker storage off the OS disk, a first stack and backups.
Every OpenMediaVault Docker Compose setup guide older than a couple of years tells you to click the Portainer button in omv-extras. That button has been gone since 2023. On a current install, meaning OpenMediaVault 8 “Synchrony” on Debian 13 now that OMV 7 hit end of life in June 2026 per the release table, the supported route is the openmediavault-compose plugin: Docker Engine plus Compose, driven from the OMV web interface, with compose files in ordinary shared folders you can back up like anything else. This is that setup, in the order that avoids redoing it at month nine.
Who this is for, and who should skip it
You want a handful of containers on the box that already serves your SMB shares: a media server, a photo backup target, maybe a download client. OMV 8 supports AMD64 and ARM64 only, so 32-bit boards are out.
Skip it if you want a marketplace with app icons. OMV treats Docker as an add-on to a general-purpose Debian system, the appeal for anyone who knows docker compose and the frustration for anyone who does not. Two services on an N100 do not need Kubernetes.
Step 1: omv-extras, the Docker repo, the plugin
omv-extras is the third-party plugin repository that carries the compose plugin. Install it as root with the one-liner from the maintainers’ README:
wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | bash
Then, in the web interface, following the wiki’s Docker in OMV 8 page:
- SYSTEM > OMV-EXTRAS, enable DOCKER REPO, SAVE. This adds Docker’s own apt repository, the source of the
docker-compose-pluginpackage that providesdocker compose. - SYSTEM > PLUGINS, select openmediavault-compose 8.x, INSTALL.
The install pulls in openmediavault-sharerootfs as a dependency. Leave it alone: uninstalling it removes the compose plugin with it.
Step 2: decide where everything lives before you start anything
This is the step people rush, and the one that hurts later. The plugin’s Settings tab (SERVICES > COMPOSE > SETTINGS) wants shared folders for four things. Keep the wiki’s names, since forum answers assume them:
- appdata: compose files, one subfolder per stack, plus each stack’s config directories. A relative path such as
./configlands here, next to the YAML. - data: bulk data like a media library. Any compose file can reference it through the special string
CHANGE_TO_COMPOSE_DATA_PATH, which the plugin swaps for the folder’s real path. - backup_compose: where the scheduled backup writes.
- docker: Docker’s own storage, which holds images, layers and named volumes. The default is
/var/lib/dockeron the OS disk. Change it, then click Reinstall Docker.
The wiki’s rules for that docker folder are specific: not on the OS drive or a USB stick, not on a mergerfs pool, not on NTFS, preferably ext4 on a separate drive. The mergerfs rule catches people, because a pool looks like a normal directory right up until Docker’s layer files are spread across disks. Carve out a plain ext4 filesystem for Docker instead. The layering in OpenMediaVault NAS planning applies here too: filesystem first, shared folder second, service last.
For NVIDIA hardware transcoding, the wiki says to leave the storage path empty, since changing it can corrupt the NVIDIA configuration when OMV reconfigures.
By default the plugin creates compose folders and files restricted to root. The wiki recommends a dedicated appuser created in the GUI with rights on the shared folders, and never running containers as admin or root. Note that user’s numbers with id appuser.
Step 3: the first stack
Put those ids in the global environment file (Files tab). The plugin stores it as global.env and exposes the variables to every compose file:
PUID=1000
PGID=1000
TZ=Etc/UTC
Then Files > Create, name it jellyfin, and paste this, adapted from the LinuxServer.io Jellyfin reference:
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
volumes:
- ./config:/config
- CHANGE_TO_COMPOSE_DATA_PATH/movies:/data/movies:ro
- CHANGE_TO_COMPOSE_DATA_PATH/tvshows:/data/tvshows:ro
ports:
- 8096:8096
restart: unless-stopped
Click Check to validate the file, then Up. The first Up downloads the image, and the Services tab shows the logs. Jellyfin answers on port 8096.
Three deliberate choices in that file. PUID and PGID run the container’s process as your appuser, so the files it writes belong to someone you can log in as. LinuxServer’s docs put it plainly: root-owned files become inaccessible to you. The config directory is a bind mount into appdata rather than a named volume. Docker’s docs prefer volumes because Docker manages them, but that buries your config inside the docker storage folder, invisible to SMB and awkward to back up. On a NAS a bind mount you can see wins. The documented trade-off, that a bind mount ties the container to the host’s directory layout, is a feature here. And unless-stopped, one of the four documented restart policies, survives reboots without resurrecting containers you deliberately stopped.
Which containers earn a permanent place is a separate question, and SelfhostRealm’s compose stack framework answers it honestly.
Backups and the restore drill
The Schedule tab runs a backup job: it stops the containers, copies the compose folder and each stack’s data with rsync, then restarts them. Volumes are included only below the Max Size threshold, 1 GB by default, unless you append # BACKUP or # SKIP_BACKUP to the volume line. Read-only mounts are never copied, and global.env goes along.
That is a consistent snapshot, not versioned history, and it lands on the same NAS. Treat backup_compose as the first hop, then rsync it to something that is not this machine. The 3-2-1 approach for a self-hosted stack covers the off-site copy.
Run the restore drill once, before you need it: on a scratch install, point Settings at restored copies of the folders, Files > Import the stacks, then Up. More than twenty minutes means the layout is too clever.
Networking and updates
Bridge networking with published ports is right for nearly everything. The Networks tab exists for the exception: a container that needs its own LAN address, Pi-hole being the classic case, gets a macvlan network with your interface as parent, your subnet and gateway, and a small reserved IP range. Keep it all on the LAN or behind a VPN. Forwarding port 8096 on the router is how a Jellyfin login page ends up indexed by internet scanners.
For updates, the Schedule tab’s update job pulls images and recreates containers. The Files tab has Pull, Up and Prune for doing it by hand. Autocompose writes a file from a container you started on the command line. Arriving from Portainer, the maintainers’ forum guide walks the migration: copy each stack’s text out, delete it, recreate it here. Two containers, one evening, and a NAS that documents its own container layout in a folder you can read.
Related across the network
- Best Docker Containers for Your Home Server in 2026 — dockerhomelab.com
- Best Mini PC for Docker Containers: 4 Sensible Homelab Picks — minilabhq.com
- How to Self Host Nextcloud on Raspberry Pi — selfhostrealm.com
- Best NAS for Docker Containers in 2026: Synology, QNAP, DIY — dockerhomelab.com
- Docker Compose Setup: First Self-Hosted Stack — dockerhomelab.com
Sources
- omv-extras wiki: Docker in OMV 8
- omv-extras wiki: openmediavault-compose plugin (OMV 8)
- openmediavault documentation: Releases
- openmediavault.org: OMV8 (Synchrony) released
- OpenMediaVault-Plugin-Developers/packages (omv-extras installer)
- Docker docs: Install the Compose plugin on Linux
- Docker docs: Volumes
- Docker docs: Bind mounts
- Docker docs: Compose file reference, services
- LinuxServer.io: Understanding PUID and PGID
- LinuxServer.io: Jellyfin image
- openmediavault forum: Guide, using the new docker plugin
Related
How to Install OpenMediaVault 8 on Raspberry Pi
Install OpenMediaVault 8 on a Raspberry Pi using Raspberry Pi OS Lite, wired networking, USB storage, SMB shares, backups, and secure remote access.
OpenMediaVault NAS Planning: Disks, Filesystems, Shares
How OpenMediaVault layers disks, filesystems, shared folders and services, and the storage decisions worth settling before you copy any data onto it.
OpenMediaVault Hardware Requirements and Build Guide
What OpenMediaVault 8 needs from CPU, memory, disks and network, where the documented minimums stop being useful, and three reference builds to copy.