Репост моей статьи с хабра.
Этот пост получился в результате моего ознакомления с Otto, одним из последних продуктов Hashicorp, о котором уже была обзорная статья на хабре.
Мой пост носит более практический характер. Я решил поднять на otto стандартный проект, чтобы сразу не наткнуться на тонкости настройки, а чтобы было интересно, выбрал Drupal 8, вышедший недавно.
Установка
Последняя версия, отмеченная тегом - 0.1.2 от 20.10.2015. Забегая вперед, скажу, что у меня не получилось сходу настроить MySQL на ней, а еще, заглянув в CHANGELOG, решил попробовать master ветку из-за Layered Dev Environments.
Otto 0.1.3-dev требует Vagrant 1.7.99+, так как стабильная версия 1.7.4, это значит, что Vagrant тоже нужен из master ветки.
UPD: вышел Vagrant 1.8, собирать Vagrant больше не надо.
Компиляция обоих проектов хорошо описана на страницах otto и vagrant, мне хватило полчаса, чтобы поставить golang, настроить gopath и скомпилировать оба проекта без знания Go и Ruby. Главное не забыть добавить
export PATH="$GOPATH/bin:$PATH"
Перезапускаем терминал, проверяем, что у нас запускаются dev-версии: vagrant version
, otto version
.
Настройка NFS
Напрямую к otto не относится, но, узнав об ужасной тормознутости стандартных virualbox shared folders, осознал необходимость настроить NFS.
На Ubuntu достаточно установить пакеты nfs-common nfs-kernel-server и добавить в /etc/sudoers несколько строк, чтобы Vagrant не спрашивал пароль при каждом запуске, подробнее в документации.
Подготовка проекта
Скачаем Drupal 8:
git clone https://github.com/drupal/drupal.git drupal8
cd drupal8
Appfile
Appfile - основной файл конфигурации otto для проекта, должен быть в корне проекта.
Вообще его может вообще не быть, тогда otto сам определит требования к окружению, в котором может запуститься приложение. Логика определения типа приложения проще некуда, например, проект будет определен как php, если в корне есть файлы *.php
otto compile
Первая команда, которая нужна в otto - otto compile. Она анализирует проект и его Appfile, после чего генерирует дерево в папке .otto, содержащее всю информацию о конфигурации dev и deploy окружений.
Документация советует не править руками содержимое этой папки. Но смотреть можно и нужно.
Также будет сгенерирован .ottoid
- уникальный идентификатор вашего приложения, по которому otto будет отслеживать его деплой, хранить историю, использовать его как зависимость и т.д.
К этому моменту наше окружение описано и готово к развертыванию.
otto dev
Следующее, что нужно - развернуть локальное dev окружение на локальной машине. По сути, otto dev - то же самое, что vagrant up.
Layered Dev Environments
Интересна концепция слоев, они очень похожи на слои Docker: при первом запуске otto dev
виртуальное окружение Vagrant будет настраиваться последовательно,
делая снимок после каждого шага. Слои описаны в типе приложения. Всё это позволяет сильно сократить время пересоздания dev окружения.
Таким образом, мы получаем мгновенный запуск готового окружения даже при полном пересоздании виртуальной машины.
Разница между перезапуском и пересозданием машины (otto dev halt && time otto dev
и otto dev destroy && time otto dev
) составляет около 5 секунд.
Судя по changelog, vagrant этот функционал не получит, по крайней мере в следующей версии, зато в Vagrant появится функционал для создания snapshots.
Посмотреть слои можно командой otto dev layers
:
$ otto dev layers
consul
php5.6
В результате, в случае PHP приложения, otto должен выдать дальнейшие инструкции:
$ otto dev
IP address: 100.66.143.21
A development environment has been created for writing a PHP app.
You can access the environment from this machine using the IP address above.
For example, if you start your app with 'php -S 0.0.0.0:5000', then you can
access it using the above IP at port 5000.
Что мы получили с автоматической настройкой?
- Ubuntu 12.04 (на данный момент нельзя выбирать базовый образ системы)
- Consul
- PHP 5.6 (otto устанавливает PHP не из стандартного репозитория, а из PPA)
- Composer
Для работы Drupal критически не хватает MySQL.
Dependencies
Простейший способ добавить MySQL: указать зависимость. Создадим Appfile в корне проекта:
application {
name = "drupal8"
type = "php"
dependency {
source = "github.com/hashicorp/otto/examples/mysql"
}
}
Этот конфиг явно указывает тип приложения (php) и добавляет MySQL как зависимость. Несмотря на то, что ссылка в source невалидная, otto ее поймет, есть и другие форматы source.
Есть способ добавить mysql еще проще, но он неправильный, я скажу о нем в недостатках.
Appfile mysql описывает зависимое приложение как Docker-контейнер, путь к образу контейнера и параметры запуска. В результате мы получим запущенный контейнер внутри Vagrant, благодаря Consul он будет доступен по адресу mysql.service.consul (внутри виртуалки) с юзером и паролем root:root. Настроенный по умолчанию Consul существенно облегчает использование Docker, можно не разбираться в тонкостях настройки service discovery, а просто пользоваться.
Зависимостью может быть любое другое приложение, но настоятельно рекомендуется, чтобы оно имело .ottoid файл, который позволит otto понять, что он запускает, даже если приложение будет переименовано.
Зависимости в данный момент не поддерживают версионность (в будущем обещают добавить), это значит, что при каждом ‘otto compile’ у вас есть шанс получить не то, что вы ожидали, поэтому стоит форкнуть зависимости себе или положить на локальной машине.
Делаем otto compile
, otto dev destroy
, otto dev
- получаем машину, готовую к запуску Drupal. Осталось запустить в ней сервер.
otto dev ssh
Заходим в виртуалку по SSH. Выполняем указанную выше команду запуска встроенного в PHP web-сервера, я не вижу ничего плохого в запуске под root на 80 порту на dev:
sudo php -S 0.0.0.0:80
После этого можно заходить открывать в браузере IP адрес, который выдал ‘otto dev’, можно его получить явно, выполнив ‘otto dev address’.
Недостатки
Сырой код
Видно, что код местами довольно прототипный. Например, в Vagrantfile используется bash для разворачивания окружения, а не ansible или что-то подобное.
Я заглянул в код App type php, нашел там определение того, что запускаемое приложение - wordpress (по наличию файла wp-config.php),
единственное отличие от стандартного php приложения - автоматическое добавление mysql в зависимости.
То есть сейчас можно указать в Appfile type = "wordpress"
или сделать touch wp-config.php
, чтобы получить mysql, но, конечно, так делать не стоит.
Окружения не проработаны
Судя по issue tracker проекта, best practices еще не готовы и не совсем понятно, как будут готовиться. Например, в случае PHP, есть Hashicorp, которые не знают особенностей окружения PHP проектов и программисты PHP, которые не знают Go и не могут отправить pull request.
Митчелл Хашимото, автор Otto, предлагает всем заинтересованным писать на Github предложения с улучшениями, ссылки на статьи с настройкой правильного окружения, а Hashicorp позаботится об их интеграции в продукт. Мне кажется, что позже появятся абстракции, которые дадут возможность широкому кругу не-go программистов помогать в развитии продукта.
Dev отличается от prod
До команд otto infra
и otto deploy
я не добрался, но узнал, что сейчас они поддерживают только AWS
и что для php проектов dev-окружение отличается от deploy-окружения, в первом случае предлагается запускать встроенный в PHP сервер,
во втором поднимается apache2 с mod-php.
Dev плохо кастомизируется
Otto в данный момент не дает возможность кастомизировать Vagrantfile dev-окружения через Appfile.
Смотрим .otto/compiled/app/dev/Vagrantfile
, оказывается, в нем прописаны параметры монтирования /vagrant, несовместимые с NFS. Исправляем строку на что-то вроде:
config.vm.synced_folder '/home/popstas/projects/site/drupal8', "/vagrant", type: "nfs"
Следующий otto compile
затрет эти изменения.
Единственный способ сделать правильно: полностью переопределить Vagrantfile, используя application type = “custom”, но в таком случае вся магия автонастройки окружения пропадает.
Выводы
Я сделал для себя вывод, что Otto еще не готов для полноценного использования, на что в общем-то намекает версия продукта 0.1. Тем не менее продукт очень интересный и уже сейчас имеет преимущества по сравнению с Vagrant, а все недостатки объясняются новизной Otto, разработчики о них знают и имеют планы по устранению.
Сейчас непонятно, как создавать свои слои, когда слои появятся в Otto полноценно, для меня это будет достаточной причиной, чтобы перейти на него с Vagrant'а.