Ha gyors és fájdalommentes fejlesztői környezet kialakításáról van szó, akkor minduntalan felmerül a kérdés, hogy Vagrant vagy Docker a jó választás. Megpróbáltam összeszedni a pro és kontra érveket.
Ez a cikk nem azokhoz szól, akik egy LAMP környezetben jól érzik magukat, és nincs szükségük semmilyen speciális szolgáltatásra a PHP-n és a MySQL-en kívül. Nekik ott a XAMPP, MAMP, AMPP amik szuperjó toolok és megoldják a legtöbb problémát, gyorsan, könnyedén, szárazon.
Na de mi van akkor, ha kell egy Redis, Memcached, Rabbitmq, Solr, Elasticsearch, vagy esetleg egy ArangoDB. Ilyenkor vagy minden fejlesztő felizzadja a fejlesztői környezetére ezeket, vagy egy központi osztott megoldással kezdünk el bohóckodni.
Ez az, amikor érdemes a fenti két eszköz valamelyikével megoldani a problémát, hisz azokkal a fenti esetek könnyen kezelhetőek.
A másik amit fontosnak tartok közölni, hogy én rajongója vagyok a Dockernek és annak megjelenése óta azt használom. Ezért ez a cikk, bár igyekszem elkerülni, szinte biztosan elfogult lesz a Dockerrel kapcsolatban. Fontos tanulságokat tartalmaz ugyanakkor az a történet, hogy miért váltottam Vagrantról, ezért ezt az elején el kell mesélnem.
Valamikor réges régen, amikor még én is Vagrantot használtam, Juhász Márton kollégámmal raktuk össze a fejlesztői környezeteket a különböző projektekhez. (Akkor még nem tudtuk, mert a fogalom se nagyon létezett, hogy mi voltunk a DevOps.) Számos projekten dolgoztunk ugyanis akkoriban, amikhez a LAMP környezet édeskevés volt és egy Solr telepítése és konfigurálása nem volt mindenki számára magától értetődő, ráadásul a csapatban használt eszközök végtelen változatosságot mutattak. Volt itt minden: Windows, OSX, Linux és azok különböző verziói. Ezért aztán a Vagrant mellett tettük le a voksunkat. Minden jó és szép volt, de jött egy aprópici probléma.
Az egyik kolléga feltett egy új Compass kiegészítőt, ezért amikor néztem át egy projektet nekem nem fordult le. Nem estem kétségbe, hisz a Readme.md tartalmazta mi ilyenkor a teendő. Azonban a futtatott update script kiírta, hogy sajnos a kiegészítő nem kompatibilis azzal a Compass verzióval, ami a gépre van telepítve. És akkor itt álljunk meg egy pillanatra és jegyezzük meg ezt a pontot, mert később vissza fogok rá térni… Most menjünk tovább, mert innen jön a kalandos része a történetnek. Telepítettem hát az új Compass verziót, ami aztán nem indult el, mert a szükséges Ruby csomagok nem voltak ott a gépemen. Persze kiderült, hogy azért nem, mert a nálam lévő Ruby verzió nem kompatibilis ezekkel, úgy hogy a Ruby-t is frissíteni kellett. Na de ezután már futott is a Compass.
A Vagrant viszont nem, mert az a Ruby verzió és az a Vagrant - ami telepítve volt - nem volt kompatibilis. Nosza, frissítsük a Vagrantot. A friss Vagrant azonban nem működött együtt a gépen lévő Virtualbox verzióval, ezért azt is frissítenem kellett, no és az össze image-t is. Gondolhatnánk, hogy na ok, akkor innentől minden menni fog, de sajnos nem. Az új Vagrant verzió új Puppet verziót is hozott magával ugyanis. Ekkor realizáltam, hogy az eddigi munkánk ha nem is száz százalékban, de nagyrészt megy a levesbe és minden projekten újra kell építeni a fejlesztői környezetet. Akkor még nem sejtettem, hogy ez nem a Vagrant vagy a Ruby hibája, tehát nem is rájuk kéne haragudnom. Na de jöjjenek a tanulságok.
Mindent virtualizálj!
Térjünk csak vissza a gyökérokhoz, ami az volt, hogy a Compass nem virtualizálva volt, hanem a host gépre volt telepítve. Ha a Compass-t is virtualizált környezetben futtatjuk, akkor elég lett volna csak a virtualizáción belül, vagyis az adott projektben frissíteni a Ruby verziót, így a Vagrant vígan futott volna tovább a host gépen.
Egységesíts mindent!
Felmerülhet benned a kérdés, hogy annál a kollégánál, aki telepítette a Compass kiegészítőt miért nem okozott ez problémát. A válasz nagyon egyszerű: Mert ő nem a vagrantos környezetet használta. Hasonló anomália egyébként Dockeres környezettel is fordult már elő velem, amikor az egyik külsős kolléga nem a virtualizált Node.js-t használta, hanem a legfrissebb verziót, ami a gépére telepítve volt. Ráadásul, ez egy jelentősebb verzióváltás volt, ugyanis ekkor jelent meg a package.lock fájl használata, előtte csak a package.json volt. Lett is nagy kalamajka, amit viszonylag gyorsan tudtunk orvosolni, hisz csak a frontend buildelésére használt konténerben kellett updatelni a node verziót. Természetesen megkértem a kollégát, hogy legközelebb először a mindenki által használt környezetet frissítse és csak azt használja a fejlesztésre vagy ha nem azt használja, akkor mindenképpen azzal is teszteljen egyet a kód beküldése előtt, mert utána a CI úgy is szólni fog.
Csökkentsd a függőségeket!
Mindig érdemes azon dolgozni egy picit, hogy el tudjuk kerülni a Függőségek Poklát (Dependency Hell). Minden általunk használt eszközt és a függőségeit próbáljuk meg külön csomagolni. Ekkor el tudjuk kerülni, hogy az egyik toolunk függőség változása hatással legyen a másik eszköz működésére.
Melyik a jobb?
Ha a személyes véleményemre vagy kíváncsi, hogy én mit használok, akkor a válaszom: Dockert, mi mást. Mint fentebb látható, érzelmileg talán soha nem fogom túltenni magam a Vagrant által okozott sokkon, bár értelmemmel felfogom, hogy sem a Vagrantnak, sem a Rubynak nem volt igazán köze ahhoz, ami velem történt.
Mondhatnám azt, hogy a Vagrant csak lomha virtuális gépeket tud kezelni, és ezért a megfelelő szeparáció nem, vagy csak komoly költségek árán valósítható meg vele, de ez nem igaz, hisz létezik hozzá Docker Provider, tehát megoldható vele a megfelelő szeparáció.
Azt is mondhatnánk, hogy a Vagrant mindig függ az adott hostra telepített Ruby verziótól, így ha az változik, akkor gondban leszünk. Azonban ez sem igaz, hisz mint mindent, a Vagrantot is tudjuk egy Docker konténeren belül futtatni, ahol az adott verziónak megfelelő függőségek mindig jelen vannak. Bár igazából erre nem igazán van szükség akkor, ha a gazdagépen csak a Vagrantot futtatjuk, és minden más ruby-s szkript egy-egy nekik megfelelő virtualizált környezetben fog futni, lásd fenti szabályok.
Összefoglalás
Úgy gondolom mindegy, hogy melyik eszközt használjuk a fejlesztői környezetek kialakítására, döntsünk nyugodtan érzelmi alapon. Amennyiben a megfelelő szeparációt szeretnénk elérni, akkor mindenképpen fogjuk a Dockert is használni, ebben biztos vagyok. Azt javaslom, koncentráljunk inkább a módszertanra az eszközök helyett és tartsuk be a következő három szabályt:
Amennyiben érdekel, hogy én hogyan alkalmazom ezeket, akkor gyere el a Konténerizált fejlesztői környezet kialakítása című workshopomra, mert ott élőben vagy online megnézheted, kipróbálhatod ezeket. Ha érdekel picit is a Docker, mindenképpen gyere el.