{"id":32526,"date":"2019-10-31T21:47:32","date_gmt":"2019-10-31T18:47:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\/"},"modified":"2019-10-31T21:47:32","modified_gmt":"2019-10-31T18:47:32","slug":"protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","title":{"rendered":"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Ju ofroj t\u00eb njihet me p\u00ebrmbledhjen e raportit t\u00eb Aleksand\u00ebr Sigachev nga Inventos \"Procesi i zhvillimit dhe testimit me Docker + Gitlab CI\"<\/strong><\/p>\n<p><\/p>\n<p>Ata q\u00eb sapo kan\u00eb filluar t\u00eb zbatojn\u00eb procesin e zhvillimit dhe testimit mbi baz\u00ebn e Docker + Gitlab CI shpesh b\u00ebjn\u00eb pyetje themelore. Nga t\u00eb fillosh? Si t\u00eb organizosh? Si t\u00eb testohet?<\/p>\n<p><\/p>\n<p>Ky raport \u00ebsht\u00eb i mir\u00eb sepse tregon n\u00eb m\u00ebnyr\u00eb t\u00eb strukturuar procesin e zhvillimit dhe testimit duke p\u00ebrdorur Docker dhe Gitlab CI. Raporti vet\u00eb \u00ebsht\u00eb nga viti 2017. Mendoj se nga ky raport mund t\u00eb nxirren baza, metodologji, ide dhe p\u00ebrvoj\u00eb p\u00ebrdorimi. <\/p>\n<p>\n<center><div class=\"youtube-placeholder\" data-id=\"lJsqRwULRVA\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/lJsqRwULRVA\/hqdefault.jpg\" alt=\"Luaj videon\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<p>Kush \u00ebsht\u00eb interesuar, lutem shihni m\u00eb posht\u00eb. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p>M\u00eb quaj Aleksand\u00ebr Sigachev. Punoj n\u00eb kompanin\u00eb Inventos. Do flas p\u00ebr p\u00ebrvoj\u00ebn time t\u00eb p\u00ebrdorimit t\u00eb Docker dhe se si e implementojm\u00eb ngadal\u00eb n\u00eb projektet e kompanis\u00eb.<\/p>\n<p><\/p>\n<p>Tema e raportit: Procesi i zhvillimit duke p\u00ebrdorur Docker dhe Gitlab CI. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e30c4757e4bda1bcc3e20b16e8e2709e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb raporti im i dyt\u00eb p\u00ebr Docker. N\u00eb momentin e raportit t\u00eb par\u00eb, ne e p\u00ebrdornim Docker vet\u00ebm n\u00eb Zhvillim n\u00eb makinat e zhvilluesve. Numri i punonj\u00ebsve q\u00eb e p\u00ebrdornin Docker ishte rreth 2-3 persona. Gradualisht u grumbullua p\u00ebrvoj\u00eb dhe ne shkuam pak m\u00eb p\u00ebrpara. Linku n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/gled\/docker-development-70411088\">Raporti i par\u00eb<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>\u00c7far\u00eb do t\u00eb p\u00ebrmbaj\u00eb ky raport? Ne do t\u00eb ndajm\u00eb p\u00ebrvoj\u00ebn ton\u00eb mbi pengesat q\u00eb has\u00ebm dhe si i zgjodh\u00ebm ato. Nuk ishte gjithmon\u00eb e k\u00ebndshme, por na ndihmoi t\u00eb shkojm\u00eb p\u00ebrpara.<\/p>\n<p><\/p>\n<p>Sllogani yn\u00eb: dockerizo gjith\u00e7ka q\u00eb arrin n\u00eb duar tona.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25ae4f97f1c502384abfe697bac502b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cilat probleme adresojm\u00eb?<\/p>\n<p><\/p>\n<p>Kur ka disa ekipe n\u00eb kompani, programuesi b\u00ebhet nj\u00eb burim i ndar\u00eb. Ka etapa kur programuesi merret nga nj\u00eb projekt dhe i jepet p\u00ebr nj\u00eb koh\u00eb n\u00eb nj\u00eb projekt tjet\u00ebr.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb kuptuar shpejt, programuesi duhet t\u00eb shkarkoj\u00eb kodin burimor t\u00eb projektit dhe ta nis\u00eb sa m\u00eb shpejt ambientin q\u00eb do t\u2019i lejoj\u00eb t\u00eb avancoj\u00eb n\u00eb zgjidhjen e detyrave t\u00eb k\u00ebtij projekti.<\/p>\n<p><\/p>\n<p>N\u00eb p\u00ebrgjith\u00ebsi, kur starton nga zero, dokumentacioni n\u00eb projekt \u00ebsht\u00eb i kufizuar. Informacioni mbi konfigurimin \u00ebsht\u00eb i disponuesh\u00ebm vet\u00ebm te t\u00eb vjetrit. Punonj\u00ebsit zakonisht rregullojn\u00eb vendin e tyre t\u00eb pun\u00ebs brenda nj\u00eb ose dy dit\u00ebsh. P\u00ebr ta p\u00ebrshpejtuar k\u00ebt\u00eb, ne p\u00ebrdor\u00ebm Docker.<\/p>\n<p><\/p>\n<p>Arsyeja tjet\u00ebr \u00ebsht\u00eb standardizimi i konfigurimeve n\u00eb Development. Sipas p\u00ebrvoj\u00ebs time, zhvilluesit gjithmon\u00eb tregojn\u00eb iniciativ\u00eb. N\u00eb \u00e7do rast t\u00eb pest\u00eb, nj\u00eb domain i personalizuar, si p.sh. vasya.dev, p\u00ebrfshihet. I uluri af\u00ebr \u00ebsht\u00eb fqinji Petja, q\u00eb ka domenin petya.dev. Ata po zhvillojn\u00eb nj\u00eb faqe ose ndonj\u00eb komponent t\u00eb sistemit duke p\u00ebrdorur k\u00ebt\u00eb em\u00ebr domeni.<\/p>\n<p><\/p>\n<p>Kur sistemi zgjeron dhe k\u00ebto emra domeni fillojn\u00eb t\u00eb p\u00ebrfshihen n\u00eb konfigurime, at\u00ebher\u00eb ndodhin konflikte t\u00eb ambientit Development dhe rruga e faqes rikriptohet.<\/p>\n<p><\/p>\n<p>E nj\u00ebjta gj\u00eb ndodh edhe me konfigurimet e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave. Disa nuk shqet\u00ebsohen p\u00ebr sigurin\u00eb dhe punojn\u00eb me nj\u00eb fjal\u00ebkalim t\u00eb zbraz\u00ebt root. Disa t\u00eb tjer\u00eb, gjat\u00eb instalimit, MySQL ka k\u00ebrkuar nj\u00eb fjal\u00ebkalim dhe fjal\u00ebkalimi ka qen\u00eb nj\u00eb 123. Ndodhin shpesh raste kur konfigurimi i baz\u00ebs s\u00eb t\u00eb dh\u00ebnave ndryshonte vazhdimisht n\u00eb var\u00ebsi t\u00eb commit-it t\u00eb zhvilluesit. Disa e korrigjuan, disa nuk e korrigjuan konfigurimin. Kishin pasur shkollime kur e nxirrnim ndonj\u00eb konfigurim provues n\u00eb <code>.gitignore<\/code> \u00e7do zhvillues duhet t\u00eb vendos\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Kjo e komplikon procesin e fillimit. P\u00ebrve\u00e7 t\u00eb gjitha, duhet t\u00eb mbani mend p\u00ebr baz\u00ebn e t\u00eb dh\u00ebnave. Duhet t\u00eb inicializoni baz\u00ebn e t\u00eb dh\u00ebnave, t\u00eb shkruani fjal\u00ebkalimin, t\u00eb krijoni p\u00ebrdoruesin, t\u00eb krijoni tabelat dhe k\u00ebshtu me radh\u00eb.<\/p>\n<p><\/p>\n<p>Nj\u00eb tjet\u00ebr problem \u00ebsht\u00eb versionet e ndryshme t\u00eb librarive. Shpesh ndodhi q\u00eb zhvilluesi punon me projekte t\u00eb ndryshme. Ka projekte Legacy, q\u00eb filluan pes\u00eb vjet m\u00eb par\u00eb (nga viti 2017 \u2014 sh\u00ebnim redaktor). N\u00eb momentin e fillimit, filluam me MySQL 5.5. Ka dhe projekte moderne ku p\u00ebrpiqemi t\u00eb implementojm\u00eb versionet m\u00eb t\u00eb reja t\u00eb MySQL, p\u00ebr shembull 5.7 ose m\u00eb t\u00eb reja (n\u00eb vitin 2017 \u2014 sh\u00ebnim redaktor).<\/p>\n<p><\/p>\n<p>Ajo q\u00eb punon me MySQL e di se k\u00ebto biblioteka sjellin var\u00ebsi. \u00cbsht\u00eb mjaft problematike t\u00eb nisim 2 baza nj\u00ebkoh\u00ebsisht. S\u00eb paku, \u00ebsht\u00eb problematike t\u00eb lidhen klient\u00ebt e vjet\u00ebr me baz\u00ebn e t\u00eb dh\u00ebnave t\u00eb re. Kjo shp\u00ebrndan nj\u00ebkoh\u00ebsisht disa probleme.<\/p>\n<p><\/p>\n<p>Problemi i ardhsh\u00ebm \u00ebsht\u00eb kur zhvilluesi punon n\u00eb makin\u00ebn lokale, ai p\u00ebrdor burime lokale, skedar\u00eb lokal\u00eb, RAM lokal. T\u00eb gjitha nd\u00ebrveprimet n\u00eb momentin e zhvillimit t\u00eb zgjidhjeve b\u00ebhen brenda kuptimit se kjo funksionon n\u00eb nj\u00eb makin\u00eb. Nj\u00eb shembull mund t\u00eb jet\u00eb kur kemi 3 server\u00eb backend n\u00eb Production, dhe zhvilluesi ruan skedar\u00ebt n\u00eb katalogun rr\u00ebnj\u00ebsor dhe nga aty nginx merr skedar\u00ebt p\u00ebr t'u p\u00ebrgjigjur k\u00ebrkesave. Kur ky kod arrin n\u00eb Production, rezulton se skedari \u00ebsht\u00eb prezent n\u00eb nj\u00ebrin nga 3 server\u00ebt.<\/p>\n<p><\/p>\n<p>Aktualisht, po zhvillohet drejtimi i mikrosh\u00ebrbimeve. Kur i ndajm\u00eb aplikacionet tona t\u00eb m\u00ebdha n\u00eb disa komponent\u00eb t\u00eb vegj\u00ebl q\u00eb nd\u00ebrveprojn\u00eb me nj\u00ebri-tjetrin. Kjo lejon q\u00eb p\u00ebr \u00e7do grup specifik detyrash t\u00eb zgjidhen teknologjit\u00eb e duhura. Gjithashtu, kjo ndihmon n\u00eb ndarjen e pun\u00ebs dhe zon\u00ebs s\u00eb p\u00ebrgjegj\u00ebsis\u00eb midis zhvilluesve.<\/p>\n<p><\/p>\n<p>Zhvilluesi Frondend, duke zhvilluar me JS, praktikisht nuk ndikon n\u00eb Backend. Zhvilluesi Backend, nga ana tjet\u00ebr, zhvillon, n\u00eb rastin ton\u00eb, me Ruby on Rails dhe nuk e pengon Frondend-in. Nd\u00ebrveprimi b\u00ebhet n\u00ebp\u00ebrmjet API-s\u00eb.<\/p>\n<p><\/p>\n<p>Si bonus, me ndihm\u00ebn e Docker arrit\u00ebm t\u00eb shfryt\u00ebzojm\u00eb burimet n\u00eb Staging. \u00c7do projekt, p\u00ebr shkak t\u00eb specifik\u00ebs s\u00eb tij, k\u00ebrkonte konfigurime t\u00eb caktuara. Fizikisht, duhej t\u00eb ndaheshim ose me nga nj\u00eb server virtual dhe t'i konfiguroni ato ve\u00e7 e ve\u00e7, ose t\u00eb ndanim ndonj\u00eb ambient variabli dhe projektet mund t\u00eb ndikonin nj\u00ebra-tjetr\u00ebn n\u00eb var\u00ebsi t\u00eb versioneve t\u00eb bibliotekave.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/fa5c99f90faef84a356d4791fd915830.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mjetet. \u00c7far\u00eb p\u00ebrdorim? <\/p>\n<p><\/p>\n<ul>\n<li>Pik\u00ebrisht vet\u00eb Docker. N\u00eb Dockerfile p\u00ebrshkruhen var\u00ebsit\u00eb e nj\u00eb aplikacioni. <\/li>\n<li>Docker-compose \u00ebsht\u00eb lidhja q\u00eb bashkon disa nga aplikacionet tona Docker.<\/li>\n<li>P\u00ebrdorim GitLab p\u00ebr ruajtjen e kodit burimor.<\/li>\n<li>P\u00ebrdorim GitLab-CI p\u00ebr integrimin sistemor.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/b6041827a6ba928e0d33add6b79c581c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Raporti p\u00ebrb\u00ebhet nga dy pjes\u00eb.<\/p>\n<p><\/p>\n<p>Pjesa e par\u00eb do t'i tregoj\u00eb sesi e kemi nisur Docker n\u00eb makinat e zhvilluesve.<\/p>\n<p><\/p>\n<p>Pjesa e dyt\u00eb do t\u00eb tregoj\u00eb sesi bashk\u00ebpunojm\u00eb me GitLab, si i aktivizojm\u00eb testet dhe si i deploy-ojm\u00eb n\u00eb Staging.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/45746d3323d35e0d18f066c8bfcb2214.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker \u00ebsht\u00eb nj\u00eb teknologji q\u00eb lejon (duke p\u00ebrdorur nj\u00eb qasje deklarative) p\u00ebrshkrimin e komponent\u00ebve t\u00eb nevojsh\u00ebm. Ky \u00ebsht\u00eb nj\u00eb shembull i Dockerfile. K\u00ebtu shpallim se trash\u00ebgojm\u00eb nga imazhi zyrtar Docker i Ruby:2.3.0. Ai p\u00ebrmban Ruby versioni 2.3. Ne instalojm\u00eb bibliotekat e nevojshme p\u00ebr nd\u00ebrtim dhe NodeJS. P\u00ebrcaktojm\u00eb se po krijojm\u00eb nj\u00eb katalog <code>\/app<\/code>. Caktojm\u00eb katalogun app si direktorin\u00eb e pun\u00ebs. N\u00eb k\u00ebt\u00eb katalog vendosim Gemfile minimale dhe Gemfile.lock t\u00eb nevojshme. Pastaj kryejm\u00eb nd\u00ebrtimin e projekteve q\u00eb instalojn\u00eb k\u00ebt\u00eb imazh var\u00ebsit\u00eb. Tregon se kontejneri do t\u00eb jet\u00eb gati t\u00eb d\u00ebgjoj\u00eb n\u00eb portin e jasht\u00ebm 3000. Komanda e fundit \u00ebsht\u00eb komanda q\u00eb drejtp\u00ebrdrejt nis aplikacionin ton\u00eb. N\u00ebse ekzekutojm\u00eb komandan\u00eb p\u00ebr nisjen e projektit, aplikacioni do t\u00eb p\u00ebrpiqet t\u00eb ekzekutoj\u00eb dhe do t\u00eb nis\u00eb komand\u00ebn e caktuar.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ba503c305ae90f49b39f4ae2cbda1668.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb shembull minimal i nj\u00eb skedari docker-compose. K\u00ebtu tregojm\u00eb se si ndodhet lidhja mes dy kontejner\u00ebve, konkretisht sh\u00ebrbimi i baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe sh\u00ebrbimi web. Aplikacionet tona web, n\u00eb shumic\u00ebn e rasteve, k\u00ebrkojn\u00eb nj\u00eb baz\u00eb t\u00eb dh\u00ebnash p\u00ebr t\u00eb ruajtur t\u00eb dh\u00ebnat si backend. Duke marr\u00eb parasysh se po p\u00ebrdorim MySQL, shembulli i MySQL \u00ebsht\u00eb i till\u00eb \u2014 por asgj\u00eb nuk na pengon t\u00eb p\u00ebrdorim nj\u00eb baz\u00eb t\u00eb dh\u00ebnash tjet\u00ebr (PostgreSQL, Redis).<\/p>\n<p><\/p>\n<p>Ne marrim imazhin e MySQL 5.7.14 nga burimi zyrtar n\u00eb Docker Hub pa modifikime. Imazhi q\u00eb p\u00ebrfaq\u00ebson aplikacionin ton\u00eb web e nd\u00ebrtuam nga direktorja aktuale. N\u00eb momentin e par\u00eb t\u00eb nisjes, ai nd\u00ebrtuan imazhin p\u00ebr ne. Pas k\u00ebsaj, ekzekuton komand\u00ebn q\u00eb kemi k\u00ebtu. N\u00ebse kthehemi mbrapa, do t\u00eb shohim se ishte caktuar nj\u00eb komand\u00eb fillestare p\u00ebrmes Puma. Puma \u00ebsht\u00eb nj\u00eb sh\u00ebrbim i shkruar n\u00eb Ruby. N\u00eb rastin e dyt\u00eb, ne e ridefinojm\u00eb. Kjo komand\u00eb mund t\u00eb jet\u00eb arbitrare, n\u00eb var\u00ebsi t\u00eb nevojave ose detyrave tona.<\/p>\n<p><\/p>\n<p>Gjithashtu, ne p\u00ebrcaktojm\u00eb se duhet t\u00eb kalojm\u00eb portin n\u00eb makin\u00ebn ton\u00eb zhvilluesi nga 3000 n\u00eb portin 3000 t\u00eb kontejnerit. Kjo zbatohet automatikisht p\u00ebrmes iptables dhe mekanizmit t\u00eb vet\u00eb, q\u00eb \u00ebsht\u00eb inkorporuar direkt n\u00eb Docker. <\/p>\n<p><\/p>\n<p>Zhvilluesi mund t\u00eb drejtohet si m\u00eb par\u00eb n\u00eb \u00e7do adres\u00eb IP t\u00eb disponueshme, p\u00ebr shembull, 127.0.0.1, IP lokal ose IP t\u00eb jasht\u00ebm t\u00eb makin\u00ebs.<\/p>\n<p><\/p>\n<p>Rreshti i fundit thot\u00eb se kontejneri web varet nga kontejneri db. Kur aktivizojm\u00eb lancimin e kontejnerit web, docker-compose do t\u00eb aktivizoj\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Pas fillimit t\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave (realmente \u2014 pas aktivizimit t\u00eb kontejnerit! Gatishm\u00ebria e BDs nuk \u00ebsht\u00eb e garantuar) do t\u00eb aktivizohet aplikacioni yn\u00eb, backend-i yn\u00eb.<\/p>\n<p><\/p>\n<p>Kjo shmang gabimet kur baza e t\u00eb dh\u00ebnave nuk \u00ebsht\u00eb ngritur dhe ndihmon n\u00eb ruajtjen e burimeve kur ndalim kontejnerin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, duke liruar k\u00ebshtu burimet p\u00ebr projekte t\u00eb tjera. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4acbcf5de89b98db055e8abc419202de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c7far\u00eb na ofron p\u00ebrdorimi i dockerizimit t\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave n\u00eb projekt. Ne dokumentojm\u00eb versionin e MySQL p\u00ebr t\u00eb gjith\u00eb zhvilluesit. Kjo ndihmon n\u00eb shmangien e disa gabimeve q\u00eb mund t\u00eb ndodhin kur ndodhin diferenca versionesh, kur ndryshon sintaksa, konfigurimi, cil\u00ebsimet e p\u00ebrpamta. Kjo lejon t\u00eb shkruhen hostname t\u00eb zakonsh\u00ebm p\u00ebr baz\u00ebn e t\u00eb dh\u00ebnave, emrin e p\u00ebrdoruesit, fjal\u00ebkalimin. Shk\u00ebputemi nga ai kaos emrash dhe konflikteve n\u00eb skedar\u00ebt config q\u00eb ishin m\u00eb par\u00eb. <\/p>\n<p><\/p>\n<p>Ne kemi mund\u00ebsin\u00eb t\u00eb p\u00ebrdorim nj\u00eb konfigurim m\u00eb optimal p\u00ebr mjedisin e Zhvillimit, i cili do t\u00eb ndryshoj\u00eb nga ai default. MySQL, n\u00eb m\u00ebnyr\u00eb t\u00eb parazgjedhur, \u00ebsht\u00eb i optimizuar p\u00ebr makina t\u00eb dob\u00ebta dhe performanca e tij \u00ebsht\u00eb shum\u00eb e ul\u00ebt nga kutia.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/417d77a06b18e2df9b71440c0f2a1653.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker lejon p\u00ebrdorimin e interpreter\u00ebve Python, Ruby, NodeJS, PHP n\u00eb versionin e nevojsh\u00ebm. K\u00ebshtu shmangim nevoj\u00ebn p\u00ebr t\u00eb p\u00ebrdorur nj\u00eb menaxher versioni. M\u00eb par\u00eb, p\u00ebr Ruby p\u00ebrdornim nj\u00eb paket\u00eb rpm q\u00eb lejonte nd\u00ebrrimin e versioneve n\u00eb var\u00ebsi t\u00eb projektit. Gjithashtu, kjo lejon migrimin e qet\u00eb t\u00eb kodit dhe versionimin e tij s\u00eb bashku me var\u00ebsit\u00eb p\u00ebrmes kontejnerit Docker. Nuk kemi asnj\u00eb problem p\u00ebr t\u00eb kuptuar versionin e interpreterit dhe t\u00eb kodit. P\u00ebr t\u00eb p\u00ebrdit\u00ebsuar versionin, \u00ebsht\u00eb e nevojshme t\u00eb ulet kontejneri i vjet\u00ebr dhe t\u00eb ngrihet nj\u00eb kontejner i ri. N\u00ebse di\u00e7ka shkon keq, mund t\u00eb ulim kontejnerin e ri dhe t\u00eb ngrem\u00eb kontejnerin e vjet\u00ebr.<\/p>\n<p><\/p>\n<p>Pas nd\u00ebrtimit t\u00eb imazhit, kontejner\u00ebt si n\u00eb Zhvillim ashtu edhe n\u00eb Prodhim do t\u00eb jen\u00eb identik\u00eb. Kjo \u00ebsht\u00eb ve\u00e7an\u00ebrisht relevante p\u00ebr instalimet e m\u00ebdha.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/185a1bfe257f7e3e0eecdc6e0e0d330f.jpg\" style=\"display:block;margin: 0 auto;\" \/> N\u00eb Frontend p\u00ebrdorim JavaScript dhe NodeJS.<\/p>\n<p><\/p>\n<p>Projektin e fundit e kemi n\u00eb ReactJS. Zhvilluesi nisi t\u00eb gjitha kontejner\u00ebt dhe punoi duke p\u00ebrdorur hot-reload.<\/p>\n<p><\/p>\n<p>M\u00eb pas niset detyra p\u00ebr nd\u00ebrtimin e JavaScript dhe kodi, i nd\u00ebrtuar n\u00eb statik\u00eb, dor\u00ebzohet p\u00ebrmes nginx p\u00ebr t\u00eb kursyer burimet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4c2e28319d56d7fc81845b4133a1bfe6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>K\u00ebtu kam sjell\u00eb skem\u00ebn e projektit ton\u00eb m\u00eb t\u00eb fundit.<\/p>\n<p><\/p>\n<p>\u00c7far\u00eb detyrash zgjidh\u00ebm? Kemi pasur nevoj\u00eb t\u00eb nd\u00ebrtojm\u00eb nj\u00eb sistem q\u00eb bashk\u00ebvepron me pajisjet mobile. Ato marrin t\u00eb dh\u00ebna. Nj\u00eb nga mund\u00ebsit\u00eb \u00ebsht\u00eb d\u00ebrgimi i njoftimeve push n\u00eb k\u00ebt\u00eb pajisje. <\/p>\n<p><\/p>\n<p>\u00c7far\u00eb b\u00ebm\u00eb p\u00ebr k\u00ebt\u00eb?<\/p>\n<p><\/p>\n<p>Ne e ndam\u00eb aplikacionin n\u00eb komponent\u00eb si: pjesa administrative n\u00eb JS, backend-i, i cili funksionon p\u00ebrmes nj\u00eb nd\u00ebrfaqe REST n\u00ebn Ruby on Rails. Backend-i bashk\u00ebvepron me baz\u00ebn e t\u00eb dh\u00ebnave. Rezultati, q\u00eb gjenerohet, dor\u00ebzohet te klienti. Pjesa administrative bashk\u00ebvepron me backend-in dhe baz\u00ebn e t\u00eb dh\u00ebnave p\u00ebrmes nd\u00ebrfaqes REST.<\/p>\n<p><\/p>\n<p>N\u00eb t\u00eb nj\u00ebjt\u00ebn koh\u00eb, kishim nevoj\u00eb t\u00eb d\u00ebrgonim njoftime Push. Para k\u00ebsaj, kishim nj\u00eb projekt n\u00eb t\u00eb cilin ishte realizuar mekanizmi q\u00eb merrej me dor\u00ebzimin e njoftimeve n\u00eb platformat mobile. <\/p>\n<p><\/p>\n<p>Ne zhvilluam k\u00ebt\u00eb skem\u00eb: operatori nga shfletuesi bashk\u00ebvepron me pjes\u00ebn administrative, pjesa administrative bashk\u00ebvepron me backend-in, vendoset detyra p\u00ebr t\u00eb d\u00ebrguar njoftime Push.<\/p>\n<p><\/p>\n<p>Njoftimet Push bashk\u00ebveprojn\u00eb me nj\u00eb komponent tjet\u00ebr, i cili \u00ebsht\u00eb realizuar n\u00eb NodeJS.<\/p>\n<p><\/p>\n<p>Krijohen radh\u00eb dhe m\u00eb pas vazhdon mekanizmi i d\u00ebrgimit t\u00eb njoftimeve.<\/p>\n<p><\/p>\n<p>K\u00ebtu jan\u00eb ilustruar dy baza t\u00eb dh\u00ebnash. Aktualisht, ne po p\u00ebrdorim 2 baza t\u00eb dh\u00ebnash t\u00eb pavarura me ndihm\u00ebn e Docker, t\u00eb cilat nuk jan\u00eb aspak t\u00eb lidhura me nj\u00ebra-tjetr\u00ebn. P\u00ebrve\u00e7 faktit q\u00eb ato ndajn\u00eb nj\u00eb rrjet virtual t\u00eb p\u00ebrbashk\u00ebt, t\u00eb dh\u00ebnat fisnike ruhen n\u00eb kataloge t\u00eb ndryshme n\u00eb makin\u00ebn e zhvilluesit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/dfde59db7e6886d2d851dcf884049318.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E nj\u00ebjta gj\u00eb por n\u00eb numra. K\u00ebtu \u00ebsht\u00eb e r\u00ebnd\u00ebsishme rip\u00ebrdorimi i kodit.<\/p>\n<p><\/p>\n<p>N\u00ebse m\u00eb par\u00eb kemi folur p\u00ebr rip\u00ebrdorimin e kodit n\u00eb form\u00ebn e bibliotekave, n\u00eb k\u00ebt\u00eb shembull sh\u00ebrbimi yn\u00eb q\u00eb merret me njoftimet Push, rip\u00ebrdoret si nj\u00eb server i plot\u00eb. Ai ofron nj\u00eb API. Dhe p\u00ebr k\u00ebt\u00eb nd\u00ebrvepron zhvillimi yn\u00eb i ri.<\/p>\n<p><\/p>\n<p>N\u00eb at\u00eb koh\u00eb ne po p\u00ebrdornim versionin 4 t\u00eb NodeJS. Tani (n\u00eb vitin 2017 \u2014 sh\u00ebnim i redaktorit) n\u00eb zhvillimet e reja po p\u00ebrdorim versionin 7 t\u00eb NodeJS. Nuk ka probleme n\u00eb komponent\u00ebt e rinj p\u00ebr t\u00eb t\u00ebrhequr versionet e reja t\u00eb bibliotekave. <\/p>\n<p><\/p>\n<p>N\u00ebse \u00ebsht\u00eb e nevojshme, mund t\u00eb kryhet nj\u00eb riorganizim dhe t\u00eb rritet versioni i NodeJS p\u00ebr sh\u00ebrbimin e njoftimeve Push. <\/p>\n<p><\/p>\n<p>Dhe n\u00ebse ne mund t\u00eb ruajm\u00eb p\u00ebrputhshm\u00ebrin\u00eb p\u00ebr API-n\u00eb, at\u00ebher\u00eb mund ta z\u00ebvend\u00ebsojm\u00eb at\u00eb n\u00eb projekte t\u00eb tjera q\u00eb jan\u00eb p\u00ebrdorur m\u00eb par\u00eb.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5c58c65be078a5a1b9fc17ee2e7b4ad4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c7far\u00eb nevojitet p\u00ebr t\u00eb shtuar Docker? Shtojm\u00eb n\u00eb depozit\u00ebn ton\u00eb Dockerfile, i cili p\u00ebrshkruan var\u00ebsit\u00eb e nevojshme. N\u00eb k\u00ebt\u00eb shembull, komponentet jan\u00eb t\u00eb ndara sipas logjik\u00ebs. Ky \u00ebsht\u00eb nj\u00eb grup minimal p\u00ebr zhvilluesin e backend-it.<\/p>\n<p><\/p>\n<p>Kur krijojm\u00eb nj\u00eb projekt t\u00eb ri, krijojm\u00eb Dockerfile, p\u00ebrshkruajm\u00eb ekosistemin e nevojsh\u00ebm (Python, Ruby, NodeJS). N\u00eb docker-compose p\u00ebrshkruhet var\u00ebsia e nevojshme \u2014 baza e t\u00eb dh\u00ebnave. P\u00ebrcaktojm\u00eb se na nevojitet nj\u00eb baz\u00eb n\u00eb k\u00ebt\u00eb version, duke ruajtur t\u00eb dh\u00ebnat aty ku duhet.<\/p>\n<p><\/p>\n<p>Ne p\u00ebrdorim nj\u00eb kontejner t\u00eb tret\u00eb p\u00ebr sh\u00ebrbimin e skedar\u00ebve statik\u00eb me nginx. \u00cbsht\u00eb parashikuar mund\u00ebsia e ngarkimit t\u00eb imazheve. Backend-i i vendos ato n\u00eb nj\u00eb v\u00ebllim t\u00eb p\u00ebrgatitur paraprakisht, i cili gjithashtu \u00ebsht\u00eb montuar n\u00eb kontejnerin me nginx q\u00eb ofron skedar\u00ebt statik\u00eb.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb ruajtur konfigurimin e nginx dhe mysql, ne kemi shtuar nj\u00eb dosje Docker, ku ruajm\u00eb konfigurimet e nevojshme. Kur zhvilluesi b\u00ebn git clone t\u00eb depozit\u00ebs n\u00eb makin\u00ebn e tij, ai merr nj\u00eb projekt tashm\u00eb t\u00eb gatsh\u00ebm p\u00ebr zhvillim lokal. Nuk lind pyetja se cili port ose cilat cil\u00ebsime duhet t\u00eb aplikohen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e7a6b308a75cacf8ce60687a9e6081dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>M\u00eb tej, kemi disa komponent\u00eb: administratori, inform-API, njoftime push.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb nisur t\u00eb gjitha k\u00ebto, krijuam nj\u00eb depo t\u00eb re, t\u00eb quajtur dockerized-app. Aktualisht, ne p\u00ebrdorim disa depove p\u00ebr \u00e7do komponent. Ato ndahen logjikisht \u2014 n\u00eb GitLab duket si nj\u00eb dosje, nd\u00ebrsa n\u00eb makin\u00ebn e zhvilluesit, \u00ebsht\u00eb nj\u00eb dosje p\u00ebr projektin p\u00ebrkat\u00ebs. N\u00ebn k\u00ebt\u00eb nivel ndodhen komponent\u00ebt q\u00eb do t\u00eb kombinohen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f4e2c45c8ec20fca0bac74b3a3892543.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb shembull i p\u00ebrmbajtjes s\u00eb dockerized-app. Ne po ashtu e nxjerrim k\u00ebtu katalogun Docker, ku plot\u00ebsojm\u00eb konfigurimet e nevojshme p\u00ebr bashk\u00ebveprimin e t\u00eb gjith\u00eb komponent\u00ebve. Ka nj\u00eb README.md, ku p\u00ebrshkruhet shkurtimisht si t\u00eb nisni projektin.<\/p>\n<p><\/p>\n<p>K\u00ebtu kemi aplikuar dy skedar\u00eb docker-compose. Kjo \u00ebsht\u00eb b\u00ebr\u00eb p\u00ebr t\u00eb pasur mund\u00ebsin\u00eb p\u00ebr ta nisur hap pas hapi. Kur zhvilluesi punon me kernin, nuk i nevojiten njoftimet Push, k\u00ebshtu q\u00eb ai thjesht nis skedarin docker-compose dhe p\u00ebr k\u00ebt\u00eb arsye ekonomizohet burimi.<\/p>\n<p><\/p>\n<p>N\u00ebse ka nevoj\u00eb p\u00ebr integrim me njoftimet Push, at\u00ebher\u00eb aktivizohet docker-compose.yaml dhe docker-compose-push.yaml.<\/p>\n<p><\/p>\n<p>Duke qen\u00eb se docker-compose.yaml dhe docker-compose-push.yaml ndodhen n\u00eb t\u00eb nj\u00ebjt\u00ebn dosje, krijohet automatikisht nj\u00eb rrjet virtual i vet\u00ebm.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/535019c82c72c1602176fbaf4aa5640f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00ebrshkrimi i komponenteve. Ky \u00ebsht\u00eb nj\u00eb skedar m\u00eb i gjer\u00eb q\u00eb p\u00ebrgjigjet p\u00ebr grumbullimin e komponent\u00ebve. \u00c7far\u00eb \u00ebsht\u00eb e ve\u00e7ant\u00eb k\u00ebtu? K\u00ebtu ne prezantojm\u00eb komponentin balancer.<\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb imazh Docker i gatsh\u00ebm, n\u00eb t\u00eb cilin funksionon nginx dhe nj\u00eb aplikacion q\u00eb d\u00ebgjon socket-in e Docker-it. Ai rigjeneron konfigurimin e nginx-it dinamikisht, nd\u00ebrsa konteiner\u00ebt aktivizohen dhe deaktivizohen. Trajtimi me komponent\u00ebt shp\u00ebrndahet sipas emrave t\u00eb domain-\u00ebve t\u00eb tret\u00eb.<\/p>\n<p><\/p>\n<p>P\u00ebr mjedisin e zhvillimit p\u00ebrdorim domain-in .dev \u2014 api.informer.dev. Aplikacionet me domain .dev jan\u00eb t\u00eb arritshme n\u00eb kompjuterin lokal t\u00eb zhvilluesit.<\/p>\n<p><\/p>\n<p>M\u00eb pas konfigurimet kalojn\u00eb n\u00eb \u00e7do projekt dhe t\u00eb gjith\u00eb projektet \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f n\u00eb t\u00eb nj\u00ebjt\u00ebn koh\u00eb.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/bc1e11e6f1fd1c837d2c8087d04145c4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00ebse e paraqesim grafisht, klienti \u00ebsht\u00eb shfletuesi yn\u00eb ose ndonj\u00eb mjet, me t\u00eb cilin ne kryejm\u00eb k\u00ebrkesa n\u00eb balancer.<\/p>\n<p><\/p>\n<p>Balancer-i, n\u00ebp\u00ebrmjet emrit t\u00eb domain-it, p\u00ebrcakton n\u00eb cilin konteiner duhet t\u00eb i drejtohemi.<\/p>\n<p><\/p>\n<p>Kjo mund t\u00eb jet\u00eb nginx, q\u00eb ofron JS t\u00eb panelit administrativ. Mund t\u00eb jet\u00eb gjithashtu nginx, q\u00eb ofron API ose skedar\u00eb statik\u00eb, q\u00eb dor\u00ebzohen nga nginx n\u00eb form\u00ebn e ngarkesave t\u00eb imazheve.<\/p>\n<p><\/p>\n<p>N\u00eb diagram, shihet se konteiner\u00ebt jan\u00eb t\u00eb bashkuar n\u00eb nj\u00eb rrjet virtual dhe jan\u00eb t\u00eb fshehur pas nj\u00eb proxy.<\/p>\n<p><\/p>\n<p>N\u00eb makin\u00ebn e zhvilluesit, mund t\u00eb qaseni n\u00eb kontejner duke ditur IP-n\u00eb, por ne n\u00eb parim nuk e p\u00ebrdorim k\u00ebt\u00eb. Praktikisht nuk ka nevoj\u00eb p\u00ebr qasje t\u00eb drejtp\u00ebrdrejt\u00eb.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/2908c31fd9d3c79f6189bdbeeb6d028f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cila \u00ebsht\u00eb nj\u00eb shembull q\u00eb mund t\u00eb shikoni p\u00ebr t\u00eb dockerizuar aplikacionin tuaj? P\u00ebr mendimin tim, nj\u00eb shembull i mir\u00eb \u00ebsht\u00eb imazhi zyrtar docker p\u00ebr MySQL.<\/p>\n<p><\/p>\n<p>Ai \u00ebsht\u00eb mjaft kompleks. Ka shum\u00eb versione. Por funksionaliteti i tij lejon t\u00eb p\u00ebrmbush\u00eb nj\u00eb gam\u00eb t\u00eb gjer\u00eb nevojash q\u00eb mund t\u00eb lindin gjat\u00eb zhvillimit t\u00eb m\u00ebtejsh\u00ebm. N\u00ebse shkoni pak m\u00eb thell\u00eb dhe kuptoni se si nd\u00ebrveprojn\u00eb t\u00eb gjitha k\u00ebto, mendoj se nuk do t\u00eb keni probleme me implementimin e pavarur.<\/p>\n<p><\/p>\n<p>N\u00eb hub.docker.com zakonisht ka lidhje me github.com, ku jepen t\u00eb dh\u00ebnat e pap\u00ebrpunuara nga t\u00eb cilat mund t\u00eb krijoni vet\u00eb imazhin.<\/p>\n<p><\/p>\n<p>M\u00eb pas, n\u00eb k\u00ebt\u00eb depo ka skripti docker-endpoint.sh, i cili p\u00ebrgjigjet p\u00ebr inicializimin e par\u00eb dhe p\u00ebr trajtimin e m\u00ebtejsh\u00ebm t\u00eb fillimit t\u00eb aplikacionit.<\/p>\n<p><\/p>\n<p>N\u00eb k\u00ebt\u00eb shembull gjithashtu ka mund\u00ebsin\u00eb e konfigurimit n\u00ebp\u00ebrmjet variablave t\u00eb mjedisit. Duke p\u00ebrcaktuar nj\u00eb variab\u00ebl mjedisi gjat\u00eb nisjes s\u00eb nj\u00eb konteineri t\u00eb vetme ose p\u00ebrmes docker-compose, mund t\u00eb themi se na nevojitet t\u00eb p\u00ebrcaktojm\u00eb nj\u00eb fjal\u00ebkalim bosh p\u00ebr docker p\u00ebr root n\u00eb MySQL, ose ndonj\u00eb fjal\u00ebkalim tjet\u00ebr q\u00eb d\u00ebshirojm\u00eb.<\/p>\n<p><\/p>\n<p>Ka mund\u00ebsin\u00eb t\u00eb krijojm\u00eb nj\u00eb fjal\u00ebkalim rast\u00ebsor. Ne themi se na nevojitet nj\u00eb p\u00ebrdorues, na nevojitet t\u00eb vendosim nj\u00eb fjal\u00ebkalim p\u00ebr p\u00ebrdoruesin dhe na nevojitet t\u00eb krijojm\u00eb nj\u00eb baz\u00eb t\u00eb dh\u00ebnash.<\/p>\n<p><\/p>\n<p>N\u00eb projektet tona kemi pak unifikuar Dockerfile-in q\u00eb p\u00ebrgjigjet p\u00ebr inicializimin. Aty e kemi p\u00ebrmir\u00ebsuar p\u00ebr nevojat tona duke b\u00ebr\u00eb thjesht zgjerimin e t\u00eb drejtave t\u00eb p\u00ebrdoruesit q\u00eb aplikacioni p\u00ebrdor. Kjo na lejoi m\u00eb pas t\u00eb krijonim leht\u00ebsisht nj\u00eb baz\u00eb t\u00eb dh\u00ebnash nga konsola e aplikacionit. N\u00eb aplikacionet Ruby ka nj\u00eb komand\u00eb p\u00ebr krijimin, ndryshimin dhe fshirjen e bazave t\u00eb dh\u00ebnash.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4a9b56e21819d28dd39753134d23fee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb shembull se si duket nj\u00eb version konkret i MySQL n\u00eb github.com. Dockerfile-i mund t\u00eb hapet dhe t\u00eb shikohet se si ndodh instalimi atje.<\/p>\n<p><\/p>\n<p>docker-endpoint.sh \u00ebsht\u00eb skripti q\u00eb menaxhon pik\u00ebn e hyrjes. N\u00eb fillim, disa veprime p\u00ebrgatitore jan\u00eb t\u00eb nevojshme, dhe t\u00eb gjitha k\u00ebto veprime jan\u00eb p\u00ebrfshir\u00eb n\u00eb skriptin e inicializimit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4153fa46526f3d802931dd1db48b08cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>T\u00eb kalojm\u00eb n\u00eb pjes\u00ebn e dyt\u00eb.<\/p>\n<p><\/p>\n<p>P\u00ebr ruajtjen e kodit burimor, kemi kaluar n\u00eb gitlab. Kjo \u00ebsht\u00eb nj\u00eb sistem mjaft i fuqish\u00ebm, i cili ka nj\u00eb \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 vizual.<\/p>\n<p><\/p>\n<p>Nj\u00eb nga komponent\u00ebt e Gitlab \u00ebsht\u00eb Gitlab CI. Ai lejon p\u00ebrshkrimin e nj\u00eb rendi komandash, t\u00eb cilat do t\u00eb p\u00ebrdoren p\u00ebr t\u00eb organizuar sistemin e dor\u00ebzimit t\u00eb kodit ose p\u00ebr t\u00eb nisur testimin automatike.<\/p>\n<p><\/p>\n<p>Raporti mbi Gitlab CI 2 <noindex><a rel=\"nofollow\" href=\"https:\/\/goo.gl\/uohKjI\">https:\/\/goo.gl\/uohKjI<\/a><\/noindex> \u2014 nj\u00eb raport nga Ruby Russia club \u2014 \u00ebsht\u00eb mjaft i detajuar dhe ndoshta do t'ju \u0438\u043d\u0442\u0435\u0440\u0435\u0441oj\u00eb.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5d26d20500f34eeb9768e6c3d91bbefa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tani do t\u00eb shqyrtojm\u00eb se \u00e7far\u00eb k\u00ebrkohet p\u00ebr t\u00eb aktivizuar Gitlab CI. P\u00ebr t\u00eb nisur Gitlab CI, mjafton t\u00eb vendosim skedarin .gitlab-ci.yml n\u00eb rr\u00ebnj\u00ebn e projektit.<\/p>\n<p><\/p>\n<p>K\u00ebtu p\u00ebrshkruajm\u00eb se \u00e7far\u00eb d\u00ebshirojm\u00eb t\u00eb ekzekutojm\u00eb si nj\u00eb sekuenc\u00eb gjendjesh, si teste ose implementime.<\/p>\n<p><\/p>\n<p>Ekzekutojm\u00eb skriptet q\u00eb th\u00ebrrasin n\u00eb m\u00ebnyr\u00eb direkte nd\u00ebrtimin e aplikacionit ton\u00eb me docker-compose. Ky \u00ebsht\u00eb nj\u00eb shembull p\u00ebr backend.<\/p>\n<p><\/p>\n<p>M\u00eb pas, ne themi se \u00ebsht\u00eb e nevojshme t\u00eb p\u00ebrfundojm\u00eb migrimet p\u00ebr ndryshimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe t\u00eb p\u00ebrfundojm\u00eb testet.<\/p>\n<p><\/p>\n<p>N\u00ebse skriptet ekzekutohen si\u00e7 duhet dhe nuk kthejn\u00eb nj\u00eb kod gabimi, sistemi kalon n\u00eb faz\u00ebn e dyt\u00eb t\u00eb publikuar.<\/p>\n<p><\/p>\n<p>Faza e publikuar \u00ebsht\u00eb realizuar aktualisht p\u00ebr stagim. Nuk kemi organizuar nj\u00eb rinisje pa nd\u00ebrprerje.<\/p>\n<p><\/p>\n<p>Ne mbyllim detyrimisht t\u00eb gjith\u00eb kontejner\u00ebt dhe pastaj i ngrem\u00eb p\u00ebrs\u00ebri t\u00eb gjith\u00eb kontejner\u00ebt, t\u00eb nd\u00ebrtuar n\u00eb faz\u00ebn e par\u00eb gjat\u00eb testimit.<\/p>\n<p><\/p>\n<p>Kryejm\u00eb migrimet e bazave t\u00eb t\u00eb dh\u00ebnave p\u00ebr mjedisin e tanish\u00ebm, t\u00eb shkruara nga zhvilluesit.<\/p>\n<p><\/p>\n<p>Ka nj\u00eb sh\u00ebnim q\u00eb kjo t\u00eb aplikohet vet\u00ebm p\u00ebr deg\u00ebn master.<\/p>\n<p><\/p>\n<p>Nuk kryhet me ndryshime n\u00eb deg\u00ebt e tjera.<\/p>\n<p><\/p>\n<p>Ka mund\u00ebsi p\u00ebr t\u00eb organizuar publikime sipas deg\u00ebve.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/8a5b880bd9a0d4bab0b276568e2ba413.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb organizuar m\u00eb tej k\u00ebt\u00eb, ne duhet t\u00eb instalojm\u00eb Gitlab Runner.<\/p>\n<p><\/p>\n<p>Kjo utilit \u00ebsht\u00eb e shkruar n\u00eb Golang. Ajo \u00ebsht\u00eb nj\u00eb skedar i vet\u00ebm si\u00e7 \u00ebsht\u00eb e zakonshme n\u00eb bot\u00ebn e Golang, i cili nuk k\u00ebrkon asnj\u00eb var\u00ebsi.<\/p>\n<p><\/p>\n<p>Kur e aktivizojm\u00eb, regjistrojm\u00eb Gitlab Runner.<\/p>\n<p><\/p>\n<p>Marrim nj\u00eb \u00e7el\u00ebs n\u00eb nd\u00ebrfaqen web t\u00eb Gitlab.<\/p>\n<p><\/p>\n<p>Pastaj th\u00ebrrasim komand\u00ebn e inicializimit n\u00eb linj\u00ebn e komand\u00ebs.<\/p>\n<p><\/p>\n<p>Konfigurojm\u00eb Gitlab Runner n\u00eb modin e dialogut (Shell, Docker, VirtualBox, SSH).<\/p>\n<p><\/p>\n<p>Kodi n\u00eb Gitlab Runner do t\u00eb ekzekutohet me \u00e7do komitim, n\u00eb var\u00ebsi t\u00eb konfigurimit .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/37c8ac7499f0cfba2eb07a84083e44e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si duket kjo n\u00eb GitLab n\u00eb nd\u00ebrfaqen e web-it. Pas lidhjes s\u00eb GitLab CI, shfaqet nj\u00eb flamur q\u00eb tregon n\u00eb cilin gjendje ndodhet nd\u00ebrtimi aktualisht.<\/p>\n<p><\/p>\n<p>Duke par\u00eb, shohim se para 4 minutash \u00ebsht\u00eb b\u00ebr\u00eb nj\u00eb commit q\u00eb kaloi t\u00eb gjitha testet dhe nuk b\u00ebri probleme.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/33ac79c45f0651a5f8bde75092c4ac44.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mund t\u00eb shohim m\u00eb n\u00eb detaje p\u00ebr nd\u00ebrtimet. K\u00ebtu shohim se jan\u00eb kaluar dy gjendje. Gjendja e testimit dhe gjendja e deploy-it n\u00eb staging.<\/p>\n<p><\/p>\n<p>N\u00ebse klikojm\u00eb n\u00eb nj\u00eb nd\u00ebrtim t\u00eb ve\u00e7ant\u00eb, atje do t\u00eb ket\u00eb daljen e komandave q\u00eb u ekzekutuan n\u00eb proces sipas .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d26dd28708c7fc8a409af4be4d48f502.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>K\u00ebshtu duket historia e produktit ton\u00eb. Shohim q\u00eb ka pasur p\u00ebrpjekje t\u00eb suksesshme. Kur testet d\u00ebshtojn\u00eb, ato nuk kalojn\u00eb n\u00eb hapin tjet\u00ebr dhe kodi n\u00eb staging nuk azhurnohet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ee7bd81dc283c7af0c194779d4230780.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cilat probleme zgjidh\u00ebm n\u00eb staging kur implementuam docker? Sistema jon\u00eb p\u00ebrb\u00ebhet nga komponente t\u00eb ndryshme dhe kishim nevoj\u00eb t\u00eb rinisnim vet\u00ebm disa nga komponentet q\u00eb ishin azhurnuar n\u00eb repositorin, jo t\u00eb gjith\u00eb sistemin.<\/p>\n<p><\/p>\n<p>P\u00ebr k\u00ebt\u00eb na duhej t\u00eb ndanim gjith\u00e7ka n\u00eb dosje t\u00eb ve\u00e7anta.<\/p>\n<p><\/p>\n<p>Pas pas k\u00ebtij hapi, has\u00ebm nj\u00eb problem sepse Docker-compose krijon nj\u00eb hap\u00ebsir\u00eb rrjeti p\u00ebr \u00e7do dosje dhe nuk sheh komponent\u00ebt e fqinjit.<\/p>\n<p><\/p>\n<p>P\u00ebr ta anashkaluar k\u00ebt\u00eb, krijuam nj\u00eb rrjet n\u00eb Docker manualisht. N\u00eb Docker-compose shkruam se p\u00ebr k\u00ebt\u00eb projekt duhet t\u00eb p\u00ebrdor\u00eb nj\u00eb rrjet t\u00eb till\u00eb.<\/p>\n<p><\/p>\n<p>K\u00ebshtu, \u00e7do komponent q\u00eb fillon me k\u00ebt\u00eb rrjet sheh komponent\u00ebt n\u00eb pjes\u00eb t\u00eb tjera t\u00eb sistemit.<\/p>\n<p><\/p>\n<p>Problemi tjet\u00ebr \u00ebsht\u00eb ndarja staging mes disa projekteve.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb b\u00ebr\u00eb q\u00eb gjith\u00e7ka t\u00eb duket bukur dhe sa m\u00eb af\u00ebr production, \u00ebsht\u00eb mir\u00eb t\u00eb p\u00ebrdoret porta 80 ose 443, t\u00eb cilat p\u00ebrdoren gjer\u00ebsisht n\u00eb WEB.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f863cf1833271bf132455a70ad7d2706.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si e zgjidh\u00ebm k\u00ebt\u00eb? E caktuam nj\u00eb Gitlab Runner p\u00ebr t\u00eb gjith\u00eb projektet e m\u00ebdha.<\/p>\n<p><\/p>\n<p>Gitlab lejon t\u00eb drejtohen disa Gitlab Runner t\u00eb shp\u00ebrndara, t\u00eb cilat thjesht do t\u00eb marrin t\u00eb gjitha detyrat n\u00eb rend t\u00eb rast\u00ebsish\u00ebm.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb shmangur \u00e7do shkak q\u00eb do t\u00eb krijonte kaos, e limituam grupin ton\u00eb t\u00eb projekteve me nj\u00eb Gitlab Runner, i cili me volumet tona funksionon pa probleme.<\/p>\n<p><\/p>\n<p>E nxor\u00ebm nginx-proxy n\u00eb nj\u00eb skrypt t\u00eb ve\u00e7ant\u00eb fillimi dhe aty sh\u00ebnuam rrjetet e t\u00eb gjitha projekteve. <\/p>\n<p><\/p>\n<p>Projekti yn\u00eb ka nj\u00eb rrjet t\u00eb vet, nd\u00ebrsa balanceri ka disa rrjete sipas emrave t\u00eb projekteve. Ai mund t\u00eb prokuroj\u00eb m\u00eb tej sipas emrave t\u00eb domeve.<\/p>\n<p><\/p>\n<p>K\u00ebrkesat tona vijn\u00eb p\u00ebrmes domenit n\u00eb portin 80 dhe menaxhohen n\u00eb nj\u00eb grup kontejnerash, t\u00eb cil\u00ebt sh\u00ebrbejn\u00eb k\u00ebt\u00eb domen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25c769f029b272a17fd06bbe60cf0ea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cilat ishin problemet e tjera? Kjo \u00ebsht\u00eb ajo q\u00eb sipas default, t\u00eb gjith\u00eb kontejner\u00ebt ekzekutohen nga p\u00ebrdoruesi root. Ky root nuk \u00ebsht\u00eb i nj\u00ebjt\u00eb me root-in e sistemit.<\/p>\n<p><\/p>\n<p>Megjithat\u00eb, n\u00ebse hyni n\u00eb kontejner, at\u00ebher\u00eb do t\u00eb jeni root dhe dosja q\u00eb krijojm\u00eb n\u00eb k\u00ebt\u00eb kontejner merr t\u00eb drejta root.<\/p>\n<p><\/p>\n<p>N\u00ebse nj\u00eb zhvillues hyn n\u00eb kontejner dhe ekzekuton disa komanda q\u00eb gjenerojn\u00eb skedar\u00eb, pastaj del nga kontejneri, ai n\u00eb direktorin\u00eb e tij t\u00eb pun\u00ebs ka nj\u00eb skedar, t\u00eb cilin nuk ka akses.<\/p>\n<p><\/p>\n<p>Si mund ta zgjidhim k\u00ebt\u00eb? Mund t\u00eb shtojm\u00eb p\u00ebrdorues q\u00eb do t\u00eb jen\u00eb n\u00eb kontejner.<\/p>\n<p><\/p>\n<p>Cilat probleme u shfaq\u00ebn kur shtuam p\u00ebrdoruesin?<\/p>\n<p><\/p>\n<p>Kur krijojm\u00eb nj\u00eb p\u00ebrdorues, shpesh nuk p\u00ebrputhen ID-t\u00eb e grupit (UID) dhe ID-t\u00eb e p\u00ebrdoruesit (GID).<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb zgjidhur k\u00ebt\u00eb problem, n\u00eb kontejner p\u00ebrdorim p\u00ebrdorues me ID 1000.<\/p>\n<p><\/p>\n<p>N\u00eb rastin ton\u00eb, kjo p\u00ebrputhet me faktin se pothuajse t\u00eb gjith\u00eb zhvilluesit p\u00ebrdorin sistemin operativ Ubuntu. N\u00eb Ubuntu, p\u00ebrdoruesi i par\u00eb ka ID 1000.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d4911374e4953fdcd807c387efeafec3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cilat jan\u00eb planet tona?<\/p>\n<p><\/p>\n<p>T\u00eb rilexojm\u00eb dokumentacionin p\u00ebr Docker. Projekti po zhvillohet aktivisht, dokumentacioni po ndryshon. T\u00eb dh\u00ebnat q\u00eb jan\u00eb marr\u00eb dy-tre muaj m\u00eb par\u00eb, tashm\u00eb po skadojn\u00eb ngadal\u00eb. <\/p>\n<p><\/p>\n<p>Disa nga problemet q\u00eb kemi zgjidhur, shum\u00eb mund t\u00eb jen\u00eb zgjidhur tashm\u00eb me mjete standarde.<\/p>\n<p><\/p>\n<p>D\u00ebshira \u00ebsht\u00eb t\u00eb kalojm\u00eb m\u00eb tej dhe t\u00eb kalojm\u00eb drejtp\u00ebrdrejt n\u00eb orkestrimin.<\/p>\n<p><\/p>\n<p>Nj\u00eb nga shembujt \u00ebsht\u00eb mekanizmi i nd\u00ebrtuar brenda Docker, i quajtur Docker Swarm, q\u00eb vjen gatish\u00ebm. D\u00ebshirojm\u00eb t\u00eb drejtojm\u00eb di\u00e7ka n\u00eb prodhim duke p\u00ebrdorur teknologjin\u00eb Docker Swarm.<\/p>\n<p><\/p>\n<p>Krijimi i kontejner\u00ebve e b\u00ebn t\u00eb v\u00ebshtir\u00eb pun\u00ebn me loget. Tani loget jan\u00eb t\u00eb izoluar. Ato jan\u00eb t\u00eb p\u00ebrhapura n\u00ebp\u00ebr kontejner\u00eb. Nj\u00eb nga detyrat \u00ebsht\u00eb t\u00eb sigurojm\u00eb akses t\u00eb leht\u00eb n\u00eb loget p\u00ebrmes nj\u00eb nd\u00ebrfaqeje web.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/cff8c72dd8af7de1fa0227601bd1d69c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449742\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &#171;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&#187; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24326,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Procesi i zhvillimit dhe testimit me Docker dhe Gitlab CI | ProHoster","description":"Ju lutem, shikoni p\u00ebrkthimin e raportit nga Aleksand\u00ebr Sigachev nga Inventos \"Procesi i zhvillimit dhe testimit me Docker + Gitlab CI\". Ata q\u00eb sapo kan\u00eb filluar t\u00eb zbatojn\u00eb procesin e zhvillimit dhe testimit n\u00eb baz\u00eb t\u00eb Docker + Gitlab CI shpesh pyesin pyetje bazike. Nga t\u00eb fillosh? Si t\u00eb organizosh? Si t\u00eb testosh? Ky raport \u00ebsht\u00eb i shk\u00eblqyer sepse tregon n\u00eb m\u00ebnyr\u00eb t\u00eb strukturuar procesin e zhvillimit dhe","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:47:32+00:00","article:modified_time":"2019-10-31T18:47:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32526","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 11:18:24","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:57:22","updated":"2026-01-21 11:18:24","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/32526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=32526"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/32526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/24326"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=32526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=32526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=32526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}