Sable
Y Combinator startup: egy neobank, amely megkönnyíti az Egyesült Államokba költözők életét.
A Sablenél a Revoluthoz hasonló szolgáltatást kínálnak (bankkártya, számlavezetés - a "szokásos" neobank dolgok), valamint - és itt a csavar - ha megoldani nem is, de enyhíteni tudják az Egyesült Államokba költözők egy sok nehézséget okozó problémáját, nevezetesen a credit score hiányát. A Sablenél ugyanis nem szükséges credit score ahhoz, hogy számlát nyithasson az USÁ-ba frissen beköltöző, azonban a számla megnyitását követően már el is kezdheti építeni a credit history-ját.
Bekerültek a Y Combinator 2019-es programjába, a befektetők előtti pitch-hez azonban már szükségük volt egy weboldalra, amiben - nem meglepő módon - pont tudtam segíteni nekik.
Viszonylag szoros volt a határidő (nagyjából 2 hét), így a már bejáratott Craft CMS-t vettem elő újra a kalapból. Szinte teljes mértékben szabad kezet kaptam: volt egy kezdeti drótváz, de rugalmasan kezeltük: ahol kellett, hozzányúltam, ahol nem, ott csak a dizájnt "húztam rá".
Kihívások és megoldások
Minden projektben akadnak olyan feladatok, amikkel addig nem, vagy nem teljesen abban a formában találkoztunk - így volt ez a Sable esetében is. Összességében egy "nyugis" projekt volt (hála annak, hogy tényleg lazán kezelték a helyzetet), azonban három dolgot mindenképpen szeretnék kiemelni.
FAQ
Gyakran ismételt kérdések - ilyennel gyakran találkozunk weboldalakon, azonban a megvalósítások már változó minőségűek szoktak lenni: van, hogy minden kérdés és válasz egy szócikkben szerepel, és változtatás esetén az egészet szerkeszteni kell, de előfordul olyan eset is, amikor a kérdés-válasz párosok ugyan önálló bejegyzésekként vannak kezelve, azonban a hierarchia nem stimmel.
A Sable-nél erre szerencsére egy teljesen natív, Craft-os funkcióval sikerült megoldást találni: a struktúrákkal. A struktúrák (structures) egy olyan szekciótípus, amelynek az elemei hierarchikus viszonyban állhatnak egymással - végső soron semmi különös, csak "be lehet tenni egymás alá az entry-ket".
Ahogy a képen is látszik, nem kellett túlgondolni a funkcionalitást: az első szinten az egyes témakörök (How to apply, Eligibility, etc.), míg ezek gyermekeiként, második szinten a konkrét kérdések, illetve a hozzájuk tartozó válaszok láthatók. A dolgom itt persze egyszerű volt, hiszen 1:n viszony volt a témakörök kérdések között (vagyis egy kérdés csak egy témakörhöz, egy témakörhöz több kérdés tartozhatott), viszont n:m kapcsolat esetén sem lett volna sokkal nehezebb megoldani ezt a feladatot (lásd. a relatedTo paramétert az entry-k lekérdezéséhez).
Referrals
Ahogy több helyen is megszokhattuk már, itt is működik ajánlói rendszer: ha egy ismerősünk "rajtunk keresztül" regisztrál a szolgáltatásba, egy bizonyos mennyiségű ajánlói jutalékot ír jóvá a szolgáltató a mi számlánkon (és jó esetben az ismerősünkén is). A Craft ebben az esetben egy belépőpontként működik: a felhasználók megérkeznek a Referral oldalra, ahol megadhatják a barátjuk nevét és e-mail címét, aki őket ajánlotta. Az űrlap beküldését követően a Craft a Guest Entries pluginon keresztül létrehoz egy bejegyzést, ezzel pedig utána már azt kezdünk, "amit csak akarunk": például elérhetővé tehetjük egy API-n keresztül, amihez csatlakoztatja a megrendelő a saját adatbázisát, és leszívja belőle az adatokat, de akár egy kis modult is írhatunk, ami a beérkezéskor egy API hívást kezdeményez a megrendelő másik rendszere felé, és felíratja oda is az adatokat - a lehetőségek végtelenek. :)
Kubernetes (K8s)
A Google intenzíven támogatja a startupokat, ezért a kezdeti indulást követően elkezdtünk azon dolgozni, hogy a weboldalt az én Docker alapú tárhelyemről a Google felhőjébe mozgassuk - azon belül is a Google Kubernetes Engine-re (GKE).
(A támogatás nyilván nem minden hátsó szándék nélküli, hiszen a vendor lock-in hatékony módja annak, hogy a startupokat magukhoz kössék, és amikorra befutnak, fix ügyfeleik legyenek. )
Űrhajó
Aki még nem találkozott a Google Cloud Console-lal (és dolgozott vele huzamosabb ideig), azt "meglepheti" a sok lehetőség: röviden összefoglalva kicsit olyan, mintha leültetnének egy nagyon high tech űrhajó vezérlőpultja elé, és azt mondanák, hogy akkor most szálljunk fel: "#assetudtamholvagyok". Mostanra javult a helyzet: már ismerem azt a néhány menüpontot, amire szükségem van, de továbbra is "vannak homályos foltok" a felületen (sőt, inkább nem homályos foltok vannak a nagy homályban).
Konténerek
A Kubernetes a következő lépés azután, hogy az alkalmazásunkat konténerizáltuk: a GKE-be az alkalmazásunkat nem a "megszokott", tárhelyre FTP-n keresztül feltöltős módon publikáljuk, hanem azokat önálló image-be csomagoljuk, amiben minden megvan, ami a futásához kellhet. Az ezen képek alapján létrejövő konténerek eldobhatóak, szükség esetén skálázhatóak (több is indítható belőlük párhuzamosan), minderről pedig - ha mindent jól állítottunk be - a Kubernetes gondoskodik. Ahhoz azonban, hogy a weboldalunk megfelelően üzemeljen ebben a környezetben, változtatásokat kell végeznünk rajta. Mikre kell figyelnünk?
- Az alkalmazás konténere eldobható, vagyis abban nem tárolhatunk olyan adatot, amire szükségünk van: tehát ha bármilyen fájlt fel szeretnénk tölteni a rendszerbe, akkor azt egy külső tárolóra kell helyeznünk. Ez lehet például valamilyen object storage, mint amilyen a DigitalOcean Spaces, vagy a Google Cloud Storage (itt nyilván az utóbbit választottuk). Mindkettőhöz létezik Craft plugin, így a dolgunkat ezek nagyban megkönnyítik.
- Bizonyos fájlokhoz nem csak egy konténernek kell hozzáférnie: ha például képeket transzformálunk (azért, hogy úgy töltsenek be a képeink, mint a Medium.com-on - vagy ezen az oldalon :P), akkor a transzformált képeket a webszervernek is el kell érnie annak érdekében, hogy értesüljön arról, ha ezek a transzformációk elkészültek (és ne küldje vissza folyamatosan a PHP-t ezeket legenerálni, mert annak loop és pod eviction lesz a vége).
- Érdemes valamilyen build rendszert kiépíteni (vagy legalább scriptet írni) ahhoz, hogy a deployment (vagyis az alkalmazás "felhőbe juttatása") gördülékenyen menjen: a frissítéseket ugyanis nem az éles környezetben telepítjük majd (jó esetben eddig sem így csináltuk, ugye...), hanem lokálisan, és ezeket a változtatásokat küldjük fel. Eddig megúszhattuk azzal, hogy a fájlokat nem csomagoltuk bele a képfájlba, hanem Docker Compose használatával felcsatoltuk a host-on létező fájlokat, az image-ben pedig csak a rendszerfájlok (vagyis maga a futttatókörnyezet) volt csak: ez a Kubernetes-szel nem fog működni. A publikált képfájlok teljesen önállóak, a weboldal minden részét tartalmazzák, a benne lévő fájlok nem a hoston tárolódnak (nyilván de, de magában a képfájlban).
- A Docker image-inket valamilyen módon publikálnunk kell, és erre nagy eséllyel a publikus Docker Hub nem lesz megfelelő. A Google üzemeltet egy privát Container Registry-t, ide tudjuk feltölteni az elkészült image-inket.
- Az már talán senkit sem lep meg, hogy a levélküldés szintén nem fog működni, így valamilyen külső szolgáltatót érdemes használnunk - de jó esetben ezen már túl vagyunk.
Fontos még megemlíteni, hogy az oldal már üzemelt, így bizonyos változtatásokat ki kellett küldeni az éles verzióra is, hogy felkészüljünk a zökkenőmentes váltásra: amint elkészült a Google Cloud Storage alapú asset-tárolás, az éles oldalra több hullámban küldtem ki frissítést:
- kezdésként hozzáadtam a GCS köteteket, amiket a Project Config-on keresztül automatikusan létrehozott az éles oldalon is a Craft (1. hullám),
- átmásoltam a régi kötetekről az újakra a képeket a Craft Control Paneljével (drag'n'drop, szóval ez volt a legjobb része :P)
- frissítettem a jogosultságokat, hogy az új kötetekhez is hozzáférjenek a szerkesztők (2. hullám),
- majd töröltem a régi köteteket (3. hullám).
A folyamat végére ugyanaz a látvány fogadta a szerkesztőket - és a felhasználókat - annyi különbséggel, hogy a feltöltött képek már nem az én szerveremre kerültek (hiszen ilyenkor az oldal még mindig nálam volt), hanem már a Google egy bucketjébe töltötte át őket a Craft.
Rövidre zárva ezt a kitérőt (a Kubernetesről nagyon sokat lehetne írni): masszív kaland tud lenni az áttérés, azonban vannak tényleg komoly pozitívumai is, így mindenképpen ajánlom kipróbálásra (egy hetet bőven szánni kell rá, még akkor is, ha egy olyan kezesbárány, de már üzemelő alkalmazást viszünk át, mint egy Craft-alapú oldal).
Elrejtve néhány opciót és kiemelve azokat a menüpontokat, amiket tényleg használunk, sokkal áttekinthetőbbé tehető a Google Cloud Console.
Összegzés
A Craft mindig meglep, hogy mennyi potenciál van benne: elképzelni sem merem, hogy mennyi szívás lett volna ugyanezt a manővert egy másik tartalomkezelővel végrehajtani. A Kubernetesre migrálás megizzasztott, hiszen ismeretlen terepen dolgoztam, de örülök és hálás vagyok a lehetőségért.
Ezúton fejezem ki a köszönetemet Matt Gray-nek, aki konzultált velem a Kubernetesre migrálás során. Ő egy kicsit nagyobb fába vágta a fejszéjét: Craft CMS hostingot épít, Kubernetes alapokon: próbáljátok ki, MENŐ!