Vagrant: автоматизация создания виртуальных машин


Vagrant  — это набор скриптов на Ruby, который предназначен для того, чтобы автоматизировать работу с виртуальными машинами на вашем компьютере. Чаще всего он используется для быстрого развертывания окружения для разработки ПО.

Зачем может понадобиться использовать виртуальную машину для разработки? Причин тому может быть много. Прежде всего, это необходимость использования разных версий библиотек и компонентов в разных проектах, а также разработка приложений под конкретную среду.

Кажется, что это не так уж и важно, но на самом деле, гораздо удобнее развернуть виртуалку с нужными вещами, чем засорять систему и ломать голову, как разрулить какие-нибудь конфликты. Думаю каждый, кто работал с крупными проектами, сталкивался с подобным вещами. Обычно развернуть и настроить среду в виртуальной машине не очень сложно, но, как правило, занимает довольно много времени. Vagrant позволяет избавиться от всей этой рутины.

Установка

Автор постарался и сделал нормальные установщики под все операционные системы [1]. На протяжении всего повествования мы будем пользоваться средством виртуализации Virtual Box [2], так как Vagrant создавался в первую очередь для него. Предпочитающие VMware, тоже могут воспользоваться Vagrant, подробности есть у них на сайте [3].

Настройка

После того, как вы установили Vagrant, потребуется создать файл файл с настройками машины, который называется Vagrantfile. Нет нужды создавать его самостоятельно, для этого есть соотвествующая команда vagrant init.

Для себя выработал такую практику: в папке каждого проекта есть папка /env, в которой лежат все файлы нужные для того, чтобы с нуля развернуть девелоперское окружение. Там создаю Vagrantfile, кладу необходимые кукбуки для Chef и т.д.

Важный момент, который нужно учитывать при работе с Vagrantfile: Vagrant использует не только тот файл, который лежит непосредственно в папке вашего проекта, но и тот, который поставляется с базовым образом машины, тот что лежит в папке с настройками (~/.vagrant.d) и т.д. Полный перечень и принцип работы подробнее можно посмотреть в документации [4].

Теперь откроем получившийся Vagrant-файл. В нем вы увидите код на Ruby и множество закомментированных строчек. Уверен, что большинству для базовой настройки будет достаточно раскомментировать нужные строчки и вписать в них необходимые значения. Далее я просто рассмотрю самые важные для нас понятия.

Если удалить все комментарии, то минимальная конфигурация, которая должна содержаться в Vagrantfile будет выглядеть следующим образом:

# -*- mode: ruby -*-
 
VAGRANTFILE_API_VERSION = "2"
 
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"
end

Здесь я написал, что хочу использовать 32-битную Ubuntu 12.04, и указал URL по которому её можно скачать. Этого же результата можно было добиться просто запустив команду init с соотвествующими параметрами.

vagrant init precise32 http://files.vagrantup.com/precise32.box

Уверен, вызывает вопрос расширение *.box. Никакой особенной магии тут нет: это обычный zip-архив в котором лежит vmdk-образ виртуальной машины и Vagrantfile с дефолтными настройками. У Vagrant довольно большое сообщество, и базовую сборку на любой вкус можно найти на сайте vagrantbox.es.

Скорее всего, просто с дефолтными параметрами запускать машину никому не захочется. Все что я напишу далее, можно найти и в комментариях сгенерированного вами Vagrantfile, я же просто заострю внимание на самых значимых вещах. Девелоперское окружение подразумевает хотя бы наличие расшареных папок и портов (чтобы вы работали в своем привычном окружении, а ваш софт — в своем).

config.vm.network "forwarded_port", guest: 3000, host: 3333
config.vm.synced_folder "../project_folder_host", /project_folder_guest

Думаю из примера очевидно: первая строчка отвечает за форвардинг портов (как можно догадаться, это порт по-умолчанию сервера в Rails) c гостевой машины на хост. Вторая строчка отвечает за создание «прозрачной» папки на гостевой машине.

Естественно, можно сконфигурировать и параметры самой виртуальной машины, например увеличим оперативную память:

config.vm.provider "virtualbox" do |vb|
  vb.customize ["modifyvm", :id, "--memory", "1024"]
end

Важный момент: по-умолчанию в Vagrant машина запускается в headless-режиме, т.е. вы не увидите окно Virtual Box с ОС внутри. Предполагается, что общение с виртуалкой будет происходить по SSH. Если по каким-либо причинам вас это не устраивает, то в этот же блок нужно добавить:

vb.gui = true

На всякий случай, приведу полный пример конфига.

# -*- mode: ruby -*-
 
VAGRANTFILE_API_VERSION = "2"
 
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"
  config.vm.network "forwarded_port", guest: 3000, host: 3333
  config.vm.synced_folder "../project_folder_host", /project_folder_guest
 
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end
 
end

Я написал много букв, но как видите, настройка сводится к указанию небольшого количества параметров и совершенно не требует знания Ruby.

Запуск, остановка и удаление машины

Запуск машины производится командой vagrant up (из той же папки, где лежит Vagrantfile). После этого автоматически скачается базовый образ, указанный в url, создастся и запустится виртуальная машина, к которой можно будет присоединиться по SSH (словом, нужно только дождаться появления сообщения: «Machine booted and ready!»). Далее пишем vagrant ssh, откроется соединение с машиной и можно делать все, что душа пожелает.

Когда наиграетесь, появится закономерное желание выключить машину. Для этого:
vagrant suspend — сохранить состояние машины;
vagrant halt — выключить машину.

Все сломали своими экспериментами и хотите полностью удалить машину?
vagrant destroy — удаляет машину, создать заново с нуля можно будет в любой момент при помощи vagrant up!

[1] Страница загрузок Vagrant
[2] Страница загрузок VirtualBox
[3] Информация об использовании Vagrant с VMware
[4] Документация по Vagrantfile