Vagrant Как на хостовой Ubuntu автоматически в VirtualBox создать виртуальную машину и развернуть в ней микросервис

Предварительная настройка Ubuntu 22.04

Рекомендуемая связка для Ubuntu 22.04:

Компонент         Версия          Комментарий
Ubuntu                 22.04.4 LTS Последний стабильный релиз на момент июля 2025
Vagrant                2.3.7 / 2.4.7  Стабильная версия, работает с VirtualBox 6.1 и 7.x
VirtualBox           6.1.50             Последняя версия 6-й ветки, надёжна и совместима
Guest Additions 6.1.50             Должна точно совпадать с VirtualBox
ядро Ubuntu      6.5 (LTS)       Если установлено ядро 6.8.x, оно слишком новое для VirtualBox 6.1.50
vagrant-vbguest 0.32.0            Опционально. Можно использовать для автоматического обновления Guest Additions

Почему не VirtualBox 7.x?
Версия 7.x всё ещё не в полной мере поддерживается Vagrant.
Есть проблемы с синхронизацией папок, NAT-сетями и плагинами (особенно на Linux-хостах).
VirtualBox 6.1.50 — максимально стабильная и хорошо поддерживаемая версия на июль 2025.

Почему нужно ядро 6.5?
VirtualBox (особенно версии 6.1.x и даже 7.x) официально не поддерживает ядро Linux 6.8, т.к. его модули (vboxdrv, vboxpci и др.) не компилируются или работают нестабильно на этом ядре. VirtualBox несовместим с ядром 6.8.0-60-generic. На практике на ядре 6.2 у большинства пользователей всё работает с VBox 6.1.50, но это не гарантировано. VirtualBox 6.1.50 был официально протестирован и патчен на совместимость с ядром 6.5.x.

1. Откат (или установка) ядра до версии 6.5

Проверьте свою версию ядра:

uname -r

Если ядро уже версии 6.5, переходим к шагу 2.
Если нет, посмотрите все установленные ядра:

dpkg -l | grep linux-image

Если в этом списке нет ядра 6.5 (LTS), то нужно его установить:

sudo apt install linux-image-6.5.0-26-generic linux-headers-6.5.0-26-generic

Затем сделаем ядро 6.5 загрузочным по умолчанию, например, таким способом:
откройте файл

sudo nano /etc/default/grub

найдите в нём строку

GRUB_DEFAULT=0

и замените на

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.5.0-26-generic"

сохраните изменения и закройте файл
обновите конфиг GRUB

sudo update-grub
sudo reboot

После перезагрузки убедимся, что всё прошло успешно:

uname -r

должны увидеть версию "6.5.0-26-generic"

2. Установка Vagrant

sudo apt update
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install vagrant

Проверим установленную версию:

vagrant --version

3. Установка VirtualBox

sudo apt install virtualbox

Проверим установленную версию:

VBoxManage --version

должны увидеть версию "6.1.50" (6.1.50_Ubuntur161033)

4. Дополнительно

Проверим текущий компилятор в текущей системе:

gcc --version

например: gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Проверим, каким компилятором собрано ядро:

cat /proc/version 

например: x86_64-linux-gnu-gcc-12
Хорошо, если их версии совпадают, но, вероятно, всё будет работать и так.

Но если возникнут с этим проблемы, то решение такое:
установим компилятор gcc-12

sudo apt install gcc-12 g++-12

зарегистрируем альтернативы

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 120
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 110
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 120

выберем нужную версию

sudo update-alternatives --config gcc
sudo update-alternatives --config g++

проверим результат

gcc --version  
g++ --version 

Создание с помощью Vagrant виртуальной машины с микросервисом (например, ktu-auth) внутри

1. Создание Vagrant-проекта

mkdir ~/my-vagrant
cd ~/my-vagrant
vagrant init

Таким образом, в домашней директории пользователя создадим директорию проекта "my-vagrant", а команда "vagrant init" создаст в ней дефолтный файл Vagrantfile.

2. Создание локальной копии удалённого репозитория

Перед запуском виртуальной машины микросервис ktu-auth, указанный в Vagrantfile, должен уже находиться в папке проекта my-vagrant. Поэтому, из данной папки выполним команду:

git clone <АдресРепозитория>

Вместо <АдресРепозитория> подставьте URL вашего репозитория!

3. Монтаж образа Гостевых дополнений

Скачаем ISO отсюда:
https://download.virtualbox.org/virtualb...
и поместим его в папку проекта "my-vagrant" (путь к этой папке пропишем в нашем Vagrantfile)

4. Автоматизация управления над Virtualbox

Отредактируем Vagrantfile в любом текстовом редакторе — замените содержимое файла на следующее:

# -*- mode: ruby -*-
Vagrant.configure("2") do |config|
  # Используем официальную Ubuntu 22.04 LTS (Jammy)
  config.vm.box = "ubuntu/jammy64"

  # Настройка провайдера VirtualBox
  config.vm.provider "virtualbox" do |vb|
    vb.name = "ubuntu2204-vbox"    # имя виртуальной машины в VirtualBox
    vb.memory = 2048               # выделяем 2 ГБ оперативки
    vb.cpus = 2                    # 2 CPU
    vb.gui = false                 # без GUI, если нужна — true
    vb.customize ["storageattach", :id,
          "--storagectl", "IDE", # ← вот контроллер, имя узнать можно так: "VBoxManage showvminfo ubuntu2204-vbox | grep -i controller"
          "--port", "1",
          "--device", "0",
          "--type", "dvddrive",
          "--medium", "/home/<your-name>/my-vagrant/VBoxGuestAdditions_6.1.50.iso"] # вместо <your-name> подставьте ваше имя пользователя!
  end

  # Синхронизация папок (тип "virtualbox" по умолчанию для Linux-хостов)
  config.vm.synced_folder "./ktu-auth", "/var/www/ktu-auth", type: "virtualbox"

  # Настройка приватной сети с IP
  config.vm.network "private_network", ip: "192.168.56.10"

  # Установка необходимых пакетов
  config.vm.provision "shell", inline: <<-SHELL
    # Не взаимодействовать с пользователем при установке (для предотвращения зависаний)
    export DEBIAN_FRONTEND=noninteractive

    set -e

    echo "Проверка и восстановление dpkg, если был прерван..."
    dpkg --configure -a || true

    echo "Обновление списка пакетов..."
    apt-get update -y

    echo "Установка Make и необходимых утилит..."
    apt-get install -y make apt-transport-https ca-certificates curl gnupg lsb-release

    echo "Установка GPG ключа Docker (если ещё нет)..."
    if [ ! -f /etc/apt/keyrings/docker.gpg ]; then
      install -m 0755 -d /etc/apt/keyrings
      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
      chmod a+r /etc/apt/keyrings/docker.gpg
    fi

    echo "Добавление репозитория Docker (если не добавлен)..."
    if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
      echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
      | tee /etc/apt/sources.list.d/docker.list > /dev/null
    fi

    echo "Повторное обновление кэша пакетов..."
    apt-get update -y

    echo "Установка Docker и Compose Plugin..."
    apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    echo "Очистка кэша пакетов..."
    apt-get autoremove -y

    echo "Добавление пользователя vagrant в группу docker..."
    if getent group docker > /dev/null; then
      usermod -aG docker vagrant
    fi

    echo "Проверка, входит ли пользователь vagrant в группу docker..."
    if id vagrant | grep -q '\\bdocker\\b'; then
      echo 'Пользователь vagrant уже в группе docker.'
    else
      echo 'ВНИМАНИЕ: Пользователь vagrant ещё не в группе docker.'
      echo 'Для применения групп выполните команду: "vagrant reload" или "vagrant destroy && vagrant up" чтобы применить изменения.'
    fi

    echo "✅ Установка завершена."
  SHELL
end

Вместо <your-name> (строка 17) подставьте ваше имя пользователя в Ubuntu!

5. Запуск виртуальной машины

VirtualBox может быть не запущен. Из папки проекта выполним команду:

vagrant up

В этом шаге Vagrant:

  • скачает образ Ubuntu (если его нет)
  • создаст и запустит ВМ
  • настроит сеть
  • установит окружение
  • запустит сервер

Если появилась ошибка, содержащая строку наподобие:

... VBoxManage: error: Could not find a controller named 'IDE'\n">
Please fix this customization and try again.

значит, мы неправильно указали название контроллера в Vagrantfile.
Имя контроллера (строка 13) нужно предварительно узнать командой:

VBoxManage showvminfo ubuntu2204-vbox | grep -i controller

смотрим что напротив "Storage Controller Name (0)" — впишите это имя в строке 13 вместо "IDE"
и ещё раз:

vagrant up

Если на этом шаге вдруг всё зависло и надолго — принудительно перезагрузите систему. Потом в Vagrantfile (строка 9) временно установите лимит оперативки в 1 ГБ:

vb.memory = 1024

и затем с нуля пресоберите VM командами:

vagrant destroy -f
vagrant up

Запуск проекта в созданной гостевой системе

В нормальной работе с Vagrant не стоит входить в ОС через VirtualBox вручную (но если очень хочется, то вот стандартные учётные данные для всех Vagrant-образов Ubuntu: логин: vagrant пароль: vagrant).
Вместо этого нужно использовать команду "vagrant ssh" из основной системы из папки проекта:

cd ~/my-vagrant
vagrant ssh

таким образом зашли в гостевую систему через терминал хостовой системы:

vagrant@ubuntu-jammy:~$

перейдём в папку проекта (уже внутри гостевой VM), над которым нужно работать:

cd /var/www/ktu-auth

посмотрим содержимое папки ktu-auth:

ls -l

выйдем из виртуалки:

exit

1. Проверим, готова ли VM к использованию Docker и Compose без sudo

vagrant ssh
docker --version
docker compose version

ожидаемый результат:

vagrant@ubuntu-jammy:~$ docker --version
Docker version 28.3.1, build 38b7060
vagrant@ubuntu-jammy:~$ docker compose version
Docker Compose version v2.38.1

Ещё проверим, входит ли пользователь vagrant в группу docker:

groups

ожидаемый результат:

vagrant docker

2. Соберём и запустим контейнеры микросервиса ktu-auth

cd /var/www/ktu-auth
make docker.start.all

3. Вероятно, при первом запуске возникнет такая ошибка

network nginx_dev_local_network declared as external, but could not be found
make: *** [Makefile:41: docker.start.all] Error 1

Добавим сеть вручную:

docker network create nginx_dev_local_network

Проверим:

docker network ls | grep nginx_dev_local_network

Повторно выполним:

make docker.start.all

Если на это раз всё ОК, должны увидеть что-то вроде:

...
Локальное приложение  KTU-auth: http://localhost:9731
Описание API KTU-auth Swagger: http://localhost:19736

4. Далее подтягиваем зависимости

make composer.install

Если всё прошло успешно, из браузера из хостовой системы должны открываться страницы:
Локальное приложение KTU-auth: http://192.168.56.10:9731
Описание API KTU-auth Swagger: http://192.168.56.10:19736