vdsm/virtual-dsm: run Synology DSM in a Docker container
vdsm/virtual-dsm is an open-source project for practical engineering and operations.
At a glance
- What is it?
- vdsm/virtual-dsm packages a Virtual DSM guest inside a Docker image that boots under KVM and exposes the DSM desktop on port 5000. It is convenient for homelab testing, but it is not a Synology product and the README does not document rollback or migration.
- Who is it for?
- Adopt vdsm/virtual-dsm if you already run Linux with KVM and want a DSM desktop to poke at without buying hardware; skip it if you need Docker Desktop on macOS or Windows 10, since the README states KVM is not available there, or if you need video hardware transcoding. Before committing data, verify that /dev/kvm exists on the host, that your chosen storage path has 16 GB free, and which .pat URL the URL variable will fetch.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 28 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Virtual DSM in a container actually gives you
The project puts a Synology DSM guest inside a Docker image. The README describes it as "Virtual DSM in a Docker container," and the feature list covers automatic download of the installation files, web-based access to the DSM desktop, KVM acceleration, configurable CPU, memory and storage, multiple disks, physical disk passthrough, memory ballooning, and NAT, user-mode, macvlan and macvtap networking.
The audience is narrow and specific. You need a Linux host with KVM, or Windows 11 with nested virtualization enabled. Docker Desktop on Linux, macOS and Windows 10 is explicitly called out as unsupported because it does not provide KVM access to containers. That single note rules out the largest group of casual Docker users, which is worth knowing before you spend time on a compose file.
How the container boots DSM: qemu, patology and the web front end
The Dockerfile starts FROM scratch and copies the whole filesystem from qemux/qemu:7.50. On top of that it installs fakeroot, python3-msgpack, python3-pysodium and a pinned dissect.cstruct==4.7, then copies ./src into /run/, ./web into /var/www/, and an nginx config to /etc/nginx/default.conf. A separate binary is pulled from qemux/qemu-host:2.06 into /run/host.bin, and an extraction script is fetched from the patology project as /run/extract.py.
That layout explains the data flow. The entrypoint is tini running /run/entry.sh, which drives the QEMU guest. Installation files are downloaded automatically, and patology handles the .pat package format. The web directory is served by nginx, which is how you reach the DSM desktop on port 5000. The image declares VOLUME /storage and EXPOSE 445 5000, and sets defaults of RAM_SIZE=2G, CPU_CORES=2 and DISK_SIZE=256G. A healthcheck runs /run/check.sh every 60 seconds after a 45 second start period.
The pinned versions matter. dissect.cstruct is fixed at 4.7 and the QEMU base at 7.50, so an upgrade of this project can move several components at once. The README does not describe a rollback path for a disk that has already been upgraded by DSM.
Installing vdsm/virtual-dsm and reaching the DSM desktop
The README offers three entry points: Docker Compose, the Docker CLI, and a Kubernetes manifest applied with kubectl. The compose file in the repository is the shortest path. It requests /dev/kvm and /dev/net/tun, adds NET_ADMIN, maps port 5000, and bind-mounts ./dsm to /storage.
services:
dsm:
container_name: dsm
image: vdsm/virtual-dsm
environment:
DISK_SIZE: "256G"
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 5000:5000
volumes:
- ./dsm:/storage
restart: always
stop_grace_period: 2mIf you prefer a single command, the README gives the equivalent CLI form, including a 120 second stop timeout that matches the compose grace period.
docker run -it --rm --name dsm -e "DISK_SIZE=256G" -p 5000:5000 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v "${PWD:-.}/dsm:/storage" --stop-timeout 120 docker.io/vdsm/virtual-dsmAfter the container starts, the README says to connect to port 5000 in a browser and wait until DSM finishes installing, then choose a username and password. The requirements section asks for at least 1 GB of available RAM and at least 16 GB of free disk space, so the ./dsm folder needs room to grow. The default guest is version 7.2; the URL environment variable accepts a direct .pat download link if you want an older release.
Storage, disks and passthrough: where the sharp edges are
Changing the storage location is a bind mount, and the README notes that the example path can be replaced with a named volume. Growing the disk is a matter of editing DISK_SIZE, and the README states this can resize an existing disk to a larger capacity without data loss. Shrinking is not mentioned anywhere.
Multiple disks follow the same pattern, with DISK2_SIZE and DISK3_SIZE paired against /storage2 and /storage3. Physical passthrough is different: you map a device such as /dev/sdb to /disk1, and the README warns that the device must be totally empty with no filesystem, otherwise DSM may not format it as a volume. That is a destructive operation if you get the device name wrong, and the container will not protect you from it.
Memory behaves in a way that surprises people. By default DSM is allocated the full RAM_SIZE for its entire lifetime. Dynamic reclaim requires enabling memory ballooning, which the README links to a document in the qemus/qemu repository rather than explaining inline. If you set RAM_SIZE to 8G and never enable ballooning, the host loses 8 GB whether the guest uses it or not.
Networking modes and the macvlan host-access trap
Bridge networking shares the host IP, which is the default. To give the container its own address, the README shows creating a macvlan network with docker network create -d macvlan, a subnet, a gateway, an ip-range and a parent interface, then attaching the service to it with an ipv4_address. The README notes that port mapping is no longer needed in that mode because all ports are exposed.
The catch is documented in an important note: the assigned IP will not be reachable from the Docker host, because macvlan does not permit communication between the two. The suggested workaround is a second macvlan network, linked to an external blog post. This is a genuine operational limitation, not a configuration mistake, and it catches people who expect to reach the DSM desktop from the same machine that runs the container.
DHCP mode goes a step further: with macvlan configured, adding DHCP: "Y" plus /dev/vhost-net and a device_cgroup_rules entry lets DSM request its own address from your router, so the container and DSM end up with separate IPs.
GPU acceleration and what it does not cover
GPU support is opt-in through the GPU environment variable. For Intel and AMD you expose /dev/dri. For NVIDIA the host needs the NVIDIA Container Toolkit, and the compose file adds NVIDIA_DRIVER_CAPABILITIES and a deploy.resources.reservations.devices block with the nvidia driver.
The README is unusually direct about the payoff: GPU acceleration can enable facial recognition in Synology Photos, but currently does not provide hardware transcoding for video. If your reason for running DSM is a media server that transcodes, this project does not solve that today. That limitation is stated in the README itself, which is better than leaving it for users to discover.
Alternatives: Xpenology and a real Synology unit
Xpenology is the closest alternative and the comparison people actually search for. Xpenology is a bare-metal loader approach: it boots DSM directly on the host hardware, typically on hardware you dedicate to it. vdsm/virtual-dsm takes the opposite route. DSM runs as a guest inside QEMU inside a Docker container on a Linux host that keeps running whatever else it was doing. The trade-off follows from that: the container approach keeps the host usable and gives you snapshots of a single /storage directory, while a bare-metal loader usually has a more direct path to disk controllers and does not add a container layer between DSM and the hardware.
Buying an actual Synology NAS is the other option, and it is the only one that comes with vendor support, official DSM updates and a serial number the way Synology intends. The search data around serial numbers and licensing reflects that gap. This project is not a Synology product, and the README makes no claim about licensing or activation.
Maintenance, licence and what to verify before trusting it with data
The repository is not archived. The last push was on 2026-08-21, the same day as the v7.65 release, and v7.64 and v7.63 landed earlier that month. Releases are frequent, which means the image tag you pin will age quickly if you pull latest.
The licence is MIT, which covers the code in this repository. It does not cover the DSM installation files that the container downloads from Synology, and it says nothing about whether running DSM outside Synology hardware is permitted where you live. That is a question for the vendor's terms, not for this project's licence file.
The upgrade cost is the part the README leaves open. There is no documented rollback procedure, no migration guide between DSM versions, and no statement about whether a disk upgraded inside the guest can be moved back to an older image. The Dockerfile pins qemux/qemu:7.50 and dissect.cstruct 4.7, so a project upgrade can shift the QEMU version underneath an existing /storage volume. Test an upgrade on a copy of the storage directory first, and keep the .pat URL you used so you can reconstruct the guest if you need to start over.
Editorial conclusion
Adopt vdsm/virtual-dsm if you already run Linux with KVM and want a DSM desktop to poke at without buying hardware; skip it if you need Docker Desktop on macOS or Windows 10, since the README states KVM is not available there, or if you need video hardware transcoding. Before committing data, verify that /dev/kvm exists on the host, that your chosen storage path has 16 GB free, and which .pat URL the URL variable will fetch.
Frequently asked questions
How do I install vdsm/virtual-dsm?
Use the compose file from the repository, which requests /dev/kvm and /dev/net/tun, adds NET_ADMIN, maps port 5000 and mounts ./dsm to /storage. A single docker run command with the same devices and volume is also given in the README. The host must be Linux with KVM, or Windows 11 with nested virtualization.
What is vdsm/virtual-dsm?
It is an open-source project that runs Virtual DSM inside a Docker container, with automatic download of the installation files and web-based access to the DSM desktop on port 5000. The image is built on a QEMU base and uses KVM acceleration on the host.
Can I run Synology DSM on a virtual machine?
This project does exactly that: DSM runs as a QEMU guest inside a Docker container, and the README describes near-native performance with KVM acceleration. The host requirements are Docker or Podman on Linux with KVM, or Windows 11 with nested virtualization.
Is there an open source version of Synology?
vdsm/virtual-dsm is open source under the MIT licence, but it only packages the container and the tooling around it. The DSM installation files are downloaded from Synology and are not covered by that licence.
What is Synology Virtual DSM?
In this project, Virtual DSM is the DSM guest that runs inside the Docker container and whose desktop you reach on port 5000. The README says version 7.2 is installed by default, and an older release can be selected with the URL environment variable.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vdsm-virtual-dsm)