Полноценная виртуальная машина внутри Docker с веб-интерфейсом

15 авг 2026
2,097
243
15
3 недели

QEMU Docker Logo

Иногда нужно быстро проверить сомнительный скрипт, протестировать установку софта на чистом дистрибутиве или развернуть окружение со специфичным ядром. Запускать ради этого VirtualBox лень, поднимать Proxmox на рабочем ноутбуке избыточно, а обычный Docker-контейнер не дает изоляции на уровне ядра.

Недавно наткнулся на репозиторий qemus/qemu. Проект упаковывает QEMU с ускорением KVM внутрь обычного Docker-контейнера и пробрасывает управление виртуальной машиной прямо в браузер.

Как устроен проект

По сути, перед нами обертка над QEMU, которая берет на себя всю рутину по настройке эмулятора, сети, дисков и noVNC-клиента. Вам не нужно вручную прописывать длинные флаги командной строки или возиться с XML-конфигами libvirt.

Всё управление сводится к передаче переменных окружения в docker-compose.yml. Образ сам скачивает нужный дистрибутив Linux, нарезает виртуальный диск, подключает KVM для околонативной скорости работы и открывает порт с веб-интерфейсом на порту 8006.

Реклама

Контейнер подходит как для локальной разработки, так и для запуска виртуалок в Kubernetes или GitHub Codespaces.

Быстрый старт

Для запуска достаточно минимального compose-файла. Например, развернем Linux Mint:

services:
  qemu:
    image: qemux/qemu
    container_name: qemu
    environment:
      BOOT: "mint"
      RAM_SIZE: "4G"
      CPU_CORES: "2"
    devices:
      - /dev/kvm
      - /dev/net/tun
    cap_add:
      - NET_ADMIN
    ports:
      - 8006:8006
    volumes:
      - ./qemu_data:/storage
    restart: always
    stop_grace_period: 2m

После выполнения команды docker compose up -d сервис автоматически скачает ISO-образ Mint и запустит виртуализацию.

Переходим в браузере по адресу http://localhost:8006 и видим экран установки ОС. Никаких дополнительных VNC-клиентов ставить не придется.

# Если вы предпочитаете чистый Docker CLI:
docker run -it --rm --name qemu \
  -e "BOOT=alpine" \
  -p 8006:8006 \
  --device=/dev/kvm \
  --device=/dev/net/tun \
  --cap-add NET_ADMIN \
  -v "${PWD}/qemu_data:/storage" \
  --stop-timeout 120 \
  docker.io/qemux/qemu

Что умеет контейнер

Автоматическая загрузка дистрибутивов

В переменной BOOT можно указать короткое имя популярного дистрибутива. Скрипт знает, откуда стянуть свежие образы:

  • arch, debian, fedora, ubuntu, alpine
  • kali, nixos, gentoo, mint, manjaro
  • rocky, alma, cachy, tails

Если нужной системы нет в списке заготовленных, можно передать прямую ссылку на любой образ:

environment:
  BOOT: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-virt-3.19.1-x86_64.iso"

Контейнер распаковывает архивы на лету и поддерживает образы .iso, .qcow2, .vmdk, .vhdx и .vdi. Также можно смонтировать локальный файл напрямую в корень контейнера как /boot.iso.

Работа с дисками и памятью

По умолчанию виртуалка получает диск размером 64 ГБ в формате qcow2 внутри директории /storage. Изменить размер можно в любой момент через переменную DISK_SIZE: "128G".

Если на хосте заканчивается оперативная память, контейнер поддерживает memory ballooning. Это помогает динамически возвращать неиспользуемую память гостевой системы хосту.

Обмен файлами с хостом

Чтобы передать файлы между хостом и виртуалкой, используется протокол 9pfs:

volumes:
  - ./my_host_folder:/shared

Внутри запущенной гостевой системы останется только смонтировать каталог:

mount -t 9p -o trans=virtio shared /mnt/shared

Проброс портов и полноценная сеть

При стандартном bridge-режиме Docker проброс портов настраивается привычным блоком ports. Чтобы пробросить SSH наружу:

ports:
  - 8006:8006
  - 2222:22

Если виртуалке нужен собственный IP-адрес в локальной сети (чтобы домашний роутер выдал ей отдельный адрес по DHCP), контейнер можно подключить через macvlan. В таком случае отпадает необходимость в постоянном маппинге портов.

Проброс реального оборудования

Через compose-файл можно прокидывать реальные физические накопители (/dev/sdb:/disk1) или USB-устройства, передавая их идентификаторы в QEMU:

environment:
  ARGUMENTS: "-device usb-host,vendorid=0x1234,productid=0x5678"
devices:
  - /dev/bus/usb

Системные требования и ограничения

Главный нюанс кроется в поддержке KVM.

Без прямого доступа к устройству /dev/kvm аппаратное ускорение работать не будет, а чистая программная эмуляция CPU сделает работу невыносимо медленной.

Где это работает гладко:

  1. Linux-хосты с поддержкой аппаратной виртуализации (Intel VT-x / AMD-V).
  2. Windows 11 с Docker Desktop или Podman Desktop при включенной вложенной виртуализации (nested virtualization).

Docker Desktop на macOS и Windows 10 в настоящее время не пробрасывает /dev/kvm внутрь контейнеров, поэтому запустить проект там не получится.

Проверить доступность KVM на Linux можно стандартной утилитой:

sudo apt install cpu-checker
sudo kvm-ok

Если команда выдает KVM acceleration can be used, контейнер запустится без проблем.

Для чего это можно использовать

  1. Тестирование сценариев автоматизации. Запуск чистых инсталляций Ansible или bash-скриптов в изолированной виртуалке без риска сломать рабочую систему.
  2. Безопасный запуск софта. Проверка подозрительных пакетов или бинарников в изолированном окружении, которое можно пересоздать одной командой.
  3. Обучение и эксперименты. Знакомство с новыми дистрибутивами (например, NixOS или Alpine) прямо в окне браузера без возни с флешками.
  4. CI/CD пайплайны. Сборка пакетов ядра или тестирование системного софта внутри полноценных виртуальных машин на раннерах Kubernetes.

Резюме

Проект qemus/qemu отлично закрывает нишу между легковесными контейнерами и тяжелыми гипервизорами. Если вам регулярно требуются изолированные виртуальные машины для тестов на Linux-машине или домашнем сервере, этот образ экономит массу времени на подготовке образов и настройке сети.

Репозиторий активно поддерживается организацией qemus, у них также есть отдельные адаптированные сборки под ARM64, Windows и macOS.

🍪 Мы используем файлы cookie и сервис аналитики Яндекс.Метрика, чтобы сайт работал лучше. Продолжая пользоваться devtrends.ru, вы соглашаетесь с обработкой данных согласно Политике конфиденциальности.