When you are working with a remote cloud server, you are usually working with a virtual machine: a sandboxed, isolated instance of an entire operating system that is running within a larger server cluster. You can also work with virtual machines locally on your desktop, using software like QEMU or VirtualBox. Virtual machines may include an entire desktop interface, or they may only run an SSH server to allow terminal connections. In either case, they are technically similar, and make similar assumptions. Apart from any large-scale cloud optimizations, the only significant difference between virtualization environments is that the virtual machine hard disks and configuration options. These are referred to as virtual machine images, and are formatted differently across providers.
In this tutorial, you will learn how to convert between virtual machine image formats (including
vmdk), so that you can take your virtual environments from your desktop to the cloud and back again as needed.
The commands in this tutorial can be run on Windows, macOS, or Linux, as long as you can install QEMU and VirtualBox along with their command line tools. This tutorial provides installation instructions using the Homebrew package manager. You can install Homebrew on macOS, on Linux, or on Windows under WSL2.
If you are running on a DigitalOcean droplet, you should have at least 2 CPUs and 2GB of memory.
You will also need at least 10GB of free space to run the commands in this tutorial.
Note: If you are using macOS with an Apple Silicon CPU (manufactured in 2020 and later), you will only be able to use QEMU and not VirtualBox.
QEMU is the most powerful and widely supported open source virtualization software. It runs on all major platforms (including Windows, macOS, Linux, and other operating systems like Android) and is capable of both virtualization and emulation as needed. For instance, if you are running a Linux server image on a Windows desktop (a common use case), both of those platforms share a common underlying architecture (Intel/AMD x86), so QEMU can achieve full performance through virtualization. If you are using QEMU to mix and match architectures, for example by running x86 Linux or Windows (as either the “host” or the “guest” operating system) with the ARM architectures of macOS or Android, QEMU will automatically use emulation to translate architectures.
Compared with virtualization, emulation is usually not used in production environments because it adds a significant performance penalty. However, QEMU treating virtualization and emulation as near-equivalent provides significant compatibility advantages, since it means that the same image formats and the same tools can be used in every scenario.
QEMU is command line software, and has a high learning curve compared to desktop virtualization software like VMware or VirtualBox due to the huge number of options that virtual machines can be configured with. It can optionally be used with GUI frontends such as QtEmu on Windows or Linux and UTM on macOS. This tutorial will provide command line instructions for working with QEMU.
To install QEMU, use Homebrew’s
- brew install qemu
This will provide the entire suite of QEMU tools and commands, including
qemu-img, which is used to convert virtual machine images on the command line. Verify that you have access to the
qemu-img command by running
- which qemu-img
Note: You can also install QEMU on Windows using its native installer, if you prefer to work on Windows without WSL2.
QEMU provides most of the functionality that you will need in this tutorial. You can also install VirtualBox, another popular virtualization package.
VirtualBox is open source virtualization software provided by Oracle. It supports all x86 operating systems (Windows, Linux, and macOS computers manufactured before 2020). It does not support emulation or non-x86 architectures, making it primarily useful for running Linux under Windows and vice versa. However, it is also more straightforward to use than QEMU, provides widely compatible default settings, and includes a desktop interface by default.
It does not provide as much command line functionality as QEMU, so it is often paired with dedicated orchestration software like Vagrant to automate and reproduce virtual machine configurations. However, it does include the
VBoxManage command-line tool, which can be used to manipulate some virtual machine images.
To install VirtualBox on macOS, use
brew install with the
–cask flag, because VirtualBox is distributed as a full application bundle, which Homebrew calls a cask:
- brew install --cask virtualbox
To install VirtualBox on Ubuntu or Debian-derived Linux distributions (including under WSL2), first use
apt update to refresh your package sources, then
- sudo apt update
- sudo apt install virtualbox
To install VirtualBox on Windows without WSL2, refer to its download page.
After installing VirtualBox, verify that you have access to the
vboxmanage command by running
- which vboxmanage
There are alternatives available to QEMU and VirtualBox for virtualization. However, most of these are platform-specific (such as Hyper-V on Windows) or designed for large-scale enterprise use (such as VMware). They will not be covered directly in this tutorial, but you will convert their image formats in the following steps.
To demonstrate converting virtual machine images, you can start by creating an image with QEMU. You can skip this section if you already have an image to convert.
qemu-img create command with the
-f qcow2 flag to create an image in QEMU’s default
- qemu-img create -f qcow2 ubuntu-desktop-22.04.qcow2 10G
At this point, you will have created an empty virtual machine image. Even though you named it
ubuntu-desktop-22.04.qcow2 and provided a capacity of
10G, at this point it will neither have Ubuntu 22.04 installed nor be 10GB large.
OutputFormatting 'ubuntu-desktop-22.04.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=10737418240 lazy_refcounts=off refcount_bits=16
QEMU images will always take up as little space as possible on your disk, while reflecting their maximum declared capacity to any software running within the virtual machine. In this case, 10GB would be the capacity that your virtual machine thinks it has available, and the maximum size that the virtual machine image will automatically scale up to.
A typical next step would be to install Ubuntu 22.04 onto the virtual machine, using a Ubuntu 22.04 ISO. However, you can skip this step for this tutorial, as you won’t actually be working directly with this virtual machine. An ISO is another type of disk image that is usually read-only, and was historically written onto CD and DVD installation media, rather than an image of a writable hard disk. Other software exists for manipulating ISO images, such as mkisofs and dd. To learn more about installing Linux using QEMU, refer to the QEMU documentation.
Once you’ve created a VM image, you can use
qemu-img convert to convert it to other formats.
vdi is the default image format of VirtualBox. By default, this will not erase the original VM image, only create a new one:
- qemu-img convert -f qcow2 ubuntu-desktop-22.04.qcow2 -O vdi ubuntu-desktop-22.04.vdi
-f flag is used to specify the input format and the input filename. The
-O flag is used to specify the output format and the output filename. You can also include the
-p flag to show a progress bar, which is helpful when converting very large images. The image that you created in the last step will convert instantly, because it does not have any contents yet. You can confirm that you created
- ls ubuntu-desktop-22.04.vdi
Other common formats include
vmdk, used primarily by VMware, and
vhd, used primarily by Microsoft’s Hyper-V. You can also create a “raw” image if your software requires it, following the next step.
If you have an image in
vdi format, you can use the
vboxmanage command provided by VirtualBox to convert it:
- vboxmanage clonemedium ubuntu-desktop-22.04.vdi ubuntu-desktop-22.04.img --format raw
Output0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Clone medium created in format 'raw'. UUID: 0501e707-c94e-4103-9069-d7b64a933d78
Note that this will automatically register the created image with your local VirtualBox configuration, which may be inconvenient if you are trying to create transient copies. You may have to manually remove any new entries from the VirtualBox interface if you inadvertently register duplicates.
Raw virtual machine images are not compressed at all, so this command will actually create a full 10GB file, unlike before. You can convert it back to
qcow2 format for use with QEMU by reversing the syntax from the last step:
- qemu-img convert -f raw ubuntu-desktop-22.04.img -O qcow2 ubuntu-desktop-22.04-new.qcow2
You can now delete the raw image to reclaim disk space:
- rm ubuntu-desktop-22.04.img
Finally, you can use the
qemu-img check and
qemu-img info commands to output some metadata from your virtual machine images:
- qemu-img check ubuntu-desktop-22.04.qcow2
OutputNo errors were found on the image. Image end offset: 262144
- qemu-img info ubuntu-desktop-22.04.qcow2
Outputimage: ubuntu-desktop-22.04.qcow2 file format: qcow2 virtual size: 10 GiB (10737418240 bytes) disk size: 196 KiB cluster_size: 65536 Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false refcount bits: 16 corrupt: false extended l2: false
Note: You can also upload these Virtual Machine images to DigitalOcean to use as cloud server images, by following DigitalOcean’s Custom Image documentation
In this tutorial, you used QEMU and VirtualBox’s command line tools to create, convert, and export virtual machine images. You reviewed some common examples of virtual machine image formats, as well as some useful default assumptions for working with virtual machines. It’s always helpful to understand the technologies underlying common concepts like virtualization, especially if you need to migrate architectures or cloud providers.
Next, you may want to review our guide to scaling virtual machines for your needs.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.