If I want to quickly install a GNU / Linux distribution on my computer, installing it in a virtual machine and then converting a virtual computer into a real one by copying the virtual disk to a physical hard disk (this process, call the “implementation”).
You can use a virtual disk as a template for quick and easy deployment of the system to multiple computers. I have a whole set of templates for various configurations, for example, for desktops and servers, for 32 and 64-bit machines, for various Linux distributions. All of them are ready to install at any time. In this article my recipe is given for converting a virtual computer into a real one. I worked with Debian 4 and 5 distributions (servers and desktops) and floppyfw (routers and firewalls). This method should work with most (if not all) Linux distributions. I used VirtualBox to create virtual machines, but any other virtualization solution (VMware, QEMU, Parallels, etc.) should also work. I by no means guarantee success – use this method at your own risk!

Create a virtual machine

I assume that you already know how to create a virtual machine and install GNU / Linux in it, so I will not describe this process in detail. I usually create a virtual machine with a small hard drive, the entire file system is located on the first partition. If you need additional partitions for / home, / var, etc., I prefer to create them later, on a real machine, as will be described below. For desktops and servers, a virtual disk of about 8 GB is enough. 
Install GNU / Linux and all the necessary applications in a virtual machine, as well as make all the necessary settings.

Cleaning (optional)

You can reduce the size of a compressed virtual disk by deleting unnecessary files and free disk space. In Debian, you can significantly increase free space by clearing the cache of downloaded software packages with the command:

$ apt-get clean

Now let’s see how much disk space we have:

df

Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda1 7360760 3409528 3577324 49% /
tmpfs 126644 0 126644 0% /lib/init/rw
udev 10240 80 10160 1% /dev
tmpfs 126644 0 126644 0% /dev/shm

In the above example, the size of the free space is 3577324 blocks (each of 1 KB). 
To remove free space, create a file filled with zeros, slightly smaller than the size of free space. To be sure, to avoid mistakes, we take its size to be 3577324 – 1000 = 3576324 blocks:

$ dd if = / dev / zero of = / zeroes.bin bs = 1024 count = 3576324

Now delete this file:

$ rm /zeroes.bin

To automate the above process, you can use a script that itself determines the size of the free space and deletes it:

freespace=df | grep ' /$' | perl -ple 's/^[^ ]+ +[^ ]+ +[^ ]+ +([^ ]+) .*/$1/'
mycount=$(( $freespace – 1000 ))
dd if=/dev/zero of=/zeroes.bin bs=1024 count=$mycount
rm /zeroes.bin

Copying a virtual disk to a file

We want to extract data from a virtual disk in such a way that it is suitable for copying to a physical disk. To do this, I connected the virtual disk with a second disk to another virtual machine. Start this virtual machine and view the partition table of the second disk.

fdisk -l /dev/hdb

Disk /dev/hdb: 8053 MB, 8053063680 bytes
255 heads, 63 sectors/track, 979 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdb1 * 1 931 7478226 83 Linux
/dev/hdb2 932 979 385560 5 Extended
/dev/hdb5 932 979 385528+ 82 Linux swap / Solaris

We want to copy everything from the beginning of the disk to the end of the first partition, i.e. first 931 cylinder. Find the number of blocks of 512 bytes in size that need to be copied: 931 * 16065 = 14956515. The command below copies the data into a compressed file.

$ dd if = / dev / hdb bs = 512 count = 14956515 | gzip> /mnt/nfs/template.bin.gz

here template.bin.gz is a compressed data file, / mnt / nfs is a shared directory in which I save it. Of course, the directory can be any.

Copy file to physical hard disk

Boot a physical computer from GNU / Linux. I used a USB stick with Debian installed on it, but any GNU / Linux live CD will do. In order to access the file containing the data for the hard disk (in my case template.bin.gz), you need to connect to the network folder in which it is located, or copy it to any media. 
Copy data to hard disk:

$ cat /mnt/nfs/template.bin.gz | gunzip> / dev / hda

In your case, replace “/ mnt / nfs” with the path to the directory where you have the data file. Also, replace / dev / hda with your hard disk (for example, it could be / dev / sda) /

Disk partitioning

Now the hard disk has exactly the same partition table as the virtual disk. If you want the actual hard disk partitions to be exactly the same size as on the virtual disk, you can skip the following sections before configuring the host name and network. However, the physical disk is usually much larger than the virtual disk, and if you want to use the available free space, for example, to expand the swap partition or increase the home directory, read on. 
We use fdisk or any of its analogs to edit the partition table of the hard disk (in my case / dev / hda).
I usually delete all existing partitions, except for the first one (/ dev / hda1). Then I create a 2 GB swap partition (/ dev / hda2), and use the remaining space to create a large partition under / home (you can instead create separate partitions under / home and / var). Save the changes and exit fdisk. 
The following is the breakdown for my 400 GB hard drive.

fdisk -l /dev/hda

Disk /dev/hda: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x0004a22d
Device Boot Start End Blocks Id System
/dev/hda1 * 1 931 7478226 83 Linux
/dev/hda2 932 1175 1959930 82 Linux swap / Solaris
/dev/hda3 1176 48641 381270645 83 Linux

Format the second swap partition:

$ mkswap / dev / hda2

Usually I format the / home partition into an ext3 file system:

$ mke2fs -j -m 1 / dev / hda3

Moving home directories

Mount the first and third partitions (“/” and “/ home”, respectively):

$ mkdir / mnt / hda1 
$ mount -t ext3 / dev / hda1 / mnt / hda1
$ mkdir / mnt / hda3
$ mount -t ext3 / dev / hda3 / mnt / hda3

Move your home directories from / dev / hda1 to / dev / hda3:

$ mv / mnt / hda1 / home / * / mnt / hda3

Editing fstab

Edit / mnt / hda1 / etc / fstab to reflect the fact that / home is now on a separate section. Below is my edited fstab:

/etc/fstab: static file system information.
#
proc /proc proc defaults 0 0
/dev/hda1 / ext3 errors=remount-ro 0 1
/dev/hda2 none swap sw 0 0
/dev/hda3 /home ext3 errors=remount-ro 0 0

Host name and network settings

The settings described below apply to Debian 5. For other systems, it may be necessary to edit other files located elsewhere. If you want the real system to have a different host name than the one from the virtual machine, edit the file / mnt / hda1 / etc / hostname, replacing the host name in it. 
A network interface can get a name that is different from the one in the virtual machine, for example, “eth1” instead of “eth0”. To avoid this, for example, if you manually configured the network, edit the file /mnt/hda1/etc/udev/rules.d/70-persistent-net.rules and delete the line that relates to the existing network interface. If you need to change network settings, edit the file / mnt / hda1 / etc / network / interfaces.

Turn off the computer and remove the USB flash drive or CD. Turn on the computer again. If everything went well, you will see the real version of your virtual machine