Vagrant czyli jak łatwo stworzyć przenośne środowisko dla programisty

Zaczynamy nowy projekt. Przyda się jakiś serwer. Trzeba by go jakoś fajnie skonfigurować. Baza danych? Również jest potrzebna. Może jakieś dodatkowe narzędzia z którymi będzie współpracować nasza aplikacja? Może trzeba stworzyć jakieś skrypy instalacyjne? Jak je przetestować? Odpalać lokalnie? Dużo roboty. To może jakaś maszyna wirtualna? Będzie szybciej, ale tyko trochę. Inny przykład – bug na środowisku produkcyjnym. Ale u mnie działa. Musi być jakaś różnica między konfiguracją tu i na produkcji. Czy wszystkie wersje tooli, serwerów i zdeployowanych aplikacji są takie same? Koszmar. Jak widać problemów związanych z utrzymaniem środowiska programistycznego jest sporo. Czy istnieje jakieś narzędzie, które może nam pomóc? Tak, nazywa się Vagrant.

Vagrant to the rescue

Czym jest Vagrant? Jest to maksymalnie proste w użyciu narzędzie służące do konfiguracji i zarządzania środowiskiem programistycznym w postaci maszyn wirtualnych. Pomysł polega na tym, że na komputerze, którego używamy do developmentu trzymamy tylko narzędzia typowo programistyczne (np. nasze IDE), a całe środowisko “uruchomieniowe” dla naszej aplikacji przygotuje nam (w postaci maszyny wirtualnej) Vagrant.

Co potrafi Vagrant? Jedną komendą stworzymy wirtualkę, która po uruchomieniu będzie już wstępnie skonfigurowana. Ogólnie rzecz biorąc będzie miała w pełni funkcjonalny system operacyjny (domyślnie Ubuntu 12.04 LTE, ale bardzo łatwo wybrać inny system). Posiada również odpowiednio skonfigurowane klucze, dzięki czemu połączymy się z nią przez ssh bez konieczności wprowadzania hasła. Maszyna domyślnie zawiera również skonfigurowany współdzielony folder. Jedną komendą możemy ją wyłączyć lub w ogóle usunąć.

Uzywanie Vagranta jest bardzo proste – a dokumentacja jest dobrze napisana. Wszystko sprowadza się do dodawania odpowiednich wpisów do pliku konfiguracyjnego (Vagrantfile). W dalszej części przedstawię kilka najprostszych konfiguracji, które pomogą zrozumieć filozofię stojącą za Vagrantem.

Instalacja

Instalacja Vagranta jest bardzo prosta i dobrze opisana w dokumentacji. Przypomnę więc więc tylko, że trzeba jeszcze pobrać i zainstalować wcześniej VirtualBox. Dodatkowo jeżeli używamy Windowsa, to przyda się nam możliwość łączenia się przez ssh. Można do tego użyć dodatkowych narzędzi takich jak np putty – ja, jako, że używam konsoli Gita dla Windows – posiadam zainstalowane MinGW – i z poziomu MinGW korzystam z Vagranta.

Przykłady użycia

Poniżej kilka prostych przykładów użycia Vagranta:

  • Stworzenie podstawowej maszyny i połączenie się z nią przez ssh
  • Automatyczna instalacja dodatkowego oprogramowania podczas tworzenia maszyny
  • Proste przekierowywanie portów
  • Stworzenie kilku maszyn i połączenie ich w sieć

Najprostsza maszyna

Aby stworzyć projekt wydajemy komendę:

vagrant init hashicorp/precise64

Komenda init tworzy nowy plik konfiguracyjny, natomiast parametr hashicorp/precise64 to tzw. “box”, który ma zostać wykorzystany do późniejszego stworzenia maszyny wirtualnej. Box jest to specjalnie przygotowany obraz, który w tym wypadku zawiera system operacyjny Ubuntu 12.04 LTE w wersji 64 bitowej. Jeżeli Vagrant nie odnajdzie lokalnie podanego przez nas boksa, to połączy się ze swoimi serwerami i spróbuje go odnaleźć i ściągnąć. Na stronie https://vagrantcloud.com/search możemy wyszukiwać potrzebne nam boksy – możemy szukać zarówno po nazwie systemu operacyjnego, jak i np. nazwie narzędzi, które byśmy chcieli, żeby były domyślnie zainstalowane (np. chcemy mieć maszynę na której jest już zainstalowany Puppet).

Plik Vagrantfile będący całą konfiguracją naszego projektu będzie wyglądać tak. Jak widać ma on w sobie całe mnóstwo komentarzy, które same w sobie zawierają mnóstwo wskazówek do wykorzystania.

Aby uruchomić maszynę wydajemy komendę:

vagrant up

Wyłączyć maszynę możemy komendą:

vagrant halt

Natomiast usunąć ją za pomocą:

vagrant destroy

Najważniejsze jest jednak to, że możemy połączyć się z nią przez ssh za pomocą komendy:

vagrant ssh

Jak widać nie musieliśmy podawać hasła – gdyż Vagrant zadbał o konfigurację kluczy dla połączenia ssh. Pod ścieżką /vagrant mamy natomiast współdzielony katalog, którym domyślnie jest folder zawierający Vagrantfile (można to skonfigurować inaczej).

Automatyczna konfiguracja maszyny podczas jej tworzenia

Najczęściej wykonywaną czynnością podczas pracy z Vagrantem jest tzw. provisioning – czyli zapewnienie automatycznej konfiguracji maszyny podczas jej tworzenia. Przykładowo chcielibyśmy żeby Vagrant zainstalował nam Git’a – więc definiujemy to w konfiguracji. Provisioning wykona się automatycznie po stworzeniu maszyny.

Vagrant daje wiele możliwości na automatyczny provisioning. Najłatwiejszym z nich jest wykorzystanie skryptu sh. Aby wskazać plik ze skryptem dopisujemy linijkę do konfiguracji:

config.vm.provision "shell", path: "./provision.sh"

Cały przykład do obejrzenia tu.

Ale to nie wszystko! Pisanie skryptów sh może być całkiem pracochłonne i niezbyt przenośne pomiędzy środowiskami (w sensie, jeżeli chcielibyśmy wmienić boksa na innego). Na szczęście Vagrant oferuje wsparcie dla innych narzędzi do konfiguracji środowisk, takich jak: Chef, Puppet, Ansible, Docker i inne.

Proste przekierowanie portów

Załóżmy, że chcemy mieć na maszynie wirtualnej serwer apache aby móc sprawdzać jak wyglądają strony html które tworzymy. Dzięki Vagrantowi możemy przekierować port http apache’a z maszyny wirtualnej na naszą maszynę developerską. Dzięki temu dokumenty serwowane przez apache są dostępne z poziomu naszej lokalnej przeglądarki.

Aby włączyć forwardowanie portów należy dodać następującą linijkę do konfiguracji (Cały przykład do zobaczenia tutaj):

config.vm.network :forwarded_port, host: 8080, guest: 80

Gdzie host jest portem naszego komputera, a guest – maszyny wirtualnej.

Kilka maszyn połączonych siecią

Czasem potrzebujemy kilku maszyn wirtualnych w tym samym momencie (np. chcielibyśmy przetestować komunikację klienta z serwerem). Poniżej fragment konfiguracji (cały przykład tutaj) trzech maszyn z przypisanymi statycznymi adresami IP – maszyny “widzą się” nawazajem w sieci:

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

	config.vm.box = "hashicorp/precise64"

	config.vm.define "first_machine" do |first_machine|
		first_machine.vm.network "private_network", ip: "192.168.0.10"
	end

	config.vm.define "second_machine" do |second_machine|
		second_machine.vm.network "private_network", ip: "192.168.0.11"
	end

	config.vm.define "third_machine" do |third_machine|
		third_machine.vm.network "private_network", ip: "192.168.0.12"
	end
end

Część konfiguracji może być wspólna dla wszystkich maszyn (w powyższym przykładzie jest to nazwa boksa) a każda z maszyn posiada swoją sekcję konfiguracyjną niezależną od pozostałych.

Wydając standardowe komendy Vagranta typu init, up, destroy, etc. działamy na wszystkich maszynach zdefiniowanych w konfiguracji. Jeżeli jednak chcielibyśmy wykonać komendę na pojedyńczej maszynie, musimy podać ją jako parametr w komendzie. Przykładowo jeżeli chcemy uruchomić jedynie maszynę first_machine, używamy następującej komendy:

vagrant up first_machine

Zaawansowane funkcje Vagranta

Vagrant umożliwia też kilka innych, bardziej zaawansowanych operacji.

Możemy np, “przepakować” boksa. Jest to operacja w której przygotowujemy nowego boksa na podstawie już istniejącego. Robi się tak wtedy, kiedy provisioning jest kosztowny czasowo. Wystarczy wtedy stworzyć maszynę z jakimś podstawowym boksem a następnie doinstalować wszystkie niezbędne narzędzia. Taką maszynę możemy “spakować” do nowego boksa i dalej używać tak samo jak każdego innego boksa – dzięki czemu czas tworzenia maszyny jest dużo krótszy.

Możemy również stworzyć boksa absolutnie od zera (jest to tzw. base box). Vagrant wymaga od nas, żeby na maszynie wirtualnej znajdowało się kilka narzędzi (manager pakietów, ssh wraz z odpowiednią konfiguracją a także guest addtions virtualboksa), poza tym sugeruje w jaki sposób skonfigurować fizyczne parametry maszyny wirtualnej (dysk, ram, etc.) – poza tym mamy praktycznie pełną dowolność dotyczącą systemu operacyjnego i jego konfiguracji.

Ciekawą rzeczą jest Vagrant cloud – serwis dzięki któremu możemy dzielić się z innymi naszymi boksami, ale nie tylko. Możemy również udostępniać nasze, skonfigurowane środowisko na zewnątrz – dzięki czemu inni mogą np. podłączyć się do naszej wirtualnej maszyny.

Podsumowanie

Vagrant jest bardzo prostym narzędziem oferującym naprawdę szerokie możliwości konfiguracji maszyn wirtualnych. Dzięki temu tworzenie środowisk developerskich jest bardzo proste – co bardzo ułatwia pracę (i nawet już nie chodzi o jakieś duże projekty, że tak powiem “zawodowe”, ale nawet zwykłe hackowanie z użyciem nowopoznanych narzędzi/frameworków).

Powyższy wpis zawiera chyba wszystkie najbardziej podstawowe rzeczy, które moglibyśmy chcieć umieć robić z Vagrantem. To plus bardzo dobrze napisana dokumentacja pozwala na natychmiastowe rozpoczęcie korzystania z tego narzędzia, do czego serdecznie zachęcam.

Stworzyłem na GitHubie prosty projekt z przykładami opisanymi w tym wpisie. Być może w przyszłości będę tam wrzucał bardziej skomplikowane przykłady konfiguracji, bądź też przykłady pokazujące jak rozwiązywać różne problemy związane z Vagrantem.

2 Replies to “Vagrant czyli jak łatwo stworzyć przenośne środowisko dla programisty”

  1. Jakoś nie mogę znaleźć sposobu aby maszynę udostępnić w sieci, tzn żeby np ssh było dostępne nie tylko z mojego hosta ale innych hostów w sieci publicznej. Czy da się to zrobić ?

Comments are closed.