| Tested on | RHEL 10.2 (Coughlan) KVM/VirtualBox guest |
|---|---|
| Package | systemd 257-23.el10_2.2virt-what 1.27-3.el10dmidecode 3.6-5.el10 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Fedora, Debian, Ubuntu, and other Linux distributions with systemd, DMI sysfs, and standard virtualization tools |
| Privilege | Normal user for systemd-detect-virt and sysfs reads; sudo for dmidecode and virt-what on some hosts |
| Scope | Detect bare metal, full virtual machines, and containers on Linux using systemd-detect-virt, virt-what, dmidecode, /sys/class/dmi/id, and lscpu. Does not cover remote out-of-band hardware inventory or non-Linux Unix systems. |
| Related guides | dmidecode command lscpu command dnf command systemctl command |
You may need to know whether Linux runs on bare metal, under a hypervisor, or inside a container before tuning performance, licensing software, or opening a support case. Start with systemd-detect-virt, then confirm with virt-what, DMI data, or lscpu when the answer must be reliable.
Quick reference: physical vs virtual Linux server
| Method | Command | Best use |
|---|---|---|
| systemd | systemd-detect-virt |
Fastest VM and container detection |
| systemd VM only | systemd-detect-virt --vm |
Ignore the container layer |
| systemd container only | systemd-detect-virt --container |
Detect Docker, Podman, or LXC |
| virt-what | virt-what |
Identify common hypervisors |
| DMI | sudo dmidecode -s system-product-name |
Platform name from SMBIOS |
| sysfs | cat /sys/class/dmi/id/product_name |
Lightweight DMI read without full dmidecode |
| CPU | lscpu |
Hypervisor and virtualization-type clues |
The first command to run:
systemd-detect-virtOn the RHEL 10.2 lab guest (VirtualBox), that prints oracle. On bare metal you typically see none.
systemd-detect-virt distinguishes full-machine virtualization from containers and reports the innermost detected layer by default.
Check physical or virtual server with systemd-detect-virt
systemd-detect-virt is the primary tool on modern Linux. It reads kernel and cgroup hints and prints a short type name.
systemd-detect-virtCommon outputs include kvm, vmware, microsoft (Hyper-V), oracle (VirtualBox), xen, amazon, google, docker, podman, lxc, wsl, and none. The exact list grows with systemd; run systemd-detect-virt --list on your host to see what your build recognizes.
When several layers exist, the default command reports the innermost environment. A process inside a container on a KVM VM may show docker or podman first.
To inspect only full-machine virtualization:
systemd-detect-virt --vmOn the lab guest:
oracleTo inspect only the container layer:
systemd-detect-virt --containerOn the same host (not inside a container):
noneRun systemd-detect-virt --vm and systemd-detect-virt --container separately when you need to distinguish the underlying VM from a container running on top of it.
Detect the hypervisor with virt-what
virt-what probes DMI, CPU flags, and other clues to name common hypervisors.
Install on RHEL-family systems:
sudo dnf install virt-whatOn Debian or Ubuntu:
sudo apt install virt-whatRun it (root is usually required):
sudo virt-whatSample output on the lab guest:
virtualbox
kvmNested or hybrid setups can print more than one line. An empty result does not prove bare metal — virt-what documents that no output may mean either physical hardware or an unrecognized virtualization platform.
Check virtualization with dmidecode
SMBIOS data often names the platform vendor and product. Use targeted queries instead of dumping the full system table first.
Read the manufacturer:
sudo dmidecode -s system-manufacturerSample output on the lab VirtualBox guest:
innotek GmbHRead the product name:
sudo dmidecode -s system-product-nameSample output:
VirtualBoxTypical physical server reference values (not from the current lab — common bare-metal patterns):
Dell Inc.
PowerEdge R760Typical virtual machine patterns include KVM, VMware Virtual Platform, VirtualBox, and Google Compute Engine. Cloud guests may still report a virtual product even when the provider name is not obvious.
For the full system DMI block when you need serial numbers or UUIDs, see the dmidecode command guide and run sudo dmidecode -t system.
Check DMI information from /sys/class/dmi/id
The same SMBIOS fields are exposed as read-only sysfs files without invoking dmidecode.
Read the vendor:
cat /sys/class/dmi/id/sys_vendorSample output on the lab guest:
innotek GmbHRead the product name:
cat /sys/class/dmi/id/product_nameSample output:
VirtualBoxReference physical server examples often look like:
Dell Inc.
PowerEdge R760Reference KVM guest examples often look like:
Red Hat
KVMSome containers and minimal images omit DMI files entirely. If cat fails with “No such file”, use systemd-detect-virt instead.
Check hypervisor information with lscpu
lscpu reports CPU topology and virtualization hints visible to the guest.
lscpuFilter for the hypervisor lines:
lscpu | grep -iE 'hypervisor|virtualization'Sample output on the lab guest:
Hypervisor vendor: KVM
Virtualization type: fullIn a virtualized guest, lscpu describes the guest-visible CPU layout, not necessarily the physical host topology.
Identify KVM, VMware, Hyper-V, VirtualBox, or cloud VMs
Map tool output to likely environments:
| Output or evidence | Likely environment |
|---|---|
systemd-detect-virt → kvm |
KVM/QEMU |
vmware |
VMware |
microsoft |
Hyper-V |
oracle |
VirtualBox |
amazon |
AWS EC2 (Nitro) |
google |
Google Compute Engine |
xen |
Xen |
none |
No virtualization detected |
docker / podman / lxc |
Container (shared host kernel) |
A machine in a public cloud is still a virtual machine even when the provider string is generic. Virtualization type and cloud provider are related questions but not identical.
VM vs container vs bare metal
Three deployment shapes matter on modern Linux:
Bare metal — Linux runs directly on physical hardware. systemd-detect-virt usually prints none, and DMI may show a server vendor such as Dell or HPE.
Virtual machine — Linux sees emulated or paravirtual hardware under a hypervisor (KVM, VMware, Hyper-V, VirtualBox, Xen). Use systemd-detect-virt --vm when a container might sit above the VM.
Container — Processes share the host kernel (Docker, Podman, LXC). Detection:
systemd-detect-virt --containerInside a running container with systemd tools available, that prints docker, podman, or lxc instead of none. Minimal container images may not ship systemd-detect-virt; check from the host namespace or inspect cgroup metadata instead.
When virtualization detection results disagree
Tools can report different answers when:
- A container runs inside a VM (innermost layer wins by default)
- Nested virtualization is enabled (
virt-whatmay list multiple hypervisors) - A cloud provider masks or genericizes SMBIOS fields
- DMI data is missing in containers or lightweight images
- A hypervisor spoofs generic hardware IDs
- A tool does not yet recognize a new virtualization product
Suggested order to check:
systemd-detect-virt
↓
virt-what
↓
dmidecode or /sys/class/dmi/id
↓
lscpuNo single DMI string proves physical hardware. When boot messages are all you have, dmesg | grep -i dmi may show a firmware line on some hosts, but permissions and kernel settings can block dmesg, and the output is less consistent than the tools above.
References
- systemd
systemd-detect-virtmanual — https://www.freedesktop.org/software/systemd/man/latest/systemd-detect-virt.html - Linux
dmidecode(8)manual — https://man7.org/linux/man-pages/man8/dmidecode.8.html - util-linux
lscpu(1)manual — https://man7.org/linux/man-pages/man1/lscpu.1.html - virt-what project — https://people.redhat.com/~rjones/virt-what/
Summary
To check if a Linux server is physical or virtual, run systemd-detect-virt first. Use --vm and --container when nested layers matter. Confirm hypervisor type with virt-what, then read dmidecode -s system-manufacturer and system-product-name or the matching /sys/class/dmi/id files. lscpu adds CPU-level hypervisor clues.
none from systemd-detect-virt usually means bare metal, but treat conflicting or empty results carefully — especially on cloud VMs and inside containers. When tools disagree, compare the type of evidence each tool is reporting. systemd-detect-virt is the best first-purpose detector; virt-what, DMI, and lscpu provide useful supporting evidence but use different detection mechanisms.
On a host where you only have shell access and no root, systemd-detect-virt and sysfs reads still work; reserve dmidecode and virt-what for when you need a second opinion and can use sudo.

