OpenMediaVaultLab
Isometric dark blue scene of a four-bay NAS with glowing drive lights, its plugin module cabled to a stack of three shipping containers representing Docker apps.
getting-started

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.

By OpenMediaVaultLab Editorial · ·Updated · 11 min read

On OpenMediaVault 8, Docker and Docker Compose run through the openmediavault-compose plugin from omv-extras. Enable the Docker repo under System > omv-extras, install openmediavault-compose 8.x from System > Plugins, then point its Settings tab at shared folders for compose files, data, backups and Docker storage. Every stack is then managed from the web interface.

Older guides tell you to click the Portainer button in omv-extras. That button went away in May 2023, when omv-extras 6.3 handed Docker installation to the compose plugin, according to the omv-extras changelog. A current install means OpenMediaVault 8 “Synchrony” on Debian 13, since OMV 7 hit end of life in June 2026 per the release table. There the compose plugin is the supported route, with compose files in ordinary shared folders you can back up like anything else. What follows 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.

For an ARM64 board, complete the OpenMediaVault on a Raspberry Pi installation before adding Compose. It covers the base OS, wired networking and data disk that this container guide assumes are already working.

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.

What does the OMV compose plugin install?

The openmediavault-compose plugin installs Docker Engine (docker-ce, docker-ce-cli, containerd.io), the docker-compose-plugin package that provides docker compose, and docker-buildx-plugin, all from Docker’s own apt repository rather than Debian’s. When you set a Docker storage path it also writes /etc/docker/daemon.json. The plugin itself is the web interface over those tools.

The list comes from the plugin’s Salt deploy state:

ComponentPackage or fileRole on the NAS
Docker Enginedocker-ce, docker-ce-cli, containerd.ioRuns the containers
Compose v2docker-compose-pluginThe docker compose command behind Up, Pull and Down
Image buildsdocker-buildx-pluginBuilds images from the Dockerfiles tab
Daemon config/etc/docker/daemon.jsonSets data-root to your storage path, json-file logs capped at Log File Max Size (50 MB default) with 3 files kept, live-restore if enabled
Web terminalopenmediavault-ctermInstalled alongside unless OMV_NO_CTERM_DEPENDENCY=yes

No Docker version is pinned, so you get whatever Docker’s repository currently ships. Docker’s Debian install page lists Debian 13 Trixie among its supported releases and both amd64 and arm64 among its architectures, which covers everything OMV 8 runs on. The plugin moves faster than OMV itself: its changelog starts the 8.x line on 28 September 2025, three months before OMV 8.0.1 was announced on 24 December 2025, and shows eight releases between 2 September and 7 October 2026, the last being 8.2.2. Expect a higher number by the time you install.

Two cautions follow. Debian’s own docker.io package is on Docker’s list of unofficial packages that conflict with the official ones and must be removed first, so do not apt install it next to the plugin. And the plugin fully manages only containers it created, per the plugin wiki; ones started with a bare docker run stay partly invisible in its tabs until Autocompose turns them into files.

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

Before piping anything into bash as root, read what omv-extras changes on an OMV 8 system. Then, in the web interface, following the wiki’s Docker in OMV 8 page:

  1. SYSTEM > OMV-EXTRAS, enable DOCKER REPO, SAVE. This adds Docker’s own apt repository, the source of the docker-compose-plugin package that provides docker compose.
  2. SYSTEM > PLUGINS, select openmediavault-compose 8.x, INSTALL.

Since plugin 8.1 (December 2025) the install enables the Docker repo by itself, so the first step is now a check rather than a requirement. 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 ./config lands 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/docker on 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, entered as a full absolute path with no symlinks. 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, sized per the FAQ below; the OMV 8 hardware requirements cover the OS disk it should not share. 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.

The same field decides who owns daemon.json. With a path set, the plugin writes that file on every apply, so hand edits do not survive; for custom daemon settings the wiki says to leave the field empty and edit /etc/docker/daemon.json yourself. Live Restore, in the same section, keeps containers running while the Docker daemon restarts.

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 (UID 998) or root (UID 0). Do not add appuser to the docker group either: the wiki notes that any member of that group can escalate to root. If shared folders are new to you, creating a shared folder in OpenMediaVault covers the privileges step.

After Reinstall Docker, confirm the result from the shell:

docker compose version
docker info | grep -E "Docker Root Dir|Logging Driver|Live Restore"

In the docker info output, Docker Root Dir should show your docker shared folder’s path rather than /var/lib/docker. If it still shows the default, the storage path did not apply.

Step 3: the first stack

OMV 8’s plugin looks up user, group, time zone and shared-folder values itself through ${{ }} placeholders, added in plugin 8.0.4 and 8.0.5 in December 2025. Files > Create, name it jellyfin, and paste this, adapted from the LinuxServer.io Jellyfin reference and the wiki’s own Jellyfin example:

services:
  jellyfin:
    image: lscr.io/linuxserver/jellyfin:latest
    container_name: jellyfin
    environment:
      - PUID=${{ uid:"appuser" }}
      - PGID=${{ gid:"users" }}
      - 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.

Before the container starts, the plugin swaps ${{ uid:"appuser" }} for appuser’s UID, ${{ gid:"users" }} for 100 (the group every GUI-created user lands in) and ${{ tz }} for the server’s time zone, so there is no id appuser output to copy by hand. For Intel Quick Sync transcoding, the wiki’s version adds /dev/dri:/dev/dri under devices: and puts appuser in the render and video groups.

Upgraded from OMV 7 with omv-release-upgrade, the tool the OMV 8 announcement names, and your files read PUID=${PUID} from a global environment file? Leave them. The wiki calls global variables optional on OMV 8, not removed, and since 8.0.6 the placeholders also expand inside that file. The plugin keeps it as global.env in the appdata root and overwrites the copy on disk, so edit it through the Files tab’s global environment editor, not over SMB.

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.

What does CHANGE_TO_COMPOSE_DATA_PATH do?

CHANGE_TO_COMPOSE_DATA_PATH is a literal placeholder that the compose plugin replaces with the absolute path of the shared folder chosen as Data under Services > Compose > Settings. Since plugin 7.0.9 (March 2024), a compose file containing it fails with an error when no Data folder is set, so set Data before running any example.

It is the older of two placeholder systems, and the templates under Files > Add from example still rely on it. OMV 8 added a general form that names any shared folder, per the plugin changelog and the wiki:

PlaceholderBecomesAvailable since
CHANGE_TO_COMPOSE_DATA_PATHPath of the Data shared folder in Settings6.x plugin (by July 2023), still supported
${{ sf:"media" }}Absolute path of the shared folder named media8.0.4, December 2025
${{ uid:"appuser" }}That user’s UID8.0.5, December 2025
${{ gid:"users" }}That group’s GID (100 for users)8.0.5, December 2025
${{ tz }}The server’s time zone, such as Europe/Madrid8.0.5, December 2025

The sf form resolves in compose, override, env and config files, and it removes the one-folder limit: a stack that reads movies from one shared folder and photos from another can name both. Use CHANGE_TO_COMPOSE_DATA_PATH when every stack reads from a single bulk folder and you want the examples to run unmodified. Use sf when data is split across shared folders, such as a mergerfs pool next to a plain disk. Since 8.1.25 (September 2026), changing a shared folder that a placeholder references marks the compose module dirty, so OMV asks you to apply the change.

If a container starts but sees an empty directory, look at the path after the placeholder for a typo, then at appuser’s privileges on that shared folder. Check validates syntax, not permissions.

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 (0 removes the limit), 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. Docker’s Debian install page adds a second reason for care: ports Docker publishes bypass ufw and firewalld rules, so a host firewall will not hide them.

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, use Import from Portainer on the Files tab, added in 8.1.13 (April 2026), which pulls stacks across with a Portainer API key or a username and password. The maintainers’ forum guide describes the manual route, which still works: 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.

FAQ

does openmediavault 8 still support portainer?

Not as a built-in installer. omv-extras removed its Portainer button in version 6.3 (May 2023), and the OMV 8 compose plugin’s changelog mentions Portainer only as a migration source: since 8.1.13 (April 2026), the Files tab can import stacks from it using an API key or username and password. Portainer itself still runs as an ordinary container.

where does omv store docker images and volumes?

In the Docker storage path set under Services > Compose > Settings, which the plugin writes to /etc/docker/daemon.json as data-root. Left empty, it is /var/lib/docker on the OS disk. Compose files and bind-mounted config live separately in the appdata shared folder. Run docker info and read the Docker Root Dir line to confirm.

how much disk space does docker need on openmediavault?

The omv-extras wiki calls 60 to 100 GB a sensible minimum for the Docker drive and suggests 250 to 500 GB or more for large media libraries. Images, layers and named volumes all land there. Its reference layout gives Docker a dedicated NVMe drive, kept off the OS disk and out of any mergerfs pool.

how do i update docker containers in openmediavault?

Two ways. Add an update job in the Schedule tab, which pulls newer images for the compose files you select. Or update one container by hand: Services tab, select it, Pull; Files tab, select its file, Up; then Prune and Image to remove the old image. Pin a version tag for anything that must not change overnight.

can omv 8 use podman instead of docker?

Experimentally. openmediavault-compose 8.1, released in December 2025, added Podman support flagged as experimental. In that mode the plugin installs podman, podman-docker and aardvark-dns in place of docker-ce, with docker-compose-plugin still installed for both runtimes. Docker is the runtime the wiki’s walkthrough and this guide use.

Sources

  1. omv-extras wiki: Docker in OMV 8
  2. omv-extras wiki: openmediavault-compose plugin (OMV 8)
  3. openmediavault documentation: Releases
  4. openmediavault.org: OMV8 (Synchrony) released
  5. OpenMediaVault-Plugin-Developers/packages (omv-extras installer)
  6. Docker docs: Install the Compose plugin on Linux
  7. Docker docs: Volumes
  8. Docker docs: Bind mounts
  9. Docker docs: Compose file reference, services
  10. LinuxServer.io: Understanding PUID and PGID
  11. LinuxServer.io: Jellyfin image
  12. openmediavault forum: Guide, using the new docker plugin
  13. openmediavault-omvextrasorg changelog (omv-extras)
  14. openmediavault-compose changelog
  15. openmediavault-compose Salt state: Docker packages and daemon.json
  16. Docker docs: Install Docker Engine on Debian
  17. Docker docs: docker system info
#openmediavault #docker#docker-compose#self-hosting #nas #home-server

Related