DEV Community

Cover image for Making a Virtual NAS with virt-manager, OpenMediaVault, and Tailscale
Fredy Sandoval
Fredy Sandoval

Posted on

Making a Virtual NAS with virt-manager, OpenMediaVault, and Tailscale

TL;DR
This is a practical, guide to turning a spare disk into a NAS by running OpenMediaVault (OMV) inside a KVM virtual machine. It covers the whole path: preparing the disk, installing OMV, passing the disk through correctly (including the traps that are easy to fall into), sharing files over SMB, mounting the share on your host, and reaching your NAS from your phone with Tailscale.

Tools used

  • virt-manager (libvirt/KVM/QEMU) — the virtualization layer
  • OpenMediaVault (OMV) — the NAS operating system
  • btrfs — filesystem, chosen for future expandability
  • Samba (SMB/CIFS) — file sharing protocol
  • Tailscale — secure remote access to the NAS from anywhere
  • cifs-utils — for mounting the share on Linux

Overview

The VM needs two disks:

  • A small virtual disk (qcow2, ~16–20 GB) for the OMV operating system itself
  • A physical disk, passed through directly to the VM, for your actual data

Keeping these separate matters — OMV refuses to store shared data on its own system disk, and passthrough gives near-native performance on the data disk.

Important order of operations: install OMV with only the OS disk attached, and add the physical data disk afterward. If both disks are present during install, OMV's partitioner can fail to show a proper disk-selection screen and loop on a "No root file system is defined" error instead. Attaching the data disk after install avoids this entirely.

Step 1: Place the OMV ISO where libvirt can read it

Download the ISO from https://www.openmediavault.org/download.html.

If virt-manager uses the system session (the default), QEMU runs as its own user and often can't read files inside your home folder. Avoid permission errors by moving the ISO into the default pool:

sudo mkdir -p /var/lib/libvirt/images
sudo mv ~/Downloads/openmediavault_*.iso /var/lib/libvirt/images/
Enter fullscreen mode Exit fullscreen mode

Step 2: Identify your target disk (don't attach it yet)

Find the disk with lsblk:

lsblk -o NAME,SIZE,MODEL,MOUNTPOINTS
Enter fullscreen mode Exit fullscreen mode

Unmount anything mounted from it:

sudo umount /dev/sdX1   # whatever partitions are mounted
Enter fullscreen mode Exit fullscreen mode

Also grab its stable identifier now, so it's ready later — /dev/sdX names can change across reboots, so use the by-id path instead:

ls -l /dev/disk/by-id/ | grep -v part
Enter fullscreen mode Exit fullscreen mode

Note the entry that matches your disk (e.g. ata-YourDiskModel_SerialNumber). You won't attach this disk to the VM until after OMV is installed.

Step 3: Create the VM

  1. virt-manager → File → New Virtual Machine
  2. Local install media (ISO) → select the OMV ISO
  3. Guest OS: Debian 12 (OMV 7 is based on it)

New virtual machine wizard in virt-manager showing the option to install from local ISO media

  1. RAM: 2048–4096 MB, CPUs: 2 is enough

virt-manager wizard step for allocating memory and CPU cores to the new VM

  1. Create a ~16–20 GB virtual disk — this becomes the OS disk only (do not attach the physical data disk at this stage)

virt-manager wizard step for creating the virtual disk image that will hold the OS

  1. Name the VM (e.g. omv), check "Customize configuration before install" → Finish

Step 4: Install OMV

Boot the VM and run through the installer. Since only the OS disk is present, the partitioner will offer just one option — select it, let it guide-partition automatically, set a root password, and complete the install.

At the console login, the username is root, with the password you set during install — this is separate from the OMV web interface login you'll use later.

Once you reach the login prompt successfully, shut the VM down:

sudo virsh shutdown omv
Enter fullscreen mode Exit fullscreen mode

Step 5: Attach the physical data disk

virt-manager steps how to add a new disk
Now that OMV is installed, attach the real disk.

Attach it via the command line — this avoids a common GUI mistake where selecting "custom storage" and typing just the disk name (without the full path) causes virt-manager to silently create a brand-new empty virtual disk file instead of using your real disk:

sudo virsh attach-disk omv /dev/disk/by-id/ata-YOUR-DISK-ID vdb --targetbus virtio --persistent
Enter fullscreen mode Exit fullscreen mode

If you prefer the GUI: Add Hardware → Storage → "Select or create custom storage", then paste the full absolute path (/dev/disk/by-id/...) into the field, bus type VirtIO.

Double-check it worked by opening the VM's XML (Edit → XML, or virsh dumpxml omv). You want:

<disk type="block" device="disk">
  <driver name="qemu" type="raw"/>
  <source dev="/dev/disk/by-id/ata-YOUR-DISK-ID"/>
  <target dev="vdb" bus="virtio"/>
</disk>
Enter fullscreen mode Exit fullscreen mode

If instead you see type="file" and a source file="..." pointing somewhere in your home folder, that's the mistake above — remove the disk, delete the accidental file it created, and reattach using the full path.

Boot the VM back up.

Step 6: Log into the web UI

Find the VM's IP:

ip a
Enter fullscreen mode Exit fullscreen mode

Browse to http://<vm-ip>. Default login: admin / openmediavault — change the password immediately.

Step 7: Wipe and format the data disk (from OMV, not the host)

  1. Storage → Disks → select your data disk → Wipe (quick wipe is fine)
  2. Storage → File Systems → Create
    • Select the disk
    • Filesystem: btrfs
    • Profile: single (this is the correct choice for one disk — you can convert to a mirror later without reformatting, once you add a second disk)
  3. Mount it when prompted, then apply the pending configuration (the yellow banner at the top — nothing takes effect until you click Apply)

Step 8: Create a shared folder, user, and SMB share

Shared folder:
Storage → Shared Folders → Create → name it (e.g. Documents), pick your btrfs filesystem, save, apply.

User:
Users → Users → Create → set username/password, add to the users group, shell nologin, leave SSH keys empty. This user is only for share access — don't reuse the admin account.

Enable SMB:
Services → SMB/CIFS → Settings → check Enabled, leave Workgroup as WORKGROUP, uncheck Home directories, minimum protocol SMB2. Save.

Create the share:
Services → SMB/CIFS → Shares → Create → pick your shared folder, Public: No, Browseable: checked, Enable recycle bin: checked. Save → Apply.

Test from the host:

smbclient -L //<vm-ip> -U yourusername
Enter fullscreen mode Exit fullscreen mode

You should see your share listed (alongside IPC$).

Step 9: Mount the share on your host

For it to behave like a real folder (so touch, editors, and every app work normally):

sudo pacman -S cifs-utils   # or apt install cifs-utils

sudo mkdir -p /mnt/nas
sudo mount -t cifs //<vm-ip>/Documents /mnt/nas \
  -o username=yourusername,uid=$(id -u),gid=$(id -g)
Enter fullscreen mode Exit fullscreen mode

To make this permanent and automatic, store the password in a credentials file and use a systemd automount in /etc/fstab, so the share connects on demand and doesn't hang at boot if the VM isn't running yet:

sudo nano /etc/samba-credentials
Enter fullscreen mode Exit fullscreen mode
username=yourusername
password=yourpassword
Enter fullscreen mode Exit fullscreen mode
sudo chmod 600 /etc/samba-credentials
Enter fullscreen mode Exit fullscreen mode

/etc/fstab line:

//<vm-ip>/Documents  /mnt/nas  cifs  credentials=/etc/samba-credentials,uid=1000,gid=1000,file_mode=0664,dir_mode=0775,noauto,x-systemd.automount,x-systemd.idle-timeout=60,_netdev  0  0
Enter fullscreen mode Exit fullscreen mode
sudo systemctl daemon-reload
Enter fullscreen mode Exit fullscreen mode

Note: mounted network shares don't show up in lsblk (that only lists block devices). Check with findmnt /mnt/nas or mount | grep cifs instead.

Step 10: Reach your NAS from your phone with Tailscale

NAT networking (virt-manager's default) only lets the host reach the VM. Rather than reconfigure networking with bridges, Tailscale tunnels through NAT with no router or bridge setup needed, and works from anywhere, not just at home.

On the VM:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Enter fullscreen mode Exit fullscreen mode

Open the printed login URL, sign in, then check the assigned address:

tailscale ip -4
Enter fullscreen mode Exit fullscreen mode

On your phone: install the Tailscale app, log into the same account, enable the VPN toggle.

For automatic backup (Android): install FolderSync, add an SMB account pointed at the VM's Tailscale IP, and create a folder pair (e.g. DCIM/CameraDocuments/PhoneBackup, sync direction "To remote folder"). Schedule it to run daily.

Tip: enable MagicDNS in the Tailscale admin console so you can use a hostname instead of memorizing an IP.

Keeping it running

Make the VM start automatically with the host:

sudo virsh autostart omv
Enter fullscreen mode Exit fullscreen mode

Planning ahead for redundancy

Because the data disk was formatted as btrfs, single profile, adding redundancy later is a live, in-place operation — no reformatting or data migration:

  1. Attach the new disk to the VM the same way as Step 5 (by-id path, virsh attach-disk)
  2. Wipe it from OMV's disk manager
  3. Convert to a mirror:
btrfs device add /dev/vdc /srv/dev-disk-by-uuid-xxxx
btrfs balance start -dconvert=raid1 -mconvert=raid1 /srv/dev-disk-by-uuid-xxxx
Enter fullscreen mode Exit fullscreen mode

Your data is then mirrored across both disks. Note this protects against a disk failure — it isn't a substitute for backups against accidental deletion.

Summary of pitfalls this guide avoids

  • ISO unreadable by QEMU → placed in /var/lib/libvirt/images
  • Installer failing to show disk selection → install OS with only the OS disk attached; attach the data disk afterward
  • Typing a disk name without its full path → accidentally creates a blank virtual disk file instead of using the real disk
  • Choosing the wrong filesystem for future growth → btrfs single, upgradeable to raid1 without reformatting
  • NAS only reachable from the host → Tailscale, no router/bridge configuration required

Top comments (0)