After close to two years of hard work, Debian 12 was released on June 10th, 2023 with plenty of new features and improvements from its predecessor, Debian 11(Bullseye).
If you’re running a private Cloud or Virtualization Platform powered by KVM, such as OpenStack and oVirt. The most ideal way to spin a Debian 12 virtual machine is from a Cloud image. In this blog we show you how you can download official Debian 12 cloud image and create a Virtual Machine instance from it on KVM hypervisor. In our future posts we will cover running Debian 12 Virtual Machine on OpenStack.
1. Download Debian 12 Cloud image
All Debian 12 Cloud images are available on official OS images downloads page. In this guide we will download the nocloud qcow2 image:
mkdir ~/cloud_images && cd ~/cloud_images
sudo wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-amd64.qcow2
You can check more details on the file using the file command:
$ file debian-12-nocloud-amd64.qcow2
debian-12-nocloud-amd64.qcow2: QEMU QCOW Image (v3), 3221225472 bytes (v3), 3221225472 bytes
For the raw image:
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-amd64.raw
2. Move Cloud Image to /var/lib/libvirt folder
We are going to create a template from the image we just created. Let’s create a folder in the /var/lib/libvirt/images folder:
sudo mkdir /var/lib/libvirt/images/templates
Move Debian 12 cloud image you just downloaded in Step 1:
sudo mv debian-12-nocloud-amd64.qcow2 /var/lib/libvirt/images/templates/
Confirm the current contents listed on the directory:
$ ls /var/lib/libvirt/images/templates/
debian-12-generic-amd64.qcow2 debian-12-nocloud-amd64.qcow2
3. Create Debian 12 (Bookworm) on KVM using Cloud Image
Next we create a Debian 12 (Bullseye) virtual machine from our cloud image.
Let’s save some important variables:
- Admin Username
- Admin user password
- Virtual Machine name
Save the variables as shown, but make sure you set the values to your liking:
export VM_NAME="Debian-12-Bookworm"
Once the variables are exported we create OS root disk image from the cloud image downloaded earlier:
sudo qemu-img convert \
-f qcow2 \
-O qcow2 \
/var/lib/libvirt/images/templates/debian-12-nocloud-amd64.qcow2 \
/var/lib/libvirt/images/$VM_NAME-root-disk.qcow2
Check file creation if successful:
$ file /var/lib/libvirt/images/$VM_NAME-root-disk.qcow2
/var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2: QEMU QCOW Image (v3), 3221225472 bytes (v3), 3221225472 bytes
$ sudo du -sh /var/lib/libvirt/images/$VM_NAME-root-disk.qcow2
1.3G /var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2
Resize the disk to desired size
Note that the root disk we created has a small disk capacity as defined in default cloud image.
$ qemu-img info /var/lib/libvirt/images/$VM_NAME-root-disk.qcow2
image: /var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2
file format: qcow2
virtual size: 3 GiB (3221225472 bytes)
disk size: 1.27 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
filename: /var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2
protocol type: file
file length: 1.27 GiB (1367605248 bytes)
disk size: 1.27 GiB
Let’s resize to our desired root disk size.
# I'm setting mine to 30GB - set yours accordingly
export VM_ROOT_DISK_SIZE=30G
# Resize Debian 12 VM disk
sudo qemu-img resize \
/var/lib/libvirt/images/$VM_NAME-root-disk.qcow2 \
$VM_ROOT_DISK_SIZE
Expected command output:
Image resized.
Confirm the current size with the qemu-img info command:
$ qemu-img info /var/lib/libvirt/images/$VM_NAME-root-disk.qcow2
imimage: /var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2
file format: qcow2
virtual size: 30 GiB (32212254720 bytes)
disk size: 1.27 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
filename: /var/lib/libvirt/images/Debian-12-Bookworm-root-disk.qcow2
protocol type: file
file length: 1.27 GiB (1367605760 bytes)
disk size: 1.27 GiB
Create a Debian 12 Virtual Machine using the virt-install command and the created disk.
virt-install \
--memory 2048 \
--vcpus 2 \
--name $VM_NAME \
--disk /var/lib/libvirt/images/$VM_NAME-root-disk.qcow2,device=disk,bus=virtio,format=qcow2 \
--os-variant debian12 \
--network network=default,model=virtio \
--virt-type kvm \
--graphics none \
--import
Use the following command to list all available OS variants.
sudo osinfo-query os
As of this article writing the latest variant of Debian is debian12.
4. Add standard user admin account
Login as root user – no password is required to get shell access.
localhost login: root
Linux localhost 6.1.0-32-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@localhost:~#
After login as root user, proceed to create the first admin user using adduser command:
root@debian:~# adduser sysadmin
root@localhost:~# adduser sysadmin
Adding user `sysadmin' ...
Adding new group `sysadmin' (1000) ...
Adding new user `sysadmin' (1000) with group `sysadmin (1000)' ...
Creating home directory `/home/sysadmin' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for sysadmin
Enter the new value, or press ENTER for the default
Full Name []: Sys Admin
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
Adding new user `sysadmin' to supplemental / extra groups `users' ...
Adding user `sysadmin' to group `users' ...
Check user id and group. It is evident the user is not in sudo privileged group.
root@localhost:~# id sysadmin
uid=1000(sysadmin) gid=1000(sysadmin) groups=1000(sysadmin),100(users)
Add the user created to sudo group for privilege escalation.
root@localhost:~# usermod -aG sudo sysadmin
root@localhost:~# id sysadmin
uid=1000(sysadmin) gid=1000(sysadmin) groups=1000(sysadmin),27(sudo),100(users)
Check if the user can login and use sudo command.
root@localhost:~# su - sysadmin
sysadmin@localhost:~$ sudo su -
[sudo] password for sysadmin:
root@localhost:~#
5. Set hostname and update system
Set hostname for your Virtual Machine:
root@localhost:~# hostnamectl set-hostname debian11-bookworm-01.localdomain
Confirm hostname is set correctly.
root@localhost:~# hostnamectl
Static hostname: debian12-bookworm-01.localdomain
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: c5759520f40f481fb464bad22b1673b9
Boot ID: 487917da658d4db58bd9f3d12f287e43
Virtualization: kvm
Operating System: Debian GNU/Linux 12 (bookworm)
Kernel: Linux 6.1.0-32-amd64
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Firmware Version: 1.16.3-debian-1.16.3-2
Logout the login again.
root@localhost:~# exit
logout
Debian GNU/Linux 12 debian12-bookworm-01.localdomain ttyS0
debian12-bookworm-01 login: sysadmin
Password:
Linux debian12-bookworm-01.localdomain 6.1.0-32-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
sysadmin@debian12-bookworm-01:~$
If the network attached to Virtual Machine uses DHCP to assign IP addresses, the instance should get a NATed IP address:
sysadmin@debian12-bookworm-01:~$ ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:e6:d5:04 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.209/24 metric 100 brd 192.168.122.255 scope global dynamic enp1s0
valid_lft 2795sec preferred_lft 2795sec
inet6 fe80::5054:ff:fee6:d504/64 scope link
valid_lft forever preferred_lft forever
Add the IP address and matching host name to /etc/hosts file.
$ sudo vim /etc/hosts
192.168.122.209 debian12-bookworm-01.localdomain
Update and upgrade system:
sudo apt updates
sudo apt upgrade -y
Reboot after the upgrade:
# reboot
Login with admin user created on the consoles that shows up after reboot.
Debian GNU/Linux 12 debian12-bookworm-01.localdomain ttyS0
debian12-bookworm-01 login: sysadmin
Password:
Linux debian12-bookworm-01.localdomain 6.1.0-32-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 27 20:39:53 UTC 2025 on ttyS0
sysadmin@debian12-bookworm-01:~$
Install OpenSSH Server:
sudo apt install -y openssh-server
Wait for keys to be generated before checking service status.
Creating config file /etc/ssh/sshd_config with new version
Creating SSH2 RSA key; this may take some time ...
3072 SHA256:ahGSy76B9WsY4beRBZ/naaoI1RkT9dxZXuBHRWsY8so [email protected] (RSA)
Creating SSH2 ECDSA key; this may take some time ...
256 SHA256:zuW/gkjwXMTtiWZtrfrrq6fH6ka1Gq7ui7wyOg5O4Uk [email protected] (ECDSA)
Creating SSH2 ED25519 key; this may take some time ...
256 SHA256:z1CDz+kNhUCXHfiOZp+JBrrr9LoMnOOkGbWEpOYbYjM [email protected] (ED25519)
Created symlink /etc/systemd/system/sshd.service/lib/systemd/system/ssh.service.
Created symlink /etc/systemd/system/multi-user.target.wants/ssh.service → /lib/systemd/system/ssh.service.
rescue-ssh.target is a disabled or a static unit, not starting it.
ssh.socket is a disabled or a static unit, not starting it.
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u10) ...
Restart ssh service to ensure it can come up without any issues in future.
sudo systemctl restart ssh
The service should now be running
$ sudo systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-03-27 20:55:53 UTC; 4min 21s ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 889 (sshd)
Tasks: 1 (limit: 2316)
Memory: 2.9M
CPU: 17ms
CGroup: /system.slice/ssh.service
889 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
Mar 27 20:55:53 debian12-bookworm-01.localdomain systemd[1]: Starting ssh.servi>
Mar 27 20:55:53 debian12-bookworm-01.localdomain sshd[889]: Server listening on>
Mar 27 20:55:53 debian12-bookworm-01.localdomain sshd[889]: Server listening on>
Mar 27 20:55:53 debian12-bookworm-01.localdomain systemd[1]: Started ssh.servic>
6. Add your ssh pubkey to sysadmin user account
To login via ssh from your workstation or KVM node, generate user ssh keys:
cloudspinx@kvm-host:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/cloudspinx/.ssh/id_rsa):
Created directory '/home/cloudspinx/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cloudspinx/.ssh/id_rsa
Your public key has been saved in /home/cloudspinx/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:Kzwt86BJaJkW4xO8MSWnFI0c83o2rrQ01w+iC/v9xd0 cloudspinx@kvm-host
The key's randomart image is:
+---[RSA 3072]----+
| .++ |
| o+. |
| o + |
| o * |
| X + S |
| . # + o o . |
|. & = X = . E |
| B X + @ |
|..*.+.. o |
+----[SHA256]-----+
Create a file on VM:
sysadmin@debian12-bookworm-01:~$ touch ~/.ssh/authorized_keys
Copy your host ssh public key and add to file ~/.ssh/authorized_keys on created VM:
$ vim ~/.ssh/authorized_keys
Or use ssh-copy:
cloudspinx@ubuntu-24:~$ ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/cloudspinx/.ssh/id_rsa.pub"
The authenticity of host '192.168.122.209 (192.168.122.209)' can't be established.
ED25519 key fingerprint is SHA256:z1CDz+kNhUCXHfiOZp+JBrrr9LoMnOOkGbWEpOYbYjM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
Test remote connection:
cloudspinx@ubuntu-24:~$ ssh sysadmin@192.168.122.135
Linux debian12-bookworm-01.localdomain 6.1.0-32-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 27 20:52:35 2025
sysadmin@debian12-bookworm-01:~$ hostnamectl
Static hostname: debian12-bookworm-01.localdomain
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: c5759520f40f481fb464bad22b1673b9
Boot ID: f98dd60c19d148689873bcd8ef97dd33
Virtualization: kvm
Operating System: Debian GNU/Linux 12 (bookworm)
Kernel: Linux 6.1.0-32-amd64
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Firmware Version: 1.16.3-debian-1.16.3-2
We have been able to create a Debian 12(Bookworm) Virtual Machine on KVM using Cloud image base image. Additionally, we created an admin user account, updated the system, and uploaded a public ssh key for passwordless authentication. In our future guide we will look at creation of Virtual Machine from Cloud image with Cloud-init user-data instance configurations.
More guides on Virtualization: