Applies to: any Linux system with GNU dd; tested on Debian 13 (coreutils 9.7, util-linux 2.41.5, qemu-img 10.0.13) with image files; loop mounting from the util-linux manual
To create a disk image in Linux, copy the whole disk into a file with dd: sudo dd if=/dev/sdb of=/backup/sdb.img bs=4M status=progress conv=fsync. The file is an exact, sector-by-sector copy, including the partition table and boot loader. You can compress it, look inside it, and write it back to a disk later.
Before you start
- Image a disk that isn’t in use. A copy of a mounted, running file system can be inconsistent. For the system disk of a server, boot a rescue or live system first (on a dedicated server, attach a live ISO through the IPMI console, as in installing a custom ISO).
- Save the image somewhere else: another disk, a mounted backup volume or another server. Never on the disk you are copying.
- Check
if=andof=twice.ifis what you read,ofis what dd overwrites. Swapped, they destroy the disk.
Find the disk’s name with lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS: disks show as disk (such as sda, vda or nvme0n1) and their partitions as part.
1. Create the image
sudo dd if=/dev/sdb of=/backup/sdb.img bs=4M status=progress conv=fsync
bs=4M reads and writes 4 MiB at a time instead of dd’s default of 512 bytes; status=progress shows progress while it runs; conv=fsync makes sure everything is written before dd exits. In our test with a 256 MiB disk image it ended with:
64+0 records in 64+0 records out 268435456 bytes (268 MB, 256 MiB) copied, 0.178011 s, 1.5 GB/s
The image is as big as the whole disk, even if the disk is mostly empty. Check it with sha256sum: the source and the image gave the same checksum in our test.
2. Compress it, or send it to another server
sudo dd if=/dev/sdb bs=4M status=progress | gzip -c > /backup/sdb.img.gz sudo dd if=/dev/sdb bs=4M status=progress | zstd -o /backup/sdb.img.zst
Our mostly empty 256 MiB test disk shrank to 255 KB with gzip and 8.6 KB with zstd. Real disks compress less: space that once held deleted files still contains the old data. In our test, an empty 128 MiB file system compressed to 0.1 MiB, but after writing and deleting a 60 MiB file it still compressed to 60.1 MiB.
If the server has no room for the image, pipe it to another server over SSH instead:
sudo dd if=/dev/sdb bs=4M status=progress | gzip -c | ssh user@backup.example.com 'cat > /backup/sdb.img.gz'
3. Look inside the image
fdisk reads the partition table straight from the file:
$ fdisk -l sdb.img Disk sdb.img: 256 MiB, 268435456 bytes, 524288 sectors Units: sectors of 1 * 512 = 512 bytes ... Disklabel type: gpt Device Start End Sectors Size Type sdb.img1 2048 133119 131072 64M Linux filesystem sdb.img2 133120 522239 389120 190M Linux filesystem
To open the files in it, attach the image as a loop device and mount a partition read-only (commands from the util-linux manual; they need root on a real system, so we didn’t run them in our container lab):
sudo losetup --find --show --partscan sdb.img # prints e.g. /dev/loop0 sudo mount -o ro /dev/loop0p1 /mnt # ... copy what you need ... sudo umount /mnt sudo losetup -d /dev/loop0
Or in one step, using the partition’s start sector from fdisk -l times 512 as the offset:
sudo mount -o loop,ro,offset=$((2048*512)) sdb.img /mnt
4. Restore the image
This overwrites the whole target disk:
sudo dd if=/backup/sdb.img of=/dev/sdb bs=4M status=progress conv=fsync gunzip -c /backup/sdb.img.gz | sudo dd of=/dev/sdb bs=4M status=progress conv=fsync
The target must be at least as large as the original. In our test the restored copy had the same SHA-256 checksum as the original.
Variations
- One partition only: use the partition as the source,
if=/dev/sdb1. You can check an ext4 partition image without mounting it:e2fsck -fn part1.img. - Save space without compressing:
conv=sparseskips writing blocks of zeros. Our 256 MiB image used 8 MB on disk this way (du -h), whilels -lstill showed 256 MiB. - Use the image in a virtual machine:
qemu-img convert -O qcow2 sdb.img sdb.qcow2converts it for KVM; our qcow2 file used 388 KiB. - Copy disk to disk without a file in between: see clone a partition or hard drive in Linux.
A disk image is a full snapshot, but it is slow to restore single files. For regular backups, file-level tools are usually better, such as backups with rsync to a VPS. Our unmanaged dedicated servers include free IPMI KVM, so you can boot a live ISO from the console to image the system disk.
Official documentation: GNU dd, losetup(8) and mount(8).
