09.06.2026

How to Create a Virtual Disk in Linux?

When administering servers, you often need flexible disk space: temporary ultra-fast storage for cache, an isolated container for testing file systems, an encrypted volume for confidential data, or the ability to expand a disk on the fly without stopping a service. In all these cases, creating a virtual disk is the solution — a block device not directly tied to a physical medium.

In this article, we will show how to create virtual disks of four main types in Linux: loop devices (file‑based), tmpfs (in RAM), LVM volumes (flexible management), and LUKS encryption. For each type we provide step‑by‑step instructions with commands and real output examples. The material is aimed at system administrators, DevOps engineers, developers, and anyone who works with servers, including cloud environments.

Terminology

How Virtual Disks Work

The Linux kernel works with block devices through a unified interface. When a program or file system accesses /dev/loop0 or /dev/mapper/secret, the kernel redirects requests to the appropriate driver: a loop device reads/writes to an ordinary file, tmpfs to RAM, LVM to physical volumes according to a mapping table, and dm-crypt first decrypts data (on read) or encrypts it (on write).

This makes it possible to create “disks” where no physical disk exists and achieve desired properties: speed, isolation, transparent encryption, or resizable size.

Practical Use Cases (Main Scenarios)

Scenario Virtual disk type Why choose it
Fast cache, temporary build files tmpfs Maximum speed, automatic cleanup
Mount an ISO image without writing to physical media loop Simplicity, no physical drive needed
Flexible disk expansion on a running server LVM Resize without recreating the file system
Instant backup before an update LVM snapshot Takes seconds and little space
Storing secrets (databases, certificates) LUKS (dm-crypt) Without the password, data cannot be read
Space saving in virtualisation or containers LVM thin provisioning Allocated 100 GB, used 10 GB

Practical Guide: How to Create a Virtual Disk in Linux

All commands are run with sudo (if you are not root). Example outputs are provided for verification.

1. Creating a Virtual Disk Using a Loop Device (from a file)

Goal: create a file virtual_disk.img, turn it into the block device /dev/loop0, format it, and mount it.

Create an empty file of 1 GB:

sudo dd if=/dev/zero of=virtual_disk.img bs=1M count=1024

Expected output:

1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.123456 s, 8.7 GB/s

Associate the file with a free loop device:

sudo losetup --find --show virtual_disk.img

Expected output (the loop device number may differ):

/dev/loop0

Check that the device appeared (use the displayed loop device number from this step onward):

lsblk /dev/loop0

Expected output:

NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0       7:0    0    1G  0 loop

Create a file system (ext4):

sudo mkfs.ext4 /dev/loop0

Expected output (abbreviated):

mke2fs 1.46.5 (30-Dec-2021)
Discarding device blocks: done
Creating filesystem with 262144 4k blocks and 65536 inodes
...
Writing superblocks and filesystem accounting information: done

Mount it:

sudo mkdir -p /mnt/vdisk
sudo mount /dev/loop0 /mnt/vdisk
df -h /mnt/vdisk

Expected output:

Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0      974M   24K  907M   1% /mnt/vdisk

After finishing, unmount and release the loop device:

sudo umount /mnt/vdisk
sudo losetup -d /dev/loop0

2. Creating a tmpfs Disk in RAM

Goal: create a /mnt/ramdisk partition of 2 GB that works in RAM.

Create the mount point and mount tmpfs with a 2 GB limit:

sudo mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=2G tmpfs /mnt/ramdisk

Expected output: the mount command prints nothing on success.

Verify:

df -h /mnt/ramdisk

Expected output:

Filesystem      Size  Used Avail Use% Mounted on
tmpfs           2.0G     0  2.0G   0% /mnt/ramdisk

(Optional) Check write speed:

dd if=/dev/zero of=/mnt/ramdisk/test bs=1M count=500

Expected output: very high speed (gigabytes per second).

Remove the test file and unmount (data will be lost):

sudo rm /mnt/ramdisk/test
sudo umount /mnt/ramdisk

Automatic mounting at boot: add a line to /etc/fstab:

tmpfs  /mnt/ramdisk  tmpfs  defaults,size=2G  0  0

3. Creating an LVM Volume (Logical Virtual Disk)

Goal: from disk /dev/vdb create a physical volume (PV), a volume group (VG), and a logical volume (LV) of size 10 GB, then expand it to 15 GB without unmounting.

Note: working with partitions requires the lvm2 package (Logical Volume Manager).

Assume you have an additional disk /dev/vdb (or /dev/sdb) with no partitions on it (to erase partitions (data will be lost, do not use a disk that contains important data) use sudo wipefs -a /dev/sdb).

Create a physical volume:

sudo pvcreate /dev/vdb

Expected output:

  Physical volume "/dev/vdb" successfully created.

Create a volume group:

sudo vgcreate vg_data /dev/vdb

Expected output:

  Volume group "vg_data" successfully created

Create a logical volume of 10 GB:

sudo lvcreate -L 10G -n lv_storage vg_data

Expected output:

Logical volume "lv_storage" created.

Format and mount:

sudo mkfs.ext4 /dev/vg_data/lv_storage
sudo mkdir -p /mnt/storage
sudo mount /dev/vg_data/lv_storage /mnt/storage

Expected output from mkfs.ext4: a message about creating the file system.

Check the size:

df -h /mnt/storage

Expected output:

Filesystem                     Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_storage  9.8G   24K  9.3G   1% /mnt/storage

Expand the volume to 15 GB (on the fly):

sudo lvextend -L 15G /dev/vg_data/lv_storage

Expected output:

  Size of logical volume vg_data/lv_storage changed from 10.00 GiB (2560 extents) to 15.00 GiB (3840 extents).
  Logical volume vg_data/lv_storage successfully resized.

Expand the file system (for ext4):

sudo resize2fs /dev/vg_data/lv_storage

Expected output:

resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/vg_data/lv_storage is mounted on /mnt/storage; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/vg_data/lv_storage is now 3932160 (4k) blocks long.

Check the new size:

df -h /mnt/storage

Expected output:

Filesystem                     Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_storage   15G   24K   14G   1% /mnt/storage

Creating a snapshot (instant copy) for backup:

Create a snapshot of size 1 GB:

sudo lvcreate -L 1G -s -n lv_snapshot /dev/vg_data/lv_storage

Expected output:

  Logical volume "lv_snapshot" created.

Mount the snapshot and copy data:

sudo mkdir -p /mnt/snapshot
sudo mount /dev/vg_data/lv_snapshot /mnt/snapshot
ls /mnt/snapshot

After the backup, remove the snapshot:

sudo umount /mnt/snapshot
sudo lvremove /dev/vg_data/lv_snapshot

Expected output on removal:

Do you really want to remove active logical volume vg_data/lv_snapshot? [y/n]: y
  Logical volume "lv_snapshot" successfully removed.

4. Creating an Encrypted Virtual Disk (LUKS)

Goal: encrypt disk /dev/vdc (or any other) using LUKS, open it as /dev/mapper/secret, and mount it.

Attention: this operation will destroy data on /dev/vdc.

Note: working with partitions requires the cryptsetup package (an open‑source utility; used to configure disk encryption based on the dm-crypt kernel module).

Initialise LUKS (set a passphrase):

sudo cryptsetup luksFormat /dev/vdc

Expected output:

WARNING!
========
This will overwrite data on /dev/vdc irrevocably.

Are you sure? Type uppercase yes: YES
Enter passphrase for /dev/vdc: ********
Verify passphrase: ********

Open the device (/dev/mapper/secret is created):

sudo cryptsetup open /dev/vdc secret

Expected output: (after entering the passphrase) nothing, or in verbose mode: Enter passphrase for /dev/vdc:

Check that the device appeared:

lsblk /dev/mapper/secret

Expected output:

NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
secret    253:0    0    1G  0 crypt

Create a file system and mount:

sudo mkfs.ext4 /dev/mapper/secret
sudo mkdir -p /mnt/encrypted
sudo mount /dev/mapper/secret /mnt/encrypted
df -h /mnt/encrypted

Expected output:

Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/secret   974M   24K  907M   1% /mnt/encrypted

Work with the encrypted disk. After a reboot you need to run cryptsetup open again.

How to close and reopen:

sudo umount /mnt/encrypted
sudo cryptsetup close secret

5. Creating a Thin LVM Volume with Space Saving

Goal: create a thin pool of 50 GB and a volume for which we set a “ceiling” of 200 GB, but physically it will occupy only the data that is actually written.

Note: working with partitions requires the lvm2 package (Logical Volume Manager).

Create a thin pool (assume the volume group vg_data already exists):

sudo lvcreate -L 50G -T vg_data/thin_pool

Expected output:

  Logical volume "thin_pool" created.

Create a thin volume with a virtual size of 200 GB:

sudo lvcreate -V 200G -T vg_data/thin_pool -n thin_volume

Expected output:

  Logical volume "thin_volume" created.

Format and mount:

sudo mkfs.ext4 /dev/vg_data/thin_volume
sudo mkdir -p /mnt/thin
sudo mount /dev/vg_data/thin_volume /mnt/thin

Check actual usage (Data% — percentage of used space in the pool):

sudo lvs -a -o +pool_lv,data_percent,metadata_percent

Expected output (example):

  LV          VG      Attr       LSize   Pool     Data%  Meta%
  thin_pool   vg_data twi-a-tz--  50.00g           0.01   0.02
  thin_volume vg_data Vwi-a-tz-- 200.00g thin_pool 0.01

Here Data% = 0.01 means that out of the 50 GB pool only about 5 MB are actually used, while the volume appears as 200 GB.

Conclusion

This article has shown how to create a virtual disk in Linux in four different ways: a loop device based on a file (convenient for experiments and images), tmpfs in RAM (maximum speed), an LVM volume (flexible size management and snapshots), and LUKS encryption (security for confidential data). Each of these methods solves specific tasks in the daily work of an administrator, developer, or DevOps engineer.

Now you can:

Use these instructions as a cheat sheet when configuring servers – both your own and in cloud infrastructure. All commands have been tested and work on current Linux distributions (Ubuntu 22.04+, Debian 12+, CentOS/RHEL 9+).