Есть необходимость в команде использовать локально среду, идентичную или приближенную к реальному продукту. Есть опыт использования Vagrant(VirtualBox + Vagrant + Homestead), но еще посоветовали Docker, с ним знакомство только по статьям. Есть ли смысл использовать его вместо Vagrant? Стек технологий такой: Node.js, php, redis, MySql, возможно в ближайшее время добавится обработка очередей задач. За мануалы или статьи буду благодарен.
Ответ Что такое Vagrant и Docker? В общем и целом, под Docker и Vagrant имеют в виду просто средства виртуализации с разной степенью этой виртуализации, Docker - как средство виртуализации на уровне ядра Linux (теперь не только Linux, но не берусь говорить, как обстоит дело на маке и окнах), Vagrant - как полную виртуализацию (затрудняюсь даже корректно охарактеризовать, что это такое, но если в первом случае все происходит внутри ядра Linux, то тут машина виртуализуется полностью, и ей предоставляются виртуальные оперативные память, процессор, и прочие устройства - ВМ думает, что общается с железом, которого на самом деле не существует). На самом деле все несколько иначе: Docker и вправду предоставляет вышеописанную виртуализацию, а Vagrant является просто менеджером средств виртуализации, и вышеприведенный пассаж про "полную виртуализацию" на самом деле относится к VirtualBox, которым управляет Vagrant. У Vagrant есть понятие провайдера (поставщика средстсв виртуализации), и Vagrant умеет управлять как VirtualBox, так и Docker. Зачем это нужно / что это позволяет сделать Вы не указываете в своем вопросе, какие именно цели преследуете, поэтому придется написать, какие вообще проблемы это решает и какие проблемы принято решать тем или иным инструментом. У виртуализации как таковой есть много приятных бонусов, в том числе: Простое и легкое ограничение процессов в ресурсах Изоляция ресурсов Возможность поставки не приложения как такового, а целиком готовое решение, которое нужно не установить и настроить, а просто запустить Косвенным образом - повторяемость процессов Это очень хорошо с точки зрения инфраструктуры, потому что это позволяет перейти от модели сломалось -> починил к модели сломалось -> развернул заново, что гораздо проще автоматизируется и экономит тучу ресурсов. С точки зрения разработки появляются два ключевых плюса, которые могут поменять парадигму разработки: Сборка приложения внутри виртуальной машины переворачивает ситуацию из "работает на моей машине" в "работает в этой виртуальной машине". Инженер, который должен развернуть приложение, получая его в образе виртуальной машины, знает, что для запуска нужно обеспечить только запуск самого образа, тратит процентов на девяносто меньше времени на разруливание ошибок запуска. Использование виртуальных машин позволяет разработчику полностью сымитировать инфраструктуру, в которой проект будет развернут, что опять же позволяет снизить издержки с известной проблемой "на моей машине все работает" и держать несколько версий ПО для разных проектов (если проект А использует PHP 5.3, а проект Б использует PHP 7.0, то вместо жонглирования версиями на рабочей машине разработчик может их держать в отдельных изолированных машинах). В данном случае, конечно, интересует второй момент. И Vagrant + VirtualBox, и Docker позволяют его реализовать, поэтому принципиальной разницы нет, поэтому имеет смысл просто описать концепции обоих инструментов. VirtualBox сам по себе является просто менеджером виртуальных машин, который позволяет запускать их из образов. Здесь все просто: берется образ файлов системы, эмулируется процессор, оперативная память, жесткий диск, виртуальная машина ищет бут-сеткор на виртуальном диске, и машина дальше стартует, как будто она реальна. Vagrant является менеджером средств виртуализации, и на самом деле может запускать не только VirtualBox, но и Docker. Конкретно в данном разрезе Vagrant позволяет автоматизировать создание виртуальной машины (или виртуальных машин) VirtualBox из образа чистой операционной системы, применив т.н. провизию - инициализировав машину с помощью shell-скрипта или менеджера конфигурации. Docker сам по себе предоставляет ровно такой же функционал виртуализации, но очень сильно отличается в плане концепции. Он использует следующий функционал для реализации своих целей: Copy-On-Write систему слоев для реализации файловой системы. Конечная файловая система собирается из нескольких слоев, в результате чего изображения могут делить нижние слои, а для каждой виртуальной машины используется свой собственный слой (верхний в этой композиции), поэтому машины могут использовать общую базу, которую не нужно копировать для старта машины. Систему пространств имен в ядре Linux (опять же затрудняюсь сказать, как это организовано в Mac/Windows) Это позволяет относиться к машинам, как к расходному материалу и пересоздавать их сотни раз в секунду (это очень быстрый процесс по сравнению с поднятием полноценной виртуальной машины). Благодаря этому сформировалась философия Docker, в которой принято правило process-per-container (один процесс на контейенер), и вместо распространения виртуальных машин концепция Docker подразумевает распространение приложений, каждое из которых завернуто в свой образ виртуальной машины для изоляции. С точки зрения виртуализации внутри происходит практически то же самое что и с обычной виртуальной машиной: запускается корневой процесс, который поднимает все остальные. В образах Vagrant-VirtualBox обычно используется привычный init, в Docker-образах - само приложение, таким образом получается, что в виртуальной машине Vagrant-Virtualbox запускается менеджер ОС, следящий за всем происходящем, а в Docker-образе - ничего, кроме конечного приложения. Поэтому при использовании инфраструктуры Docker ключевым отличием станет то, что Vagrant+Virtualbox обычно используется для поднятия одной машины со всем на свете, а в случае с Docker будет поднято по контейнеру на каждый сервис (redis, база данных, сервис очередей, etc.). Таким образом Virtualbox + Vagrant и Docker различаются главным образом концепцией, которая не несет функциональной разницы. Тем не менее, нельзя не отметить, что коммьюнити для каждого инструмента больше развито в том направлении, в котором используется сам инструмент: используя Docker, вы сможете пользоваться общедоступными изолированными машинами с одним процессом в каждой машине и конфигурацией через переменные окружения, используя Vagrant, вы получаете доступ к машинам, конфигурируемым через configuration manager (chef, puppet, saltstack) или и вовсе просто через shell-скрипт и готовым к установке большого количества сервисов на одну машину. Есть ли разница В комментариях к вопросу я занял позицию "криминальной разницы между ними нет", и намерен продолжать ее занимать. Что Vagrant-поверх-VirtualBox, что Docker на самом деле предоставляют один и тот же функционал: Виртуальная машина с одним корневым процессом (строго говоря, так вообще все машины работают) Распространяемые образы этих виртуальных машин Возможность проброса портов виртуальной машины на хост Возможность монтирования директорий хоста внутрь виртуальной машины Возможность организации внутренней сети виртуальных машин Возможность запуска/остановки композиции виртуальных машин Возможность сохранения, выгрузки и загрузки снэпшота виртуальной машины Ограничение виртуальной машины по ресурсам Поэтому на самом деле никакой функциональной разницы, на чем вы будете строить свою инфраструктуру, нет: вы можете ровно так же перевести vagrant на философию "один процесс на машину" или запихнуть все на свете в один docker-container. Однако, у Docker есть ряд преимуществ, не влияющих на сам функционал виртуализации, которые просто делают его использование более удобным и экономным (и которые сформировали его философию): Отсутствие расходов на полноценную виртуализацию COW-система слоев, которая позволяет экономить место при использовании нескольких машин с общим предком Практически мгновенный запуск за счет того, что не нужно инициализировать систему (загружать ядро, монтировать диски и весь тот невероятный парк операций, который происходит при включении машины), и контейнеру остается только запустить бинарник, указанный для него точкой входа. Из-за этого цикл жизни контейнера (на машине разработчика), как правило, гораздо короче, чем у виртуальной машины (и, бонусом, это позволяет обнулить базу данных практически одной командой). Обращение с Docker может быть немного более сложным, но накладные расходы на запуск-остановку композиции сервисов снижаются, а экспорт конечного приложения в виде образа виртуальной машины может быть менее трудоемким, чем в случае с Vagrant + VirtualBox. Тем не менее, сам vagrant я не стал бы списывать со счетов, потому что, пока мир не перешел на контейнерные технологии целиком, он ближе воссоздает целевое окружение (одну машину со всем установленным внутри), да и, к тому же, никто не запрещает использовать его в связке с Docker.