{"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 q\u00eb t\u00eb njiheni me p\u00ebrmbledhjen e raportit t\u00eb Alexander Sigachev nga Inventos \"Procesi i zhvillimit dhe testimit me Docker + Gitlab CI\"<\/strong><\/p>\n<p><\/p>\n<p>Ata q\u00eb sapo fillojn\u00eb t\u00eb implementojn\u00eb procesin e zhvillimit dhe testimit mbi baz\u00ebn e Docker + Gitlab CI shpesh b\u00ebjn\u00eb pyetje bazike. Nga t\u00eb filloj? Si ta organizoj? Si t\u00eb testoj?<\/p>\n<p><\/p>\n<p>Ky raport \u00ebsht\u00eb i mir\u00eb sepse strukturohet p\u00ebr t\u00eb treguar procesin e zhvillimit dhe testimit duke p\u00ebrdorur Docker dhe Gitlab CI. Raporti vet\u00eb \u00ebsht\u00eb i vitit 2017. Mendoj se nga ky raport mund t\u00eb nxjerrim bazat, metodologjin\u00eb, iden\u00eb, p\u00ebrvoj\u00ebn e p\u00ebrdorimit. <\/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 i interesuar, ju lutem, shihni m\u00eb posht\u00eb. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p>M\u00eb prezantohem, jam Aleksandr Sigachev. Punoj n\u00eb kompanin\u00eb Inventos. Do t\u00eb flas p\u00ebr p\u00ebrvoj\u00ebn time n\u00eb p\u00ebrdorimin e Docker dhe si e po e implementojm\u00eb gradualisht 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 mbi Docker. N\u00eb koh\u00ebn 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 p\u00ebrdornin Docker ishte rreth 2-3 persona. Me kalimin e koh\u00ebs, u akumulua p\u00ebrvoj\u00eb dhe avancuam pak m\u00eb tej. Linku p\u00ebr <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/gled\/docker-development-70411088\">raportin ton\u00eb t\u00eb par\u00eb<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>\u00c7far\u00eb do t\u00eb ket\u00eb n\u00eb k\u00ebt\u00eb raport? Ne do t\u00eb ndajm\u00eb p\u00ebrvoj\u00ebn ton\u00eb mbi pengesat q\u00eb kemi p\u00ebrballur, si i kemi zgjidhur problemet. Nuk gjithmon\u00eb ishte e bukur, por na lejoj t\u00eb ecim p\u00ebrpara.<\/p>\n<p><\/p>\n<p>Deviza jon\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 zgjidhim?<\/p>\n<p><\/p>\n<p>Kur n\u00eb kompani ka disa ekipe, programuesi \u00ebsht\u00eb nj\u00eb burim q\u00eb ndahet. Ndonj\u00ebher\u00eb ndodhin etapa kur programuesi hiqet 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 t\u00eb aktivizoj\u00eb sa m\u00eb shpejt nj\u00eb mjedis q\u00eb do t'i lejoj\u00eb atij t\u00eb vazhdoj\u00eb p\u00ebrpara duke zgjidhur detyrat e k\u00ebtij projekti.<\/p>\n<p><\/p>\n<p>Zakonisht, n\u00ebse fillon nga zero, dokumentacioni n\u00eb projekt \u00ebsht\u00eb minimal. Informacioni se si t\u00eb konfigurohet \u00ebsht\u00eb vet\u00ebm te t\u00eb p\u00ebrvojshmit. Punonj\u00ebsit e vet\u00eborganizojn\u00eb vendin e pun\u00ebs n\u00eb nj\u00eb ose dy dit\u00eb. P\u00ebr ta p\u00ebrshpejtuar k\u00ebt\u00eb, ne p\u00ebrdor\u00ebm Docker.<\/p>\n<p><\/p>\n<p>Arsyeja e ardhshme \u00ebsht\u00eb standardizimi i konfigurimeve n\u00eb zhvillim. Nga p\u00ebrvoja ime, zhvilluesit gjithmon\u00eb tregojn\u00eb inisiativ\u00eb. N\u00eb \u00e7do rast t\u00eb pest\u00eb, njohin nj\u00eb domen t\u00eb personalizuar, p\u00ebr shembull vasya.dev. Pran\u00eb tij \u00ebsht\u00eb fqinj Petya, i cili ka domen petya.dev. Ata zhvillojn\u00eb nj\u00eb uebfaqe ose ndonj\u00eb komponent t\u00eb sistemit duke p\u00ebrdorur k\u00ebt\u00eb em\u00ebr domeni.<\/p>\n<p><\/p>\n<p>Kur sistemi zgjerohet dhe k\u00ebto emra domain fillojn\u00eb t\u00eb shfaqen n\u00eb konfigurime, lind nj\u00eb konflikt midis mjediseve t\u00eb Zhvillimit dhe rruga e uebsit rishkruhet.<\/p>\n<p><\/p>\n<p>E nj\u00ebjta gj\u00eb ndodh 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, gjat\u00eb faz\u00ebs s\u00eb instalimit t\u00eb MySQL, u k\u00ebrkua nj\u00eb fjal\u00ebkalim dhe fjal\u00ebkalimi doli t\u00eb ishte 123. Ndodh shpesh q\u00eb konfigurimi i baz\u00ebs s\u00eb t\u00eb dh\u00ebnave t\u00eb ndryshohet vazhdimisht n\u00eb var\u00ebsi t\u00eb commit-it t\u00eb zhvilluesit. Disa kan\u00eb b\u00ebr\u00eb ndryshime, disa nuk e kan\u00eb b\u00ebr\u00eb konfigurimin. Ka pasur truke, kur ne nxjerrim nj\u00eb konfigurim testues n\u00eb <code>.gitignore<\/code> dhe \u00e7do zhvillues duhet t\u00eb instaloj\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Kjo e komplikon procesin e fillimit. P\u00ebrve\u00e7 gjith\u00e7kaje, duhet t\u00eb mbajm\u00eb mend p\u00ebr baz\u00ebn e t\u00eb dh\u00ebnave. Baza e t\u00eb dh\u00ebnave duhet t\u00eb inicializohet, duhet t\u00eb shkruhet nj\u00eb fjal\u00ebkalim, duhet t\u00eb shkruhet nj\u00eb p\u00ebrdorues, t\u00eb krijohet nj\u00eb tabel\u00eb dhe k\u00ebshtu me radh\u00eb.<\/p>\n<p><\/p>\n<p>Nj\u00eb tjet\u00ebr problem \u00ebsht\u00eb p\u00ebr versionet e ndryshme t\u00eb bibliografive. Ndodh shpesh q\u00eb zhvilluesi punon me projekte t\u00eb ndryshme. Ka nj\u00eb projekt Legacy, q\u00eb e kemi filluar pes\u00eb vjet m\u00eb par\u00eb (nga viti 2017 - sh\u00ebnim i redaktorit). N\u00eb momentin e fillimit, kemi filluar me MySQL 5.5. Ka edhe projekte moderne, ku p\u00ebrpiqemi t\u00eb implementojm\u00eb versione m\u00eb moderne t\u00eb MySQL, si 5.7 ose m\u00eb t\u00eb reja (n\u00eb vitin 2017 - sh\u00ebnim i redaktorit).<\/p>\n<p><\/p>\n<p>Atij q\u00eb punon me MySQL e di se k\u00ebto biblioteka sjellin var\u00ebsi. \u00cbsht\u00eb mjaft problematike t\u00eb nisi 2 baza bashk\u00eb. T\u00eb pakt\u00ebn, \u00ebsht\u00eb problematike t\u00eb lidh\u00ebsh klient\u00eb t\u00eb vjet\u00ebr me nj\u00eb baz\u00eb t\u00eb re t\u00eb dh\u00ebnash. Kjo sjell, nga ana tjet\u00ebr, disa probleme.<\/p>\n<p><\/p>\n<p>Problemi tjet\u00ebr \u00ebsht\u00eb kur zhvilluesi punon n\u00eb nj\u00eb makin\u00eb lokale, ai p\u00ebrdor burime lokale, skedar\u00eb lokal\u00eb, RAM lokal. T\u00eb gjitha nd\u00ebrveprimet gjat\u00eb procesit t\u00eb zhvillimit t\u00eb zgjidhjeve realizohen n\u00eb kontekstin e asaj q\u00eb 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\u00eb p\u00ebrgjigjur k\u00ebrkes\u00ebs. Kur ky kod arrin n\u00eb Production, del se skedari \u00ebsht\u00eb n\u00eb nj\u00eb nga 3 server\u00ebt.<\/p>\n<p><\/p>\n<p>Aktualisht po zhvillohet drejtimi i mikrosherbimeve. Kur ndajm\u00eb aplikacionet tona t\u00eb m\u00ebdha n\u00eb disa komponente t\u00eb vogla q\u00eb nd\u00ebrveprojn\u00eb me nj\u00ebra-tjetr\u00ebn. Kjo lejon p\u00ebrzgjedhjen e teknologjive sipas gryk\u00ebs specifike t\u00eb detyrave. Po ashtu, 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 Frontend, duke punuar me JS, praktikisht nuk ndikon n\u00eb Backend. Zhvilluesi Backend, nga ana tjet\u00ebr, zhvillon, n\u00eb rastin ton\u00eb, Ruby on Rails dhe nuk ndikon n\u00eb Frontend. Nd\u00ebrveprimi b\u00ebhet p\u00ebrmes API.<\/p>\n<p><\/p>\n<p>Si nj\u00eb bonus, me ndihm\u00ebn e Docker, arrit\u00ebm t\u00eb optimizojm\u00eb burimet n\u00eb Staging. \u00c7do projekt, p\u00ebr shkak t\u00eb specifikave t\u00eb tij, k\u00ebrkonte konfigurime t\u00eb caktuara. Fizikisht duhej t\u00eb ndaheshin disa server\u00eb virtual\u00eb dhe t\u2019i konfiguroni ve\u00e7 e ve\u00e7, ose t\u00eb ndajm\u00eb nj\u00eb ambient t\u00eb p\u00ebrbashk\u00ebt dhe projektet mund t\u00eb ndikojn\u00eb nj\u00ebra-tjetr\u00ebn n\u00eb var\u00ebsi t\u00eb versioneve t\u00eb librarive.<\/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>Vet\u00eb Docker. N\u00eb Dockerfile p\u00ebrshkruhen var\u00ebsit\u00eb e nj\u00eb aplikacioni. <\/li>\n<li>Docker-compose \u00ebsht\u00eb nj\u00eb lidhje q\u00eb bashkon disa nga aplikacionet tona Docker.<\/li>\n<li>GitLab e p\u00ebrdorim p\u00ebr ruajtjen e kodit burimor.<\/li>\n<li>GitLab-CI e p\u00ebrdorim 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>Referati p\u00ebrb\u00ebhet nga dy pjes\u00eb.<\/p>\n<p><\/p>\n<p>Pjesa e par\u00eb do t\u00eb flas\u00eb p\u00ebr m\u00ebnyr\u00ebn se si aktivizuam Docker n\u00eb makinat e zhvilluesve.<\/p>\n<p><\/p>\n<p>Pjesa e dyt\u00eb do t\u00eb flas\u00eb p\u00ebr m\u00ebnyr\u00ebn se si nd\u00ebrveprojm\u00eb me GitLab, si i aktivizojm\u00eb testet dhe si i l\u00ebshojm\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 \u2014 kjo \u00ebsht\u00eb nj\u00eb teknologji q\u00eb lejon (duke p\u00ebrdorur nj\u00eb qasje deklarative) t\u00eb p\u00ebrshkruajm\u00eb komponent\u00ebt e nevojsh\u00ebm. Kjo \u00ebsht\u00eb nj\u00eb shembull i Dockerfile. K\u00ebtu shpallim se trash\u00ebgojm\u00eb nga imazhi zyrtar i Docker Ruby:2.3.0. Ai p\u00ebrmban Ruby version 2.3 t\u00eb instaluar. Ne instalojm\u00eb bibliotekat e nevojshme p\u00ebr nd\u00ebrtimin dhe NodeJS. P\u00ebrshkruajm\u00eb se 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 minimal dhe Gemfile.lock q\u00eb na nevojitet. M\u00eb pas kryejm\u00eb nd\u00ebrtimin e projekteve, t\u00eb cilat instalojn\u00eb k\u00ebto var\u00ebsi t\u00eb imazhit. U tregojm\u00eb se kontejneri do t\u00eb jet\u00eb gati t\u00eb d\u00ebgjoj\u00eb n\u00eb portin e jasht\u00ebm 3000. Komanda e fundit \u2014 \u00ebsht\u00eb komanda q\u00eb aktivizon aplikacionin ton\u00eb. N\u00ebse ne realizojm\u00eb komand\u00ebn e aktivizimit t\u00eb projektit, aplikacioni do t\u00eb p\u00ebrpiqet t\u00eb ekzekutohet dhe do t\u00eb aktivizoj\u00eb komand\u00ebn e specifikuar.<\/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. N\u00eb k\u00ebt\u00eb rast, ne tregojm\u00eb se si b\u00ebhet lidhja midis dy kontejner\u00ebve. Kjo p\u00ebrfshin sh\u00ebrbimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe sh\u00ebrbimin web. Aplikacionet tona web n\u00eb shumic\u00ebn e rasteve k\u00ebrkojn\u00eb si backend nj\u00eb baz\u00eb t\u00eb dh\u00ebnash p\u00ebr ruajtjen e t\u00eb dh\u00ebnave. Pasi p\u00ebrdorim MySQL, shembulli me MySQL \u00ebsht\u00eb i till\u00eb, por asgj\u00eb nuk ndalon p\u00ebrdorimin e ndonj\u00eb baze tjet\u00ebr t\u00eb dh\u00ebnash (PostgreSQL, Redis).<\/p>\n<p><\/p>\n<p>Ne marrim nga burimi zyrtar n\u00eb Docker hub imazhin MySQL 5.7.14 pa ndryshime. Imazhi q\u00eb p\u00ebrgjigjet p\u00ebr aplikacionin ton\u00eb web ne e nd\u00ebrtojm\u00eb nga direktoria aktuale. Gjat\u00eb fillimit t\u00eb par\u00eb, ai na ndihmon t\u00eb nd\u00ebrtojm\u00eb imazhin. M\u00eb pas, ai ekzekuton komand\u00ebn q\u00eb ne kemi k\u00ebtu. N\u00ebse kthehemi prapa, do t\u00eb shohim q\u00eb ishte e p\u00ebrcaktuar nj\u00eb komand\u00eb p\u00ebr fillimin n\u00ebp\u00ebrmjet Puma. Puma \u00ebsht\u00eb nj\u00eb sh\u00ebrbim i shkruar n\u00eb Ruby. N\u00eb rastin e dyt\u00eb, ne e rishkruajm\u00eb. Kjo komand\u00eb mund t\u00eb jet\u00eb e rast\u00ebsishme n\u00eb var\u00ebsi t\u00eb nevojave ose detyrave tona.<\/p>\n<p><\/p>\n<p>Gjithashtu, ne p\u00ebrshkruajm\u00eb se si duhet t\u00eb kalojm\u00eb portin nga makina e krijuesit n\u00eb portin 3000 t\u00eb kontejnerit. Kjo b\u00ebhet automatikisht p\u00ebrmes iptables dhe mekanizmit t\u00eb tij, i cili \u00ebsht\u00eb nd\u00ebrtuar n\u00eb Docker. <\/p>\n<p><\/p>\n<p>Krijuesi mund gjithashtu, ashtu si m\u00eb par\u00eb, t\u00eb aksesoj\u00eb \u00e7do adres\u00eb IP t\u00eb disponueshme, p\u00ebr shembull, 127.0.0.1 n\u00eb m\u00ebnyr\u00eb lokale ose adres\u00ebn IP t\u00eb jashtme t\u00eb makin\u00ebs.<\/p>\n<p><\/p>\n<p>Rreshti i fundit thot\u00eb se kontejneri web varet nga kontejneri db. Kur ne th\u00ebrrasim p\u00ebr t\u00eb filluar kontejnerin web, paraprakisht docker-compose do t\u00eb nis\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Pas fillimit t\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave (n\u00eb t\u00eb v\u00ebrtet\u00eb \u2014 pas aktivizimit t\u00eb kontejnerit! Gatishm\u00ebria e BDr\u00eb nuk garanton k\u00ebt\u00eb) do t\u00eb nis\u00eb aplikacionin ton\u00eb, backend-in ton\u00eb.<\/p>\n<p><\/p>\n<p>Kjo lejon t\u00eb shmangen gabimet kur baza e t\u00eb dh\u00ebnave nuk \u00ebsht\u00eb ngritur dhe ndihmon n\u00eb kursimin e burimeve, kur ne ndalojm\u00eb kontejnerin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, duke i 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 regjistrojm\u00eb versionin e MySQL p\u00ebr t\u00eb gjith\u00eb krijuesit. Kjo ndihmon n\u00eb shmangien e disa gabimeve q\u00eb mund t\u00eb ndodhin kur versionet ndryshojn\u00eb, kur ndodhin ndryshime n\u00eb sintaks\u00eb, konfigurim, cil\u00ebsime standarde. Kjo lejon t\u00eb p\u00ebrcaktojm\u00eb hostname t\u00eb p\u00ebrbashk\u00ebta p\u00ebr baz\u00ebn e t\u00eb dh\u00ebnave, login, password. Ne largohemi nga ai zhurm\u00eb emrash dhe konflikteje n\u00eb skedaret e konfigurimit, t\u00eb cilat 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 dalloj\u00eb nga ai i parazgjedhur. MySQL, si standard, \u00ebsht\u00eb i konfiguruar 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 interpreterit Python, Ruby, NodeJS, PHP t\u00eb versionit t\u00eb d\u00ebshiruar. Ne i shp\u00ebtojm\u00eb nevoj\u00ebs p\u00ebr t\u00eb p\u00ebrdorur ndonj\u00eb menaxher versionesh. M\u00eb par\u00eb p\u00ebrdornim nj\u00eb paket\u00eb rpm p\u00ebr Ruby, e cila lejonte nd\u00ebrrimin e versionit n\u00eb var\u00ebsi t\u00eb projektit. Kjo gjithashtu mund\u00ebson, fal\u00eb kontejnerit Docker, t\u00eb migrimin e kodit dhe versionimin e tij s\u00eb bashku me var\u00ebsit\u00eb. Nuk kemi problem t\u00eb kuptojm\u00eb versionin e si interpreterit, ashtu edhe t\u00eb kodit. P\u00ebr t\u00eb p\u00ebrdit\u00ebsuar versionin, duhet t\u00eb mbyllim kontejnerin e vjet\u00ebr dhe t\u00eb ngrem\u00eb nj\u00eb kontejner t\u00eb ri. N\u00ebse di\u00e7ka shkon keq, mund t\u00eb mbyllim 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 t\u00eb nj\u00ebjt\u00eb. Kjo \u00ebsht\u00eb ve\u00e7an\u00ebrisht e r\u00ebnd\u00ebsishme p\u00ebr instalime t\u00eb 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>Aktualisht projekti yn\u00eb m\u00eb i fundit \u00ebsht\u00eb n\u00eb ReactJS. Zhvilluesi nisi t\u00eb gjitha kontejner\u00ebt dhe zhvilloi duke p\u00ebrdorur hot-reload.<\/p>\n<p><\/p>\n<p>M\u00eb pas, fillon detyra p\u00ebr nd\u00ebrtimin e JavaScript dhe kodi, i nd\u00ebrtuar n\u00eb statik\u00eb, jepet p\u00ebrmes nginx duke kursyer burime.<\/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 paraqitur skem\u00ebn e projektit ton\u00eb m\u00eb t\u00eb fundit.<\/p>\n<p><\/p>\n<p>Cilat probleme zgjidh\u00ebm? Na duhej t\u00eb ndihmonim n\u00eb nd\u00ebrtimin e nj\u00eb sistemi me t\u00eb cilin nd\u00ebrveprojn\u00eb 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 ndam\u00eb aplikacionin n\u00eb komponente t\u00eb tilla si: pjesa administrative n\u00eb JS, backend q\u00eb punon p\u00ebrmes nj\u00eb nd\u00ebrfaqe REST n\u00ebn Ruby on Rails. Backend nd\u00ebrvepron me baz\u00ebn e t\u00eb dh\u00ebnave. Rezultati, q\u00eb gjenerohet jepet klientit. Adminja nd\u00ebrvepron me backend dhe baz\u00ebn e t\u00eb dh\u00ebnave p\u00ebrmes nd\u00ebrfaqes REST.<\/p>\n<p><\/p>\n<p>Gjithashtu na duhej t\u00eb d\u00ebrgonim njoftime push. Para k\u00ebsaj pat\u00ebm nj\u00eb projekt, n\u00eb t\u00eb cilin ishte zbatua nj\u00eb mekaniz\u00ebm q\u00eb ishte p\u00ebrgjegj\u00ebs p\u00ebr dor\u00ebzimin e njoftimeve n\u00eb platformat mobile. <\/p>\n<p><\/p>\n<p>Ne zhvilluam nj\u00eb skem\u00eb t\u00eb till\u00eb: operatori nga shfletuesi interakton me adminin, admini interakton me backend, vendoset detyra se duhet t\u00eb d\u00ebrgojm\u00eb njoftime push.<\/p>\n<p><\/p>\n<p>Njoftimet push nd\u00ebrveprojn\u00eb me nj\u00eb komponent tjet\u00ebr, i cili \u00ebsht\u00eb i implementuar n\u00eb NodeJS.<\/p>\n<p><\/p>\n<p>K\u00ebtu ndodhen radh\u00ebt dhe m\u00eb pas vazhdon mekanizmi i d\u00ebrgimit t\u00eb njoftimeve.<\/p>\n<p><\/p>\n<p>K\u00ebtu jan\u00eb vizatuar dy baza t\u00eb dh\u00ebnash. Momentin aktual, ne po p\u00ebrdorim me an\u00eb t\u00eb Docker dy baza t\u00eb dh\u00ebnash t\u00eb pavarura, t\u00eb cilat nuk jan\u00eb 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 fizike 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 ri-p\u00ebrdorimi i kodit.<\/p>\n<p><\/p>\n<p>N\u00ebse m\u00eb par\u00eb fol\u00ebm p\u00ebr ri-p\u00ebrdorimin e kodit n\u00eb form\u00ebn e bibliotekave, n\u00eb k\u00ebt\u00eb shembull sh\u00ebrbimi yn\u00eb q\u00eb menaxhon njoftimet Push ri-p\u00ebrdoret si nj\u00eb server i plot\u00eb. Ai ofron nj\u00eb API. Nd\u00ebrsa me t\u00eb nd\u00ebrveprohet zhvillimi yn\u00eb i ri.<\/p>\n<p><\/p>\n<p>N\u00eb at\u00eb koh\u00eb ne p\u00ebrdornim versionin 4 t\u00eb NodeJS. Aktualisht (n\u00eb vitin 2017 - sh\u00ebnimi i redaktorit) n\u00eb zhvillimet e reja p\u00ebrdorim versionin 7 t\u00eb NodeJS. Nuk ka probleme t\u00eb attrahojm\u00eb versione t\u00eb reja bibliotekash n\u00eb komponent\u00ebt e rinj. <\/p>\n<p><\/p>\n<p>N\u00ebse \u00ebsht\u00eb e nevojshme, mund t\u00eb kryejm\u00eb refaktorim dhe t\u00eb rrisim versionin e NodeJS p\u00ebr sh\u00ebrbimin e njoftimeve Push. <\/p>\n<p><\/p>\n<p>Dhe n\u00ebse arrijm\u00eb t\u00eb ruajm\u00eb kompatibilitetin n\u00eb API, at\u00ebher\u00eb do t\u00eb mund ta z\u00ebvend\u00ebsojm\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\u00ebRepository Dockerfile, i cili p\u00ebrshkruan var\u00ebsit\u00eb e nevojshme. N\u00eb k\u00ebt\u00eb shembull komponent\u00ebt jan\u00eb t\u00eb ndar\u00eb sipas logjik\u00ebs. Ky \u00ebsht\u00eb nj\u00eb set minimal p\u00ebr zhvilluesin backend.<\/p>\n<p><\/p>\n<p>Kur krijojm\u00eb nj\u00eb projekt t\u00eb ri, krijojm\u00eb Dockerfile, p\u00ebrshkruajm\u00eb ekosistemin e nevojshme (Python, Ruby, NodeJS). N\u00eb docker-compose p\u00ebrshkruajm\u00eb var\u00ebsit\u00eb e nevojshme - baz\u00ebn e t\u00eb dh\u00ebnave. P\u00ebrcaktojm\u00eb se na nevojitet nj\u00eb baz\u00eb e caktuar versioni, p\u00ebr t\u00eb ruajtur t\u00eb dh\u00ebnat atje ku duhet.<\/p>\n<p><\/p>\n<p>Ne p\u00ebrdorim nj\u00eb kontejner t\u00eb tret\u00eb t\u00eb ve\u00e7ant\u00eb me nginx p\u00ebr ofrimin e statik\u00ebs. \u00cbsht\u00eb parashikuar mund\u00ebsia e ngarkimit t\u00eb imazheve. Backend i vendos ato n\u00eb nj\u00eb volum t\u00eb p\u00ebrgatitur m\u00eb par\u00eb, i cili gjithashtu \u00ebsht\u00eb montuar n\u00eb kontejnerin me nginx, i cili ofron statikat.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb ruajtur konfigurimin e nginx dhe mysql, ne kemi shtuar nj\u00eb dosje Docker, n\u00eb t\u00eb cil\u00ebn ruajm\u00eb konfiguratat e nevojshme. Kur zhvilluesi b\u00ebn git clone t\u00eb repository-t n\u00eb makin\u00ebn e tij, ai merr nj\u00eb projekt tashm\u00eb t\u00eb p\u00ebrgatitur p\u00ebr zhvillimin lokal. Nuk lind problemi 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 pas ne kemi disa komponent\u00eb: admin, inform-API, njoftime push.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb nisur gjith\u00e7ka, ne krijuam nj\u00eb depo t\u00eb re, t\u00eb cil\u00ebn e quajt\u00ebm dockerized-app. N\u00eb momentin aktual, ne po p\u00ebrdorim disa depo p\u00ebr \u00e7do komponent. Ato dallohen thjesht logjikisht \u2014 n\u00eb GitLab duket si nj\u00eb dosje, nd\u00ebrsa n\u00eb kompjuterin e zhvilluesit \u00ebsht\u00eb nj\u00eb dosje p\u00ebr projektin specifik. N\u00ebn nivelin e saj gjenden komponent\u00ebt q\u00eb do t\u00eb bashkohen.<\/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 gjithashtu e nxjerrim k\u00ebtu katalogun Docker, ku plot\u00ebsojm\u00eb konfigurimet e nevojshme p\u00ebr nd\u00ebrveprimet e t\u00eb gjitha komponent\u00ebve. Ka nj\u00eb README.md, ku p\u00ebrshkruhet shkurtimisht se si t\u00eb nisni projektin.<\/p>\n<p><\/p>\n<p>K\u00ebtu ne aplikojm\u00eb dy skeda docker-compose. Kjo \u00ebsht\u00eb b\u00ebr\u00eb p\u00ebr t\u00eb pasur mund\u00ebsin\u00eb e nisjes hap pas hapi. Kur zhvilluesi punon me b\u00ebrtham\u00ebn, nuk i nevojiten njoftimet Push, k\u00ebshtu q\u00eb ai thjesht nis sked\u00ebn docker-compose dhe p\u00ebr rrjedhoj\u00eb resurset ekonomizohen.<\/p>\n<p><\/p>\n<p>N\u00ebse ka nevoj\u00eb p\u00ebr integrim me njoftimet Push, at\u00ebher\u00eb niset 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 dosje, krijohet automatikisht nj\u00eb rrjet virtual i nj\u00ebjt\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\/535019c82c72c1602176fbaf4aa5640f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00ebrshkrimi i komponent\u00ebve. Ky \u00ebsht\u00eb nj\u00eb sked\u00eb m\u00eb e zgjatur, e cila p\u00ebrgjigjet p\u00ebr nd\u00ebrtimin e komponent\u00ebve. \u00c7far\u00eb \u00ebsht\u00eb e r\u00ebnd\u00ebsishme k\u00ebtu? K\u00ebtu ne prezantojm\u00eb komponentin balancues.<\/p>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb imazh i gatsh\u00ebm Docker, n\u00eb t\u00eb cilin niset nginx dhe aplikacioni q\u00eb d\u00ebgjon socket-in Docker. Dinamikisht, me aktivizimin dhe \u00e7aktivizimin e kontejner\u00ebve, rigjeneron konfigurimin nginx. Nd\u00ebrveprimet me komponent\u00ebt i ndajm\u00eb sipas emrave t\u00eb domain-it t\u00eb tret\u00eb.<\/p>\n<p><\/p>\n<p>P\u00ebr ambientin e zhvillimit p\u00ebrdorim domenin .dev \u2014 api.informer.dev. Aplikacionet me domenin .dev jan\u00eb t\u00eb aksesueshme n\u00eb kompjuterin lokal t\u00eb zhvilluesit.<\/p>\n<p><\/p>\n<p>Pastaj, konfigurimet kalojn\u00eb p\u00ebr \u00e7do projekt dhe t\u00eb gjitha projektet nisen s\u00eb bashku 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 ilustrojm\u00eb n\u00eb m\u00ebnyr\u00eb grafike, at\u00ebher\u00eb klienti \u00ebsht\u00eb shfletuesi yn\u00eb ose ndonj\u00eb mjet me t\u00eb cilin b\u00ebjm\u00eb k\u00ebrkesa te balancuesi.<\/p>\n<p><\/p>\n<p>Balancuesi p\u00ebrcakton n\u00ebp\u00ebrmjet emrit t\u00eb domain-it se cilit kontejner duhet t'i drejtohet.<\/p>\n<p><\/p>\n<p>Ky mund t\u00eb jet\u00eb nginx, q\u00eb jep JS t\u00eb admin\u00ebve. Ky mund t\u00eb jet\u00eb nginx, q\u00eb jep API-n\u00eb ose skedar\u00ebt statik\u00eb, q\u00eb jepen nga nginx si ngarkes\u00eb imazhesh.<\/p>\n<p><\/p>\n<p>N\u00eb diagram shikohet se kontejner\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\u00eb e zhvilluesit, mund t\u00eb qaseni n\u00eb kontejner duke e ditur IP-n\u00eb, por n\u00eb parim nuk e p\u00ebrdorim k\u00ebt\u00eb. D nearly necessiteti i qasjes direkte nuk lind praktikisht.<\/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>Cili \u00ebsht\u00eb nj\u00eb shembull q\u00eb mund t\u00eb shihni p\u00ebr t\u00eb dockerizuar aplikacionin tuaj? N\u00eb mendimin tim, nj\u00eb shembull i mir\u00eb \u00ebsht\u00eb imazhi zyrtar i docker p\u00ebr MySQL.<\/p>\n<p><\/p>\n<p>Ai \u00ebsht\u00eb mjaft kompleks. Ka shum\u00eb versione. Por funksionaliteti i tij mund t\u00eb mbuloj\u00eb shum\u00eb nevoja q\u00eb mund t\u00eb lindin gjat\u00eb zhvillimit t\u00eb m\u00ebtejsh\u00ebm. N\u00ebse shpenzoni koh\u00eb dhe kuptoni sesi t\u00eb gjitha k\u00ebto bashk\u00ebveprojn\u00eb, mendoj se nuk do t\u00eb keni probleme me implementimin e vet\u00eb.<\/p>\n<p><\/p>\n<p>N\u00eb hub.docker.com zakonisht ka lidhje me github.com, ku jan\u00eb t\u00eb dh\u00ebna t\u00eb 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 nj\u00eb skenar docker-endpoint.sh, q\u00eb \u00ebsht\u00eb p\u00ebrgjegj\u00ebs p\u00ebr inicializimin e par\u00eb dhe p\u00ebr p\u00ebrpunimin e m\u00ebtejsh\u00ebm t\u00eb nisjes s\u00eb aplikacionit.<\/p>\n<p><\/p>\n<p>Gjithashtu, n\u00eb k\u00ebt\u00eb shembull ka mund\u00ebsi konfigurimi p\u00ebrmes variablave t\u00eb ambientit. Duke p\u00ebrcaktuar variabl\u00ebn e ambientit n\u00eb nisjen e nj\u00eb kontejneri t\u00eb vet\u00ebm ose p\u00ebrmes docker-compose, mund t\u00eb themi se na nevojitet t\u00eb vendosim nj\u00eb fjal\u00ebkalim t\u00eb zbraz\u00ebt p\u00ebr root n\u00eb MySQL, ose nj\u00eb tjet\u00ebr q\u00eb ne duam.<\/p>\n<p><\/p>\n<p>Ka mund\u00ebsi p\u00ebr t\u00eb krijuar nj\u00eb fjal\u00ebkalim rast\u00ebsor. Ne themi se na nevojitet nj\u00eb p\u00ebrdorues, duhet t\u00eb vendosim nj\u00eb fjal\u00ebkalim p\u00ebr p\u00ebrdoruesin dhe duhet t\u00eb krijojm\u00eb nj\u00eb baz\u00eb t\u00eb dh\u00ebnash.<\/p>\n<p><\/p>\n<p>N\u00eb projektet tona kemi paksa unifikuar Dockerfile-in, i cili \u00ebsht\u00eb p\u00ebrgjegj\u00ebs p\u00ebr inicializimin. Atje kemi b\u00ebr\u00eb disa ndryshime sipas nevojave tona p\u00ebr t\u00eb thjeshtuar zgjerimin e t\u00eb drejtave t\u00eb p\u00ebrdoruesit q\u00eb p\u00ebrdoret nga aplikacioni. Kjo na ka lejuar m\u00eb pas t\u00eb krijojm\u00eb thjesht nj\u00eb baz\u00eb t\u00eb dh\u00ebnash nga konsola e aplikacionit. N\u00eb aplikacionet Ruby ka komand\u00eb p\u00ebr krijimin, ndryshimin dhe fshirjen e bazave t\u00eb t\u00eb dh\u00ebnave.<\/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 i asaj si duket nj\u00eb version specifik i MySQL n\u00eb github.com. Mund ta hapni Dockerfile-in dhe t\u00eb shihni se si ndodh instalimi.<\/p>\n<p><\/p>\n<p>docker-endpoint.sh \u00ebsht\u00eb skenari p\u00ebrgjegj\u00ebs p\u00ebr pik\u00ebn e hyrjes. Gjat\u00eb inicializimit t\u00eb par\u00eb k\u00ebrkohen disa veprime p\u00ebrgatitore dhe t\u00eb gjitha k\u00ebto veprime jan\u00eb hequr n\u00eb skenarin 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>Kalojm\u00eb n\u00eb pjes\u00ebn e dyt\u00eb.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb ruajtur kodin burimor, kemi kaluar n\u00eb gitlab. Kjo \u00ebsht\u00eb nj\u00eb sistem mjaft i fuqish\u00ebm, i cili ka nj\u00eb nd\u00ebrfaqe vizuale.<\/p>\n<p><\/p>\n<p>Nj\u00eb nga komponent\u00ebt e Gitlab \u00ebsht\u00eb Gitlab CI. Ai lejon p\u00ebrshkrimin e nj\u00eb serie komandash, t\u00eb cilat m\u00eb von\u00eb do t\u00eb p\u00ebrdoren p\u00ebr t\u00eb organizuar sistemin e dor\u00ebzimit t\u00eb kodit ose p\u00ebr t\u00eb nisur testimin automatizuar.<\/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 mjaft i detajuar dhe ndoshta do t'ju interesoje.<\/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 shohim \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 duam t\u00eb ekzekutojm\u00eb si nj\u00eb seri gjendjesh, si teste, d\u00ebrgime.<\/p>\n<p><\/p>\n<p>Ekzekutojm\u00eb skriptet q\u00eb th\u00ebrrasin ndryshe nd\u00ebrtimin e aplikacionit ton\u00eb me docker-compose. Ky \u00ebsht\u00eb nj\u00eb shembull i backend.<\/p>\n<p><\/p>\n<p>Pastaj themi se duhet t\u00eb kalojm\u00eb migrimet p\u00ebr ndryshimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe t\u00eb zbatojm\u00eb testet.<\/p>\n<p><\/p>\n<p>N\u00ebse skriptet ekzekutohen sakt\u00eb dhe nuk kthejn\u00eb kod gabimi, at\u00ebher\u00eb sistemi kalon n\u00eb faz\u00ebn e dyt\u00eb t\u00eb d\u00ebrgimit.<\/p>\n<p><\/p>\n<p>Faza e d\u00ebrgimit aktualisht \u00ebsht\u00eb e realizuar p\u00ebr staging. Nuk e kemi organizuar rind\u00ebrtimin pa downtime.<\/p>\n<p><\/p>\n<p>Ne mbyllim me forc\u00eb t\u00eb gjitha kontejner\u00ebt, dhe pastaj i ngrem\u00eb s\u00ebrish t\u00eb gjitha kontejner\u00ebt, t\u00eb nd\u00ebrtuar n\u00eb faz\u00ebn e par\u00eb gjat\u00eb testimit.<\/p>\n<p><\/p>\n<p>Kalon tashm\u00eb migrimet e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave p\u00ebr ambientin aktual t\u00eb ndryshuesh\u00ebm, t\u00eb cilat jan\u00eb shkruar 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>Kur ndryshohen deg\u00eb t\u00eb tjera, nuk ekzekutohet.<\/p>\n<p><\/p>\n<p>Ka mund\u00ebsin\u00eb p\u00ebr t\u00eb organizuar p\u00ebrvidh\u00eb n\u00ebp\u00ebr deg\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\/8a5b880bd9a0d4bab0b276568e2ba413.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00ebr ta organizuar m\u00eb tej, na nevojitet t\u00eb instalojm\u00eb Gitlab Runner.<\/p>\n<p><\/p>\n<p>Kjo utilitare \u00ebsht\u00eb e shkruar n\u00eb Golang. Ajo \u00ebsht\u00eb nj\u00eb skedar unik si\u00e7 \u00ebsht\u00eb zakon n\u00eb bot\u00ebn Golang, i cili nuk k\u00ebrkon asnj\u00eb var\u00ebsi.<\/p>\n<p><\/p>\n<p>Kur e nisi, 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 rreshtin e komandave.<\/p>\n<p><\/p>\n<p>Konfigurojm\u00eb Gitlab Runner n\u00eb modalitetin dialog (Shell, Docker, VirtualBox, SSH).<\/p>\n<p><\/p>\n<p>Kodi n\u00eb Gitlab Runner do t\u00eb ekzekutohet me \u00e7do commit n\u00eb var\u00ebsi t\u00eb konfigurimit t\u00eb .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 vizualisht n\u00eb Gitlab n\u00eb nd\u00ebrfaqen web. Pas lidhjes me Gitlab CI, na shfaqet nj\u00eb flamur, i cili tregon n\u00eb \u00e7far\u00eb gjendje ndodhet nd\u00ebrtimi n\u00eb k\u00ebt\u00eb moment.<\/p>\n<p><\/p>\n<p>Ne shohim q\u00eb 4 minuta m\u00eb par\u00eb u b\u00eb nj\u00eb commit, i cili kaloi t\u00eb gjitha testet dhe nuk shkaktoi 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 nd\u00ebrtimet. K\u00ebtu shohim q\u00eb tashm\u00eb jan\u00eb kaluar dy gjendje. Gjendja e testimit dhe gjendja e shp\u00ebrndarjes n\u00eb staging.<\/p>\n<p><\/p>\n<p>N\u00ebse ne klikojm\u00eb n\u00eb nj\u00eb nd\u00ebrtim specifik, atje do t\u00eb ket\u00eb daljen e konsol\u00ebs s\u00eb komandave q\u00eb jan\u00eb ekzekutuar gjat\u00eb procesit 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\u00ebtu gjendet historia e produktit ton\u00eb. Ne shohim q\u00eb ka pasur p\u00ebrpjekje t\u00eb suksesshme. Kur testet d\u00ebshtojn\u00eb, at\u00ebher\u00eb nuk kalon n\u00eb hapin tjet\u00ebr dhe kodi n\u00eb staging nuk p\u00ebrdit\u00ebsohet.<\/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 kishim n\u00eb staging gjat\u00eb implementimit t\u00eb dockerit? Sistemi yn\u00eb p\u00ebrb\u00ebhet nga komponente dhe na duhej t\u00eb ri-fillonim vet\u00ebm pjes\u00ebn e komponenteve q\u00eb ishin p\u00ebrdit\u00ebsuar n\u00eb repository, jo t\u00ebr\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 k\u00ebsaj, shfaqej problemi se Docker-compose krijon p\u00ebr \u00e7do dosje hap\u00ebsir\u00ebn e vet t\u00eb rrjetit dhe nuk shkonte p\u00ebrb\u00ebr\u00ebsit fqinj.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb gjetur nj\u00eb zgjidhje, krijuam nj\u00eb rrjet manualisht n\u00eb Docker. N\u00eb Docker-compose e p\u00ebrshkruam q\u00eb p\u00ebr k\u00ebt\u00eb projekt t\u00eb p\u00ebrdoret ky rrjet.<\/p>\n<p><\/p>\n<p>K\u00ebshtu, \u00e7do komponent q\u00eb fillon me k\u00ebt\u00eb rrjet i sheh komponentet n\u00eb pjes\u00eb t\u00eb tjera t\u00eb sistemit.<\/p>\n<p><\/p>\n<p>Problemi tjet\u00ebr \u2014 \u00ebsht\u00eb ndarja e staging midis disa projekteve.<\/p>\n<p><\/p>\n<p>Sepse 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, q\u00eb p\u00ebrdoret n\u00eb m\u00ebnyr\u00eb universale 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? Ne caktuam nj\u00eb Gitlab Runner p\u00ebr t\u00eb gjitha projektet e m\u00ebdha.<\/p>\n<p><\/p>\n<p>Gitlab lejon t\u00eb nis\u00eb disa Gitlab Runner t\u00eb shp\u00ebrndara, t\u00eb cilat thjesht porositen nd\u00ebrshe n\u00eb rend t\u00eb rast\u00ebsish\u00ebm p\u00ebr t\u00eb marr\u00eb t\u00eb gjitha detyrat dhe p\u00ebr t'i ekzekutuar ato.<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb shmangur kaosin, ne e kufizuam grupin ton\u00eb t\u00eb projekteve n\u00eb nj\u00eb Gitlab Runner, i cili p\u00ebr volumin ton\u00eb e menaxhon pa probleme.<\/p>\n<p><\/p>\n<p>E nxorr\u00ebm nginx-proxy n\u00eb nj\u00eb skenar t\u00eb ve\u00e7ant\u00eb nisjeje dhe n\u00eb t\u00eb p\u00ebrshkruam rrjetet e t\u00eb gjitha projekteve. <\/p>\n<p><\/p>\n<p>Projekti yn\u00eb ka nj\u00eb rrjet, nd\u00ebrsa balancuesi ka disa rrjete sipas emrave t\u00eb projekteve. Ai mund t\u00eb proksi n\u00eb vazhdim\u00ebsi sipas emrave t\u00eb domain-eve.<\/p>\n<p><\/p>\n<p>K\u00ebrkesat tona vijn\u00eb p\u00ebrmes domain-it n\u00eb portin 80 dhe drejtohen n\u00eb grupin e kontejner\u00ebve q\u00eb sh\u00ebrbejn\u00eb p\u00ebr k\u00ebt\u00eb domain.<\/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 se t\u00eb gjitha kontejner\u00ebt n\u00eb m\u00ebnyr\u00eb default ekzekutohen si p\u00ebrdoruesi root. Ky root nuk \u00ebsht\u00eb nj\u00eblloj si root i sistemit host.<\/p>\n<p><\/p>\n<p>Megjithat\u00eb, n\u00ebse hyni n\u00eb kontejner, do t\u00eb jet\u00eb root dhe skedari q\u00eb krijojm\u00eb n\u00eb k\u00ebt\u00eb kontejner ka t\u00eb drejtat root.<\/p>\n<p><\/p>\n<p>N\u00ebse zhvilluesi ka hyr\u00eb n\u00eb kontejner dhe ka b\u00ebr\u00eb disa komanda q\u00eb krijojn\u00eb skedar\u00eb, pastaj del nga kontejneri, ai ka nj\u00eb skedar n\u00eb direktorin\u00eb e tij t\u00eb pun\u00ebs, p\u00ebr t\u00eb cilin nuk ka qasje.<\/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>\u00c7far\u00eb problemesh u paraqit\u00ebn kur shtuam p\u00ebrdoruesin?<\/p>\n<p><\/p>\n<p>Duke krijuar p\u00ebrdorues, shpesh nuk p\u00ebrputhen ID e grupit (UID) dhe ID e p\u00ebrdoruesit (GID).<\/p>\n<p><\/p>\n<p>P\u00ebr t\u00eb zgjidhur k\u00ebt\u00eb problem n\u00eb kontejner, ne p\u00ebrdorim p\u00ebrdorues me ID 1000.<\/p>\n<p><\/p>\n<p>N\u00eb rastin ton\u00eb, kjo p\u00ebrputhet me faktin se praktikisht t\u00eb gjith\u00eb zhvilluesit p\u00ebrdorin OS-n\u00eb Ubuntu. Dhe n\u00eb OS-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 rishikojm\u00eb dokumentacionin p\u00ebr Docker. Projekti po zhvillohet aktivisht, dokumentacioni ndryshon. T\u00eb dh\u00ebnat q\u00eb jan\u00eb marr\u00eb dy-tre muaj m\u00eb par\u00eb, tashm\u00eb po b\u00ebhen gradualisht t\u00eb vjetra. <\/p>\n<p><\/p>\n<p>Disa probleme q\u00eb kemi zgjidhur, \u00ebsht\u00eb shum\u00eb e mundshme q\u00eb tashm\u00eb jan\u00eb zgjidhur me mjete standarde.<\/p>\n<p><\/p>\n<p>Ka aq shum\u00eb d\u00ebshir\u00eb t\u00eb shkojm\u00eb p\u00ebrpara dhe t\u00eb kalojm\u00eb drejtp\u00ebrdrejt n\u00eb orkestrim.<\/p>\n<p><\/p>\n<p>Nj\u00eb nga shembujt \u00ebsht\u00eb mekanizmi i nd\u00ebrtuar n\u00eb Docker i quajtur Docker Swarm, i cili paraqitet nga kutia. D\u00ebshirojm\u00eb t\u00eb fillojm\u00eb di\u00e7ka n\u00eb prodhim n\u00eb baz\u00eb t\u00eb teknologjis\u00eb Docker Swarm.<\/p>\n<p><\/p>\n<p>Krijimi i konteiner\u00ebve e b\u00ebn t\u00eb komplikuar pun\u00ebn me logjet. Aktualisht, logjet jan\u00eb t\u00eb izoluar. Ato jan\u00eb shp\u00ebrndar\u00eb n\u00ebp\u00ebr kontejner\u00eb. Nj\u00eb nga detyrat \u00ebsht\u00eb t\u00eb sigurojm\u00eb qasje t\u00eb leht\u00eb n\u00eb logjet 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.2 - 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.\" \/>\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.2\" \/>\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.\" \/>\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":"Propozoj t\u00eb shqyrtojm\u00eb p\u00ebrkthimin e raportit t\u00eb Aleksand\u00ebr Sigachev nga Inventos \"Procesi i zhvillimit dhe testimit me Docker + Gitlab CI\". Ata q\u00eb sapo fillojn\u00eb t\u00eb implementojn\u00eb procesin e zhvillimit.","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.","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}]}}