How to Detect Virtualization and Container Environments in Ubuntu Using systemd-detect-virt

In modern cloud engineering, DevOps automation, and fleet systems administration, shell scripts and deployment pipelines must frequently adapt their execution based on the underlying hardware environment. For example, an administrative script provisioning an Ubuntu system may need to skip hardware microcode updates or physical RAID monitoring tools when executing inside a cloud virtual machine (VM), or bypass systemd service daemon controls when executing inside an isolated application container. While inspecting /proc/cpuinfo, DMI tables via dmidecode, or lspci outputs requires parsing text heuristically, Ubuntu includes the purpose-built systemd-detect-virt binary. This tool delivers fast, exit-code-driven identification of hypervisors and container technologies directly from the command line.

How systemd-detect-virt Identifies Virtual Platforms

The systemd-detect-virt utility inspects CPU hypervisor flags, ACPI tables, SMBIOS hardware strings, and container namespace identifiers:

  • Hardware Virtualization (Hypervisors): Detects hardware-assisted hypervisors by querying the CPUID instruction for hypervisor feature bits and reading vendor strings (e.g. KVM, QEMU, VMware, Hyper-V, Xen, VirtualBox, and Apple Virtualization Framework).
  • Operating System Containers: Detects container environments by inspecting /proc/1/environ (such as container= environment variables), cgroup mount hierarchies, and namespace isolations (e.g. Docker, Podman, LXC, systemd-nspawn, OpenVZ, and Kubernetes containerd).
  • Exit Code Logic: Returns exit code 0 when executing inside a virtualized or container environment, and exit code 1 (non-zero) when executing on bare-metal physical hardware.

Basic Execution and Environment Output

To inspect the virtualization layer of an Ubuntu system, execute the command without parameters:

# Detect the active virtualisation environment
systemd-detect-virt

The output reports the specific hypervisor or container technology name:

# Output example on an AWS EC2 instance or Proxmox VM:
kvm

# Output example inside a Docker or Podman container:
docker

# Output example on a bare-metal physical server:
none

Distinguishing Between Virtual Machines and Containers

By default, if an Ubuntu instance runs inside a container hosted on a virtual machine, systemd-detect-virt prioritizes reporting the innermost container environment. Use command flags to target specific virtualization tiers:

# Query only hardware hypervisors (virtual machines)
systemd-detect-virt --vm

# Query only container environments
systemd-detect-virt --container

If executed inside a Docker container running on a KVM virtual machine, --vm returns kvm, while --container returns docker.

Using systemd-detect-virt in Shell Automation Scripts

Because the utility utilizes standard Linux return codes, administrators can construct clean conditional branching logic in deployment scripts:

#!/bin/bash
# Shell automation script demonstrating environment branching

if systemd-detect-virt --quiet; then
    VIRT_TYPE=$(systemd-detect-virt)
    echo "Virtualised environment detected: $VIRT_TYPE"
else
    echo "Bare-metal physical hardware detected. Initialising physical hardware sensors..."
    sudo sensors-detect --auto
fi

The --quiet or -q flag suppresses stdout, ensuring the command outputs nothing while cleanly setting the shell return code ($?) for silent conditional checks.

Conditional Service Execution in systemd Unit Files

Beyond shell scripts, systemd-detect-virt powers native condition checks within systemd service definitions via ConditionVirtualization=:

[Unit]
Description=Hardware Watchdog Daemon
Documentation=man:watchdog(8)
# Only execute if running on physical bare-metal hardware
ConditionVirtualization=false

[Service]
ExecStart=/usr/sbin/watchdog -F
Restart=always

[Install]
WantedBy=multi-user.target

Alternatively, services tailored for virtualized guests (such as QEMU guest agent or Hyper-V KVP daemon) can specify ConditionVirtualization=vm or ConditionVirtualization=kvm to ensure the daemon automatically skips execution if installed on physical hardware.

Auditing Supported Virtualization and Container Identifiers

To view the complete catalog of hypervisor and container technologies recognized by systemd on Ubuntu:

# List all known hypervisors and container engines
systemd-detect-virt --list

The catalog includes modern architectures such as WSL (Windows Subsystem for Linux), bhyve, Parallels, UML (User-Mode Linux), and rkt.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.