Wirtualne maszyny takie jak VirtualBox mają możliwość udostępniania katalogów z komputera gospodarza (host) na maszynę gościa (guest). Umożliwia to w bardzo łatwy sposób dostęp do danych bowiem wystarczy wejść do określonego katalogu i mamy dostęp.
Spróbuję zobrazować zasadę działania udostępniania katalogów pomiędzy maszyną na której jest uruchamiana wirtualna maszyna, a systemem uruchamianym na wirtualnej maszynie.
Na powyższym schemacie mamy host-a, jest to maszyna na której będzie uruchamiana wirtualna maszyna. Kolejny element to wirtualna maszyna, w tym przypadku VirtualBox. Teraz pomiędzy nimi chcielibyśmy wymieniać dane, najwygodniejszą metodą jest właśnie udostępnienie katalogu. Rozwiązanie to jest o tyle wygodne, że katalog udostępniony z poziomu host-a jest synchronizowany w obu kierunkach. Oznacza to tyle, że jeśli dodamy nowy plik z poziomu wirtualnej maszyny pojawi się on na maszynie host-a i odwrotnie.
Bazując na najprostszej konfiguracji, którą omawiałem we wpisie Instalacja i konfiguracja środowiska zobaczymy jak działa udostępnianie katalogów. Dla niewtajemniczonych poniżej konfiguracja z której będę korzystał.
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provider "virtualbox" do |vb|
vb.name = "WebServer"
vb.cpus = 1
vb.memory = 1024
vb.gui = false
end
end
Nigdzie tutaj nie ma żadnej wzmianki o udostępnieniu katalogu. Jednak Vagrant jest na tyle uprzejmy, że sam montuje katalog w którym znajduje się plik Vagrantfile
do katalogu o nazwie vagrant
. Możemy to zobaczyć na etapie uruchamiania/budowania wirtualnej maszyny.
Oczywiście ścieżki będą się różniły od tych zaprezentowanych na powyższym screenie. Montowanie katalogu w którym znajduje się możemy odtworzyć i zmodyfikować dodając do pliku Vagrantfile poniższy wpis.
config.vm.synced_folder ".", "/vagrant"
lub wyłączyć dodając wpis
config.vm.synced_folder ".", "/vagrant", disabled: true
Posiadając wiedzę o domyślnym montowaniu katalogu zawierającego plik Vagrantfile możemy dodać go do naszego projektu. Zaś po uruchomieniu maszyny będzie on dostępny w systemie gościa. Przy odpowiedniej konfiguracji systemu gościa, mamy możliwość bezpośredniej pracy nad projektem, który będzie uruchamiany przez wirtualną maszynę.
Do udostępniania katalogów Vagrant ma dodatkową opcję, którą dodajemy w pliku Vagrantfile. W najprostszej postaci wygląda ona następująco:
config.vm.synced_folder "katalog_zrodlowy", "katalog_docelowy"
Dodajmy montowanie katalogu src
znajdującego się w katalogu projektu do katalogu /var/www/czterytygodnie
config.vm.synced_folder "./src", "/var/www/czterytygodnie"
Przy próbie uruchomienia takiej definicji możemy otrzymać błąd, jeśli katalog src
nie istnieje.
W takim przypadku możemy utworzyć katalog lub dodać opcję create
w konfiguracji.
config.vm.synced_folder "./src", "/var/www/czterytygodnie",
create: true
Po przeładowaniu wirtualnej maszyny poleceniem vagrant reload
powinniśmy otrzymać poniższą listę montowanych katalogów.
Na liście znajdziemy domyślnie montowany katalog oraz naszą nową definicję, która utworzyła katalog src
w katalogu projektu. Mimo tego, że mamy możliwość tworzenia katalogu w momencie montowania, to nie polecał bym używania tej opcji. W większości wypadków chcemy mieć dostęp do katalogu istniejącego już na dysku nie zaś ma on być tworzony.
Poznaliśmy już opcję create
oraz disabled
, jednak nie tylko je zostają nam udostępnione przez Vagranta. Zobaczmy jakie mamy możliwości konfiguracji udostępniania katalogów:
mount
Do tej pory nie określaliśmy typu udostępniania katalogu przez co był stosowany zapewne domyślny typ VirtualBox
.
Domyślny typ stosowany z reguły, gdy nie zdefiniujemy innego typu przy udostępnieniu. Typ ten synchronizuje katalog znajdujący się na maszynie host-a z tym na maszynie gościa w obu kierunkach.
Domyślny sposób synchronizacji oferowany przez VirtualBox-a nie jest idealny, gdyż przy większych katalogach z dużą ilością plików pojawiają się problemy wydajnościowe. Rozwiązaniem tych problemów może być zmiana sposobu synchronizacji na NFS.
Użytkownicy systemu Windows niestety są pozbawieni tej metody synchronizacji. W przypadku jej ustawienia Vagrant zignoruje tę opcję.
Do działania tej metody synchronizacji konieczne jest zainstalowanie nfsd
na maszynie gospodarza (host-a). W przypadku linux-a (Ubuntu) operacja sprowadza się do wydania polecenia:
sudo apt-get install nfs-kernel-server
Zaś w przypadku Mac OS X takowy serwer powinien być już zainstalowany.
W przypadku gdy używasz VirtualBox-a konieczne jest dodatkowe zdefiniowanie sieci prywatnej. Jest to związane z ograniczeniami VirtualBox-a.
Zobaczmy jak zmieni się nasza konfiguracja, jeśli będziemy chcieli zastosować synchronizację typu NFS.
config.vm.synced_folder "./src", "/var/www/czterytygodnie",
type: "nfs"
Zmiana niemal kosmetyczna, jednak przy przeładowaniu konfiguracji poleceniem vagrant reload
otrzymamy prośbę o podanie hasła do naszego komputera.
Jest to związane z faktem, że Vagrant potrzebuje zmodyfikować plik /etc/exports
oraz zrestartować serwer NFS. Operacja ta jest wykonywana za każdym razem, gdy będziemy uruchamiali wirtualną maszynę poleceniem vagrant up
lub vagrant reload
.
Jeśli nie chcesz za każdym razem wpisywać hasła to należy dokonać edycji pliku /etc/sudoers
wprowadzając poniższe modyfikacje:
Mac OS X
mnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD = /sbin/nfsd restart
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /usr/bin/sed -E -e /*/ d -ibak /etc/exports
%admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE
Ubuntu
Cmnd_Alias VAGRANT_EXPORTS_CHOWN = /bin/chown 0\:0 /tmp/*
Cmnd_Alias VAGRANT_EXPORTS_MV = /bin/mv -f /tmp/* /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /etc/init.d/nfs-kernel-server status
Cmnd_Alias VAGRANT_NFSD_START = /etc/init.d/nfs-kernel-server start
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
%sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_CHOWN, VAGRANT_EXPORTS_MV, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY
Fedora
Cmnd_Alias VAGRANT_EXPORTS_CHOWN = /bin/chown 0\:0 /tmp/*
Cmnd_Alias VAGRANT_EXPORTS_MV = /bin/mv -f /tmp/* /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /usr/bin/systemctl status --no-pager nfs-server.service
Cmnd_Alias VAGRANT_NFSD_START = /usr/bin/systemctl start nfs-server.service
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
%vagrant ALL=(root) NOPASSWD: VAGRANT_EXPORTS_CHOWN, VAGRANT_EXPORTS_MV, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY
Kolejna metoda synchronizacji to rsync stosowana głównie w przypadkach braku możliwości użycia innych metod. Synchronizacja w tym przypadku odbywa się tylko w jednym kierunku z maszyny gospodarza (host) na maszynę gościa (guest). Nie jest to także synchronizacja ciągła bowiem automatycznie uruchamia się tylko w momencie uruchamiania maszyny poleceniem vagrant up
lub vagrant reload
.
W systemach unix-owych rsync powinien być zainstalowany i nie powinniśmy mieć problemów z jego użyciem. W systemach z rodziny Windows zapewne będzie konieczność instalacji dodatkowego oprogramowania. Możemy zainstalować środowisko Cygwin lub co jest według mnie lepszym rozwiązaniem instalujemy GIT-a zawierającego środowisko MinGW.
Nasza konfiguracja po zmianie sposobu synchronizacji może wyglądać następująco:
config.vm.synced_folder "./src", "/var/www/czterytygodnie",
type: "rsync"
Podczas uruchamiania wirtualnej maszyny zobaczymy informację o synchronizacji wskazanego katalogu.
Niestety synchronizacja jest jednorazowa co praktycznie uniemożliwia komfortową pracę z tak skonfigurowaną maszyną wirtualną. Jednak możliwe jest wymuszenie synchronizacji danych poprzez wywołanie polecenia vagrant rsync
to dalej nie jest idealne, ale już jest lepiej. Vagrant daje nam jeszcze jedną możliwość jest nią monitorowanie udostępnionego katalogu poprzez vagrant rsync-auto
. Po uruchomieniu polecenia udostępnione katalogi z włączoną opcją rsync-auto będą monitorowane i synchronizowane.
Po wywołaniu polecenia następuje inicjalizacja rsync i pierwsza synchronizacja po której rsync przechodzi w stan obserwacji. Gdy tylko nastąpi jakaś modyfikacja w katalogu, rsync powinien dokonać ponownej synchronizacji i tak aż do momentu wyłączenia mechanizmu.
RSync poza opcją rsync-auto
posiada kilka innych opcji konfiguracji. O wszystkich możecie poczytać w dokumentacji, ja zaś chciałem wam powiedzieć jednak o jednaj bardzo przydatnej rsync__exclude
. Ustawienie to pozwala na eliminację z synchronizacji pewnych katalogów, które nie muszą znajdować się na maszynie docelowej np. katalog git-a, IDE itp.
config.vm.synced_folder "./src", "/var/www/czterytygodnie",
type: "rsync",
rsync__exclude: ".git/"
W tym przypadku został wyeliminowany katalog z repozytorium GIT-a, które będzie zbędne na maszynie docelowej.
Ostatni sposób synchronizacji dedykowany systemowi Windows. Jest on dla Windows-a tym czym jest NFS dla Linux-a / OS X, czyli wydajnym mechanizmem synchronizacji dwukierunkowej. Jednak nawet system Windows musi w tym przypadku spełnić pewne wymagania. Mianowicie wymagany jest PowerShell w wersji 3 lub wyższej oraz wszelkie polecenia będą wykonywane z uprawnieniami administratora.
Typ ten posiada jedynie trzy opcje w konfiguracji:
Opcje te nie są wymagane i jeśli nie zostaną zdefiniowane to przy uruchamianiu zostaniemy poproszeni o ich podanie.
Nasza konfiguracja po zmianie sposobu synchronizacji może wyglądać następująco:
config.vm.synced_folder "./src", "/var/www/czterytygodnie",
type: "smb"
Udostępnianie katalogów wykorzystując Vagrant-a jest bardzo proste i przy niezbyt złożonych operacjach nie powinno powodować żadnych problemów. Jednak jeśli projekt jest duży, zawiera frameworki pokroju Symfony / Laravel / Zend Framework, to praca w takim środowisku może być mało optymalna. Nie zawsze bowiem wystarczy zmiana rodzaju synchronizacji na NFS czy SMB. Czasem trzeba będzie posiłkować się utrzymywaniem części projektu bezpośrednio w maszynie wirtualnej i synchronizacją rsync. Jednak niech was to nie odstrasza od tego rozwiązania bowiem potrafi ono bardzo usprawnić proces budowania środowiska.
Jeśli zaś chcecie wdrażać rozwiązania oparte o Vagrant-a na produkcję, to możecie śmiało cały projekt załadować do wirtualnej maszyny i zapomnieć o udostępnianiu katalogów.