{"id":69351,"date":"2020-02-18T14:44:06","date_gmt":"2020-02-18T11:44:06","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker"},"modified":"2020-03-03T16:15:00","modified_gmt":"2020-03-03T13:15:00","slug":"sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","title":{"rendered":"Krijimi i nj\u00eb zinxhiri CI\/CD dhe automatizimi i pun\u00ebs me Docker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Un\u00eb kam shkruar sajtet e mia t\u00eb para n\u00eb fund t\u00eb viteve '90. At\u00ebher\u00eb, ta b\u00ebje ata funksional ishte shum\u00eb e leht\u00eb. Kishte nj\u00eb server Apache n\u00eb ndonj\u00eb host t\u00eb p\u00ebrbashk\u00ebt, n\u00eb t\u00eb cilin mund t\u00eb hyje p\u00ebrmes FTP-s\u00eb, duke shkruar n\u00eb shiritin e shfletuesit di\u00e7ka si <code>ftp:\/\/ftp.example.com<\/code>. Pastaj duhej t\u00eb shtoja emrin dhe fjal\u00ebkalimin dhe t\u00eb ngarkoja skedar\u00ebt n\u00eb server. Ishin koh\u00eb t\u00eb tjera, gjith\u00e7ka ishte m\u00eb e thjesht\u00eb at\u00ebher\u00eb sesa tani.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/488668\/\"><img decoding=\"async\" alt=\"Krijimi i nj\u00eb zinxhiri CI\/CD dhe automatizimi i pun\u00ebs me Docker\" src=\"\/wp-content\/uploads\/2020\/02\/0861cdd82770ef4695ffac7a09777c52.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Q\u00eb nga ajo koh\u00eb, shum\u00eb ka ndryshuar. Saitet jan\u00eb b\u00ebr\u00eb m\u00eb komplekse, dhe para se t\u00eb dilnin n\u00eb produkte, duhen mbledhur. Nj\u00eb server i vetem \u00ebsht\u00eb b\u00ebr\u00eb nj\u00eb num\u00ebr serverash q\u00eb punojn\u00eb pas balancuesve t\u00eb ngarkes\u00ebs, dhe p\u00ebrdorimi i sistemeve t\u00eb kontrollit t\u00eb versioneve \u00ebsht\u00eb b\u00ebr\u00eb di\u00e7ka e zakonshme.<\/p>\n<p>P\u00ebr projektin tim personal, kisha nj\u00eb konfigurim t\u00eb ve\u00e7ant\u00eb. Dija se m\u00eb nevojitej mund\u00ebsia p\u00ebr t\u00eb shp\u00ebrndar\u00eb sajtin n\u00eb prodhim, duke kryer vet\u00ebm nj\u00eb veprim: shkruaj kodin n\u00eb deg\u00ebn <code>master<\/code> n\u00eb GitHub. P\u00ebr m\u00eb tep\u00ebr, dija se p\u00ebr t\u00eb siguruar operimin e aplikacionit tim t\u00eb vog\u00ebl n\u00eb internet, nuk d\u00ebshiroja t\u00eb merresha me menaxhimin e nj\u00eb klasteri t\u00eb madh Kubernetes, t\u00eb p\u00ebrdorja teknologjin\u00eb Docker Swarm, ose t\u00eb mb\u00ebshtesja nj\u00eb park serverash me pod\u00eb, agjent\u00eb dhe \u00e7do lloj nd\u00ebrlikimi tjet\u00ebr. P\u00ebr t\u00eb arritur q\u00ebllimin e thjeshtimit maksimal t\u00eb pun\u00ebs, m\u00eb duhej t\u00eb m\u00ebsoja p\u00ebr CI\/CD.<\/p>\n<p>N\u00ebse keni nj\u00eb projekt t\u00eb vog\u00ebl (n\u00eb k\u00ebt\u00eb rast po flasim p\u00ebr nj\u00eb projekt Node.js) dhe d\u00ebshironi t\u00eb dini se si t\u00eb automatizoni shp\u00ebrndarjen e k\u00ebtij projekti, duke siguruar q\u00eb ajo q\u00eb ndodhet n\u00eb depo, p\u00ebrputhet sakt\u00ebsisht me at\u00eb q\u00eb funksionon n\u00eb prodhim, mendoj se ky artikull mund t'ju interesoj\u00eb.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>K\u00ebrkesat paraprake<\/h2>\n<p>\nPritet q\u00eb lexuesi i k\u00ebtij artikulli t\u00eb ket\u00eb njohuri themelore n\u00eb p\u00ebrdorimin e komandave n\u00eb linj\u00ebn e komand\u00ebs dhe n\u00eb shkruarjen e skriptave Bash. P\u00ebr m\u00eb tep\u00ebr, do t'i nevojiten llogari <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">Travis CI<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<h2>Q\u00ebllimet<\/h2>\n<p>\nNuk do t\u00eb thoja se ky artikull mund t\u00eb quhet pa kushte \"udh\u00ebzues m\u00ebsimor\". Kjo \u00ebsht\u00eb m\u00eb shum\u00eb nj\u00eb dokument n\u00eb t\u00eb cilin p\u00ebrshkruaj at\u00eb q\u00eb kam m\u00ebsuar dhe shpjegoj procesin e pranuesh\u00ebm p\u00ebr testimin dhe shp\u00ebrndarjen e kodit n\u00eb prodhim, i kryer n\u00eb nj\u00eb kalim t\u00eb vet\u00ebm automatizuar.<\/p>\n<p>Ja si ka dal\u00eb n\u00eb fund procesi im i pun\u00ebs.<\/p>\n<p>P\u00ebr kodin e d\u00ebrguar n\u00eb \u00e7do deg\u00eb t\u00eb depozit\u00ebs, p\u00ebrve\u00e7 <code>master<\/code>, kryhen k\u00ebto veprime:<\/p>\n<ul>\n<li>Nis nj\u00eb nd\u00ebrtim t\u00eb projektit n\u00eb Travis CI.<\/li>\n<li>Kryhen t\u00eb gjitha testet modulare, integruese dhe p\u00ebrmes.<\/li>\n<\/ul>\n<p>\nVet\u00ebm p\u00ebr kodin q\u00eb kalon n\u00eb <code>master<\/code>, zbatohet e m\u00ebposhtmja:<\/p>\n<ul>\n<li>\u00c7do gj\u00eb q\u00eb u tha m\u00eb sip\u00ebr, plus\u2026<\/li>\n<li>Nd\u00ebrtimi i imazhit Docker n\u00eb baz\u00eb t\u00eb kodit aktual, konfigurimeve dhe mjedisit.<\/li>\n<li>Vendosja e imazhit n\u00eb Docker Hub.<\/li>\n<li>Lidhja me serverin e prodhimit.<\/li>\n<li>Ngarkimi i imazhit nga Docker Hub n\u00eb server.<\/li>\n<li>Ndalesa e kontejnerit aktual dhe fillimi i nj\u00eb t\u00eb riut, bazuar n\u00eb imazhin e ri.<\/li>\n<\/ul>\n<p>\nN\u00ebse nuk e dini asgj\u00eb p\u00ebr Docker, imazhet dhe kontejner\u00ebt \u2014 mos u shqet\u00ebsoni. Un\u00eb do t\u2019ju tregoj t\u00eb gjitha p\u00ebr k\u00ebt\u00eb.<\/p>\n<h2>\u00c7far\u00eb \u00ebsht\u00eb CI\/CD?<\/h2>\n<p>\nAkrilateria CI\/CD do t\u00eb thot\u00eb \u00abintegrimi i vazhduesh\u00ebm\/komponenti i vazhduesh\u00ebm\u00bb \u2014 \u00abintegrimi i vazhduesh\u00ebm\/vazhdueshm\u00ebri n\u00eb prodhim\u00bb.<\/p>\n<h3>\u258dIntegrimi i vazhduesh\u00ebm<\/h3>\n<p>\nIntegrimi i vazhduesh\u00ebm \u00ebsht\u00eb procesi kur zhvilluesit b\u00ebjn\u00eb komitet n\u00eb depo kryesore t\u00eb kodit burim t\u00eb projektit (zakonisht n\u00eb deg\u00ebn <code>master<\/code>). Gjat\u00eb k\u00ebsaj periudhe, cil\u00ebsia e kodit sigurohet p\u00ebrmes testeve automatike.<\/p>\n<h3>\u258dVazhdueshm\u00ebria n\u00eb prodhim<\/h3>\n<p>\nVazhdueshm\u00ebria n\u00eb prodhim \u00ebsht\u00eb nj\u00eb shp\u00ebrndarje e shpesht\u00eb automatike e kodit n\u00eb prodhim. Pjesa e dyt\u00eb e akrilat\u00ebs CI\/CD shpesh zbulohet si \u00abndarje e vazhdueshme\u00bb. Kjo, n\u00eb p\u00ebrmbledhje, \u00ebsht\u00eb e nj\u00ebjt\u00eb me \u00abvazhdueshm\u00ebrin\u00eb n\u00eb prodhim\u00bb, por \u00abndarja e vazhdueshme\u00bb n\u00ebnkupton nevoj\u00ebn p\u00ebr konfirmimin manual t\u00eb ndryshimeve para se t\u00eb filloj\u00eb procesi i shp\u00ebrndarjes s\u00eb projektit.<\/p>\n<h2>Fillimi i pun\u00ebs<\/h2>\n<p>\nAplikacioni me t\u00eb cilin kam m\u00ebsuar gjith\u00e7ka \u00ebsht\u00eb quajtur <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/taniarascia\/takenote\">TakeNote<\/a><\/noindex>. Ky \u00ebsht\u00eb nj\u00eb projekt web, mbi t\u00eb cilin un\u00eb po punoj, i dedikuar p\u00ebr marrjen e sh\u00ebnimeve. Fillimisht, u p\u00ebrpoqa t\u00eb b\u00ebj nj\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/jamstack.org\/\">projekte JAMStack<\/a><\/noindex>- ose vet\u00ebm nj\u00eb aplikacion frontend pa server, p\u00ebr t\u00eb shfryt\u00ebzuar mund\u00ebsit\u00eb standarde p\u00ebr hostimin dhe shp\u00ebrndarjen e projekteve q\u00eb ofron <noindex><a rel=\"nofollow\" href=\"https:\/\/www.netlify.com\/\">Netlify<\/a><\/noindex>. Nd\u00ebrsa kompleksiteti i aplikacionit rritej, m\u00eb duhej t\u00eb krijoja gjithashtu pjes\u00ebn e tij serverike, e cila n\u00ebnkuptonte q\u00eb do t\u00eb duhej t\u00eb formuloja nj\u00eb strategji t\u00eb vetme p\u00ebr integrimin e automatizuar dhe shp\u00ebrndarjen e automatizuar t\u00eb projektit.<\/p>\n<p>N\u00eb rastin tim, aplikacioni \u00ebsht\u00eb nj\u00eb server Express q\u00eb funksionon n\u00eb ambientin Node.js, i cili sh\u00ebrben nj\u00eb aplikacion React nj\u00eb-faq\u00ebshe dhe mb\u00ebshtet nj\u00eb API t\u00eb sigurt serverik. Kjo arkitektur\u00eb ndjek nj\u00eb strategji q\u00eb mund t\u00eb gjendet n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/www.taniarascia.com\/full-stack-cookies-localstorage-react-express\/\">k\u00ebt\u00eb<\/a><\/noindex> udh\u00ebzues p\u00ebr autentifikimin fullstack.<\/p>\n<p>Diskutova me <noindex><a rel=\"nofollow\" href=\"http:\/\/qualitytesting.tech\/\">tjet\u00ebr<\/a><\/noindex>, i cili \u00ebsht\u00eb nj\u00eb ekspert i automatizimit, dhe e pyesa se \u00e7far\u00eb duhet t\u00eb b\u00ebj q\u00eb gjith\u00e7ka t\u00eb funksionoj\u00eb ashtu si\u00e7 kam nevoj\u00eb. Ai m\u00eb sugjeroi nj\u00eb ide se si duhet t\u00eb duket procesi i automatizuar i pun\u00ebs, i paraqitur n\u00eb seksionin 'Q\u00ebllimet' t\u00eb k\u00ebtij artikulli. D\u00ebshira ime p\u00ebr t\u00eb vendosur q\u00ebllime t\u00eb tilla do t\u00eb thot\u00eb q\u00eb duhet t\u00eb kuptoj si t\u00eb p\u00ebrdor Docker.<\/p>\n<h2>Docker<\/h2>\n<p>\nDocker \u00ebsht\u00eb nj\u00eb mjet q\u00eb, fal\u00eb teknologjis\u00eb s\u00eb kontejnerizimit, lejon q\u00eb t\u00eb shp\u00ebrndahen aplikacione me leht\u00ebsi, si dhe t\u00eb realizohet vendosja dhe ekzekutimi i tyre n\u00eb t\u00eb nj\u00ebjtin mjedis, edhe kur vet\u00eb platforma Docker funksionon n\u00eb mjedise t\u00eb ndryshme. Fillimisht, duhet t\u00eb kem n\u00eb dispozicion mjetet e komand\u00ebs (CLI) t\u00eb Docker-it. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/install\/\">Udh\u00ebzimi<\/a><\/noindex> p\u00ebr instalimin e Docker-it nuk mund t\u00eb quhet shum\u00eb i qart\u00eb dhe i kuptuesh\u00ebm, por prej tij mund t\u00eb m\u00ebsohet se p\u00ebr t\u00eb b\u00ebr\u00eb hapin e par\u00eb t\u00eb instalimit, duhet t\u00eb shkarkohet Docker Desktop (p\u00ebr Mac ose Windows).<\/p>\n<p>Docker Hub \u00ebsht\u00eb p\u00ebraf\u00ebrsisht si <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/\">GitHub<\/a><\/noindex> p\u00ebr depozitat git, ose regjistri <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/\">npm<\/a><\/noindex> p\u00ebr paketat JavaScript. Ky \u00ebsht\u00eb nj\u00eb depo online p\u00ebr imazhet Docker. Docker Desktop lidhet me t\u00eb.<\/p>\n<p>Pra, p\u00ebr t\u00eb filluar pun\u00ebn me Docker, duhet t\u00eb b\u00ebni dy gj\u00ebra:<\/p>\n<ul>\n<li>Instaloni <noindex><a rel=\"nofollow\" href=\"https:\/\/www.docker.com\/get-started\">Docker Desktop<\/a><\/noindex>.<\/li>\n<li>Regjistrohuni n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>\nPas k\u00ebsaj mund t\u00eb kontrolloni funksionimin e Docker CLI, duke ekzekutuar komand\u00ebn e m\u00ebposhtme p\u00ebr t\u00eb verifikuar versionin e Docker-it:<\/p>\n<pre><code class=\"plaintext\">docker -v<\/code><\/pre>\n<p>\nM\u00eb pas, hyni n\u00eb Docker Hub duke futur, kur t\u2019ju k\u00ebrkohet, emrin tuaj t\u00eb p\u00ebrdoruesit dhe fjal\u00ebkalimin:<\/p>\n<pre><code class=\"plaintext\">docker login<\/code><\/pre>\n<p>\nP\u00ebr t\u00eb p\u00ebrdorur Docker, duhet t\u00eb kuptoni konceptet e imazheve dhe kontejner\u00ebve.<\/p>\n<h3>\u258dImazhet<\/h3>\n<p>\nNj\u00eb imazh \u00ebsht\u00eb si nj\u00eb plan q\u00eb p\u00ebrmban udh\u00ebzime p\u00ebr nd\u00ebrtimin e nj\u00eb konteineri. Ky \u00ebsht\u00eb nj\u00eb snapshot i pandryshuesh\u00ebm i sistemit t\u00eb skedar\u00ebve dhe konfigurimeve t\u00eb aplikacionit. Zhvilluesit mund t\u00eb ndajn\u00eb imazhe me leht\u00ebsi.<\/p>\n<pre><code class=\"plaintext\"># \u0412\u044b\u0432\u043e\u0434 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043e\u0431\u0440\u0430\u0437\u0430\u0445\ndocker images<\/code><\/pre>\n<p>\nKjo komand\u00eb do t\u00eb nxjerr\u00eb nj\u00eb tabel\u00eb me k\u00ebt\u00eb titull:<\/p>\n<pre><code class=\"plaintext\">REPOSITORY \u00a0 \u00a0 TAG     IMAGE ID \u00a0 \u00a0 CREATED     SIZE\n---<\/code><\/pre>\n<p>\nM\u00eb pas do t\u00eb shqyrtojm\u00eb disa shembuj komandash n\u00eb t\u00eb nj\u00ebjtin format \u2014 fillimisht vjen komanda me koment, dhe pastaj nj\u00eb shembull t\u00eb asaj q\u00eb ajo mund t\u00eb nxjerr\u00eb.<\/p>\n<h3>\u258dKontejner\u00ebt<\/h3>\n<p>\nKontejneri \u00ebsht\u00eb nj\u00eb paket\u00eb ekzekutuese q\u00eb p\u00ebrmban gjith\u00e7ka t\u00eb nevojshme p\u00ebr t\u00eb ekzekutuar nj\u00eb aplikacion. Aplikacioni n\u00eb k\u00ebt\u00eb qasje do t\u00eb funksionoj\u00eb gjithmon\u00eb n\u00eb t\u00eb nj\u00ebjt\u00ebn m\u00ebnyr\u00eb, pavar\u00ebsisht nga infrastruktura: n\u00eb nj\u00eb mjedis t\u00eb izoluar dhe n\u00eb t\u00eb nj\u00ebjt\u00ebn mjedis. K\u00ebtu flitet p\u00ebr faktin se n\u00eb mjedise t\u00eb ndryshme ekzekutohen instancat e s\u00eb nj\u00ebjt\u00ebs figur\u00eb.<\/p>\n<pre><code class=\"plaintext\"># \u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432\ndocker ps -a\nCONTAINER ID \u00a0 \u00a0 IMAGE     COMMAND \u00a0 \u00a0 CREATED     STATUS     PORTS \u00a0 \u00a0 NAMES\n---<\/code><\/pre>\n<p><\/p>\n<h3>\u258dEtiketat<\/h3>\n<p>\nEtiketa \u00ebsht\u00eb nj\u00eb tregues p\u00ebr nj\u00eb version t\u00eb caktuar t\u00eb figur\u00ebs.<\/p>\n<h3>\u258dShqyrtim i shkurt\u00ebr i komandave Docker<\/h3>\n<p>\nK\u00ebtu \u00ebsht\u00eb nj\u00eb p\u00ebrmbledhje e disa komandave t\u00eb shpeshta t\u00eb Docker.<\/p>\n<p>Ekipa<\/p>\n<p>Konteksti<\/p>\n<p>Veprim<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/build\/\">docker build<\/a><\/noindex><\/p>\n<p>Imazh<\/p>\n<p>Krijimi i figur\u00ebs nga Dockerfile<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/tag\/\">docker tag<\/a><\/noindex><\/p>\n<p>Imazh<\/p>\n<p>Etiketimi i figur\u00ebs<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/images\/\">docker images<\/a><\/noindex><\/p>\n<p>Imazh<\/p>\n<p>Shfaqja e list\u00ebs s\u00eb figurave<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/run\/\">docker run<\/a><\/noindex><\/p>\n<p>Konteineri<\/p>\n<p>Ekzekutimi i kontejnerit t\u00eb bazuar n\u00eb figur\u00eb<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/push\/\">docker push<\/a><\/noindex><\/p>\n<p>Imazh<\/p>\n<p>D\u00ebrgimi i figur\u00ebs n\u00eb regjistrin<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/about:blank\">docker pull<\/a><\/noindex><\/p>\n<p>Imazh<\/p>\n<p>Shkarkimi i figur\u00ebs nga regjistri<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/ps\/\">docker ps<\/a><\/noindex><\/p>\n<p>Konteineri<\/p>\n<p>Shfaqja e list\u00ebs s\u00eb kontejner\u00ebve<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/system_prune\/\">docker system prune<\/a><\/noindex><\/p>\n<p>Figura\/Kontejneri<\/p>\n<p>Fshirja e kontejner\u00ebve dhe figurave t\u00eb pap\u00ebrdorura<\/p>\n<h3>\u258dDossier Dockerfile<\/h3>\n<p>\nUn\u00eb di si t\u00eb ekzekutoj lokalish aplikacionin p\u00ebr prodhim. Kam nj\u00eb konfigurim Webpack, t\u00eb destinuar p\u00ebr krijimin e nj\u00eb aplikacioni t\u00eb gatsh\u00ebm React. M\u00eb tej, kam nj\u00eb komand\u00eb q\u00eb ekzekuton nj\u00eb server t\u00eb bazuar n\u00eb Node.js, n\u00eb portin <code>5000<\/code>. Duket k\u00ebshtu:<\/p>\n<pre><code class=\"plaintext\">npm i        # instalimi i var\u00ebsive\nnpm run build # krijimi i aplikacionit React\nnpm run start # ekzekutimi i serverit Node<\/code><\/pre>\n<p>\nDuhet t\u00eb theksohet se nuk kam nj\u00eb aplikacion-shembull p\u00ebr k\u00ebt\u00eb material. Por, k\u00ebtu, p\u00ebr eksperimente, do t\u00eb shkonte \u00e7do aplikacion t\u00eb thjesht\u00eb Node.<\/p>\n<p>P\u00ebr t\u00eb p\u00ebrdorur kontejnerin, do t'ju duhet t\u00eb jepni instrukcione Docker. Kjo b\u00ebhet p\u00ebrmes nj\u00eb dosje t\u00eb quajtur <code>Dockerfile<\/code>, e cila ndodhet n\u00eb direktorin\u00eb themelore t\u00eb projektit. Kjo dosje, n\u00eb fillim, duket mjaft e paqart\u00eb.<\/p>\n<p>Por ajo q\u00eb p\u00ebrmban, thjesht p\u00ebrshkruan, me komandat e ve\u00e7anta, di\u00e7ka t\u00eb ngjashme me konfigurimin e mjedisit t\u00eb pun\u00ebs. Ja disa nga k\u00ebto komanda:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#from\">FROM<\/a><\/noindex> \u2014 Kjo komand\u00eb fillon dosjen. N\u00eb t\u00eb specifikohet figura baz\u00eb, mbi t\u00eb cil\u00ebn nd\u00ebrtohet kontejneri.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#copy\">COPY<\/a><\/noindex> \u2014 Kopjimi i skedave nga burimi lokal n\u00eb kontejner.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#workdir\">WORKDIR<\/a><\/noindex> \u2014 Caktimi i direktorive t\u00eb pun\u00ebs p\u00ebr komandat e m\u00ebpasshme.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#run\">RUN<\/a><\/noindex> \u2014 Ekzekutimi i komandave.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#expose\">EXPOSE<\/a><\/noindex> \u2014 Caktimi i portit.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#entrypoint\">ENTRYPOINT<\/a><\/noindex> \u2014 Specifikimi i komand\u00ebs q\u00eb do t\u00eb ekzekutohet.<\/li>\n<\/ul>\n<p>\n<code>Dockerfile<\/code> mund t\u00eb duket n\u00eb k\u00ebt\u00eb m\u00ebnyr\u00eb:<\/p>\n<pre><code class=\"plaintext\"># \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437\nFROM node:12-alpine\n\n# \u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e app\/\nCOPY . app\/\n\n# \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c app\/ \u0432 \u0440\u043e\u043b\u0438 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438\nWORKDIR app\/\n\n# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 (\u043a\u043e\u043c\u0430\u043d\u0434\u0430 npm ci \u043f\u043e\u0445\u043e\u0436\u0430 npm i, \u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043e\u043a)\nRUN npm ci --only-production\n\n# \u0421\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d\u0430\nRUN npm run build\n\n# \u041f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442\nEXPOSE 5000\n\n# \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Node-\u0441\u0435\u0440\u0432\u0435\u0440\nENTRYPOINT npm run start<\/code><\/pre>\n<p>\nSipas imazhit t\u00eb baz\u00ebs s\u00eb zgjedhur, mund t'ju nevojiten disa var\u00ebsi t\u00eb tjera. Problemi \u00ebsht\u00eb q\u00eb disa imazhe t\u00eb baz\u00ebs (si Node Alpine Linux) jan\u00eb krijuar p\u00ebr t'u b\u00ebr\u00eb sa m\u00eb kompakte. Si rezultat, mund t\u00eb mungojn\u00eb disa programe n\u00eb t\u00eb cilat ju po mendoni.<\/p>\n<h3>\u258dNd\u00ebrtimi, etiketimi dhe nisja e kontejnerit<\/h3>\n<p>\nNd\u00ebrtimi dhe nisja lokale e kontejnerit \u2014 kjo \u00ebsht\u00eb, pasi t\u00eb kemi <code>Dockerfile<\/code>, detyrat jan\u00eb mjaft t\u00eb thjeshta. Para se ta d\u00ebrgoni imazhin n\u00eb Docker Hub, duhet ta testoni lokalisht.<\/p>\n<h3>\u258dNd\u00ebrtimi<\/h3>\n<p>\nS\u00eb pari, duhet t\u00eb nd\u00ebrtosh <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/build\/\">imazh<\/a><\/noindex>, duke specifikuar emrin, dhe, \u00e7ka nuk \u00ebsht\u00eb e nevojshme, etiket\u00ebn (n\u00ebse nuk jepet etiketa, sistemi automatikisht do t'i caktohet nj\u00eb etiket\u00eb imazhit <code>latest<\/code>).<\/p>\n<pre><code class=\"plaintext\"># \u0421\u0431\u043e\u0440\u043a\u0430 \u043e\u0431\u0440\u0430\u0437\u0430\ndocker build -t &lt;image&gt;:&lt;tag&gt; .<\/code><\/pre>\n<p>\nPas p\u00ebrfundimit t\u00eb k\u00ebsaj komande, mund t\u00eb shikoni se si Docker e kryen nd\u00ebrtimin e imazhit.<\/p>\n<pre><code class=\"plaintext\">D\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb daemon-in Docker \u00a0 2.88MB\nHapi 1\/9 : FROM node:12-alpine\n\u00a0---&gt; ...p\u00ebrfundimi i hapave t\u00eb nd\u00ebrtimit...\nNd\u00ebrtuar me sukses 123456789123\nEtiketuar me sukses &lt;image&gt;:&lt;tag&gt;<\/code><\/pre>\n<p>\nNd\u00ebrtimi mund t\u00eb zgjas\u00eb disa minuta \u2014 gjith\u00e7ka varet nga sa shum\u00eb var\u00ebsi keni. Pas p\u00ebrfundimit t\u00eb nd\u00ebrtimit, mund t\u00eb ekzekutoni komand\u00ebn <code>docker images<\/code> dhe t\u00eb shikoni p\u00ebrshkrimin e imazhit tuaj t\u00eb ri.<\/p>\n<pre><code class=\"plaintext\">REPOSITORY\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 TAG               IMAGE ID\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 CREATED              SIZE\n&lt;image&gt; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 latest            123456789123\u00a0 \u00a0 \u00a0 \u00a0 Para nj\u00eb minute   x.xxGB<\/code><\/pre>\n<p><\/p>\n<h3>\u258dNisja<\/h3>\n<p>\nImazhi \u00ebsht\u00eb krijuar. Kjo do t\u00eb thot\u00eb se mbi t\u00eb mund t\u00eb nisni nj\u00eb kontejner. Sepse un\u00eb dua t\u00eb kem mund\u00ebsin\u00eb t\u00eb qasem n\u00eb aplikacionin q\u00eb punon n\u00eb kontejner n\u00eb adres\u00ebn <code>localhost:5000<\/code>, un\u00eb, n\u00eb an\u00ebn e majt\u00eb t\u00eb \u00e7iftit <code>5000:5000<\/code> n\u00eb komand\u00ebn e ardhshme vendosa <code>5000<\/code>. N\u00eb an\u00ebn e djatht\u00eb ndodhet porta e kontejnerit.<\/p>\n<pre><code class=\"plaintext\"># \u0417\u0430\u043f\u0443\u0441\u043a \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 5000 \u0438 \u043f\u043e\u0440\u0442\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 5000\ndocker run -p 5000:5000 &lt;image&gt;:&lt;tag&gt;<\/code><\/pre>\n<p>\nTani, kur kontejneri \u00ebsht\u00eb krijuar dhe nisur, mund t\u00eb p\u00ebrdorni komand\u00ebn <code>docker ps<\/code> p\u00ebr t\u00eb par\u00eb informacionin mbi k\u00ebt\u00eb kontejner (ose mund t\u00eb p\u00ebrdorni komand\u00ebn <code>docker ps -a<\/code>, e cila tregon informacionin mbi t\u00eb gjith\u00eb kontejner\u00ebt, jo vet\u00ebm ato q\u00eb jan\u00eb duke punuar).<\/p>\n<pre><code class=\"plaintext\">ID i KONTAINERIT        IMAZHI               KOMANDA                     KRIJUAR              STATUS                     PORTAT                     EMRAT\n987654321234                     \"\\\/bin\\\/sh -c 'npm run\u2026\"   6 sekonda m\u00eb par\u00eb        Po 6 sekonda             0.0.0.0:5000-&gt;5000\\\/tcp   stoic_darwin<\/code><\/pre>\n<p>\nN\u00ebse tani kaloni n\u00eb adres\u00ebn <code>localhost:5000<\/code> \u2014 mund t\u00eb shihni faqen e aplikacionit q\u00eb punon, e cila dukej qart\u00eb ashtu si faqja e aplikacionit q\u00eb punon n\u00eb mjedisin e prodhimit.<\/p>\n<h3>\u258dCaktimi i etiket\u00ebs dhe publikimi<\/h3>\n<p>\nP\u00ebr t\u00eb p\u00ebrdorur nj\u00eb nga imazhet e krijuara n\u00eb serverin e prodhimit, na nevojitet q\u00eb t\u00eb kemi mund\u00ebsin\u00eb t\u00eb ngarkojm\u00eb k\u00ebt\u00eb imazh nga Docker Hub. Kjo do t\u00eb thot\u00eb se s\u00eb pari duhet t\u00eb krijojm\u00eb nj\u00eb depo n\u00eb Docker Hub p\u00ebr projektin. Pas k\u00ebsaj, do t\u00eb kemi nj\u00eb vend ku mund ta d\u00ebrgojm\u00eb imazhin. Imazhi duhet t\u00eb rinominohet n\u00eb m\u00ebnyr\u00eb q\u00eb emri t\u00eb filloj\u00eb me emrin ton\u00eb t\u00eb p\u00ebrdoruesit n\u00eb Docker Hub. Pas k\u00ebsaj duhet t\u00eb vij\u00eb emri i depos. N\u00eb fund t\u00eb emrit mund t\u00eb jet\u00eb \u00e7far\u00ebdo etikete. M\u00eb posht\u00eb jepet nj\u00eb shembull i em\u00ebrtes\u00ebs s\u00eb imazheve sipas k\u00ebsaj skeme.<\/p>\n<p>Tani mund t\u00eb nd\u00ebrtojm\u00eb imazhin duke i dh\u00ebn\u00eb atij nj\u00eb em\u00ebr t\u00eb ri dhe t\u00eb ekzekutojm\u00eb komand\u00ebn <code>docker push<\/code> p\u00ebr ta d\u00ebrguar at\u00eb n\u00eb depon Docker Hub.<\/p>\n<pre><code class=\"plaintext\">docker build -t \\\/ : .\ndocker tag \\\/ : \\\/ :latest\ndocker push \\\/ :\n\n# N\u00eb praktik\u00eb, kjo mund t\u00eb duket, p\u00ebr shembull, si m\u00eb posht\u00eb:\ndocker build -t user\\\/app:v1.0.0 .\ndocker tag user\\\/app:v1.0.0 user\\\/app:latest\ndocker push user\\\/app:v1.0.0<\/code><\/pre>\n<p>\nN\u00ebse gj\u00ebrat shkojn\u00eb si\u00e7 duhet, imazhi do t\u00eb jet\u00eb i disponuesh\u00ebm n\u00eb Docker Hub dhe mund t\u00eb ngarkohet leht\u00ebsisht n\u00eb server ose t\u00eb transferohet te zhvilluesit e tjer\u00eb.<\/p>\n<h2>Hapat e ardhsh\u00ebm<\/h2>\n<p>\nDerisa arrit\u00ebm n\u00eb k\u00ebt\u00eb pik\u00eb, ne konfirmuam se aplikacioni, n\u00eb form\u00ebn e nj\u00eb konteineri Docker, funksionon lokal. Ne ngarkuam konteinerin n\u00eb Docker Hub. T\u00eb gjitha k\u00ebto do t\u00eb thot\u00eb se tashm\u00eb kemi b\u00ebr\u00eb nj\u00eb p\u00ebrparim t\u00eb mir\u00eb drejt q\u00ebllimit. Tani duhet t\u00eb zgjidhim dy \u00e7\u00ebshtje t\u00eb tjera:<\/p>\n<ul>\n<li>Konfigurimi i mjetit CI p\u00ebr testimin dhe zhvillimin e kodit.<\/li>\n<li>Konfigurimi i serverit t\u00eb prodhimit n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb mund t\u00eb ngarkoj\u00eb dhe t\u00eb ekzekutoj\u00eb kodin ton\u00eb.<\/li>\n<\/ul>\n<p>\nN\u00eb rastin ton\u00eb, si zgjidhje CI\/CD p\u00ebrdoret <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">Travis CI<\/a><\/noindex>. Si server \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/\">DigitalOcean<\/a><\/noindex>.<\/p>\n<p>Duhet theksuar se k\u00ebtu mund t\u00eb p\u00ebrdoret edhe nj\u00eb kombinim tjet\u00ebr sh\u00ebrbimesh. P\u00ebr shembull, n\u00eb vend t\u00eb Travis CI, mund t\u00eb p\u00ebrdorni CircleCI ose Github Actions. Nd\u00ebrsa n\u00eb vend t\u00eb DigitalOcean \u2014 AWS ose Linode.<\/p>\n<p>Ne vendos\u00ebm t\u00eb punojm\u00eb me Travis CI, dhe n\u00eb k\u00ebt\u00eb sh\u00ebrbim kam tashm\u00eb disa gj\u00ebra t\u00eb konfigurura. Prandaj tani do t'ju tregoj shkurtimisht se si ta p\u00ebrgatisim p\u00ebr pun\u00eb.<\/p>\n<h2>Travis CI<\/h2>\n<p>\nTravis CI \u00ebsht\u00eb nj\u00eb mjet p\u00ebr testimin dhe zhvillimin e kodit. Nuk do t\u00eb doja t\u00eb hyja n\u00eb holl\u00ebsi rreth konfigurimit t\u00eb Travis CI, pasi \u00e7do projekt \u00ebsht\u00eb unik dhe kjo nuk do t\u00eb sjell\u00eb ndihm\u00eb t\u00eb madhe. Por do t\u00eb flas p\u00ebr bazat q\u00eb do t'ju ndihmojn\u00eb t\u00eb filloni pun\u00ebn n\u00eb rast se vendosni t\u00eb p\u00ebrdorni Travis CI. \u00c7far\u00ebdo q\u00eb t\u00eb zgjidhni \u2014 Travis CI, CircleCI, Jenkins, ose di\u00e7ka tjet\u00ebr, do t\u00eb aplikohen metoda t\u00eb ngjashme konfigurimi.<\/p>\n<p>P\u00ebr t\u00eb filluar pun\u00ebn me Travis CI, shkoni n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">faqja e projektit<\/a><\/noindex> dhe krijoni nj\u00eb llogari. Pastaj integrojeni Travis CI me llogarin\u00eb tuaj GitHub. Gjat\u00eb konfigurimit t\u00eb sistemit, do t'ju duhet t\u00eb specifikoni depozit\u00ebn me t\u00eb cil\u00ebn d\u00ebshironi t\u00eb automatizoni pun\u00ebn, si dhe t\u00eb jepni akses n\u00eb t\u00eb. (Un\u00eb p\u00ebrdor GitHub, por jam e sigurt se Travis CI mund t\u00eb integrohet gjithashtu me BitBucket, GitLab dhe sh\u00ebrbime t\u00eb tjera t\u00eb ngjashme).<\/p>\n<p>\u00c7do her\u00eb q\u00eb Travis CI fillon pun\u00ebn e tij, aktivohet nj\u00eb server q\u00eb ekzekuton komandat e p\u00ebrshkruara n\u00eb skedarin e konfigurimit, duke p\u00ebrfshir\u00eb shp\u00ebrndarjen e deg\u00ebve p\u00ebrkat\u00ebse t\u00eb depozit\u00ebs.<\/p>\n<h3>\u258dCikli i jet\u00ebs s\u00eb detyr\u00ebs<\/h3>\n<p>\nSkedari i konfigurimit t\u00eb Travis CI, i quajtur <code>.travis.yml<\/code> dhe i ruajtur n\u00eb direktorin\u00eb rr\u00ebnj\u00eb t\u00eb projektit, mb\u00ebshtet konceptin e ngjarjeve <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.travis-ci.com\/user\/job-lifecycle\/\">ciklit t\u00eb jet\u00ebs<\/a><\/noindex> t\u00eb detyr\u00ebs. K\u00ebto jan\u00eb ngjarjet, t\u00eb renditura n\u00eb rendin n\u00eb t\u00eb cilin ndodhin:<\/p>\n<ul>\n<li><code>apt addons<\/code><\/li>\n<li><code>cache components<\/code><\/li>\n<li><code>before_install<\/code><\/li>\n<li><code>instalo<\/code><\/li>\n<li><code>before_script<\/code><\/li>\n<li><code>script<\/code><\/li>\n<li><code>before_cache<\/code><\/li>\n<li><code>after_success ose after_failure<\/code><\/li>\n<li><code>before_deploy<\/code><\/li>\n<li><code>deploy<\/code><\/li>\n<li><code>after_deploy<\/code><\/li>\n<li><code>after_script<\/code><\/li>\n<\/ul>\n<p><\/p>\n<h3>\u258dTestimi<\/h3>\n<p>\nN\u00eb skedarin e konfigurimit, un\u00eb do t\u00eb rregulloj nj\u00eb server lokal Travis CI. Si gjuh\u00eb kam zgjedhur Node version 12 dhe i kam treguar sistemit se duhet t\u00eb instalohet var\u00ebsit\u00eb e nevojshme p\u00ebr t\u00eb p\u00ebrdorur Docker.<\/p>\n<p>\u00c7do gj\u00eb q\u00eb \u00ebsht\u00eb e listuar n\u00eb <code>.travis.yml<\/code>, do t\u00eb ekzekutohet kur ekzekutohen t\u00eb gjitha pull request-et n\u00eb t\u00eb gjitha deg\u00ebt e depozit\u00ebs, p\u00ebrve\u00e7 n\u00ebse nuk \u00ebsht\u00eb specifikuar ndryshe. Kjo \u00ebsht\u00eb nj\u00eb ve\u00e7ori e dobishme, pasi do t\u00eb thot\u00eb se mund t\u00eb testojm\u00eb t\u00eb gjith\u00eb kodin q\u00eb hyn n\u00eb depo. Kjo na lejon t\u00eb dim\u00eb n\u00ebse kodi \u00ebsht\u00eb i gatsh\u00ebm p\u00ebr t'u regjistruar n\u00eb deg\u00ebn <code>master<\/code>, dhe nuk do t\u00eb d\u00ebmtoj\u00eb procesin e nd\u00ebrtimit t\u00eb projektit. N\u00eb k\u00ebt\u00eb konfigurim globale, un\u00eb instaloj gjith\u00e7ka lokalisht, aktivizoj serverin e zhvilluesit Webpack n\u00eb sfond (kjo \u00ebsht\u00eb nj\u00eb ve\u00e7ori e procesit tim t\u00eb pun\u00ebs) dhe ekzekutoj testet.<\/p>\n<p>N\u00ebse d\u00ebshironi q\u00eb n\u00eb depozit\u00ebn tuaj t\u00eb shfaqen gjithashtu simbole me informacion mbi mbulimin e kodit me teste, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.taniarascia.com\/display-build-status-and-test-coverage\/\">k\u00ebtu<\/a><\/noindex> mund t\u00eb gjeni nj\u00eb udh\u00ebzues t\u00eb shkurt\u00ebr mbi p\u00ebrdorimin e Jest, Travis CI dhe Coveralls p\u00ebr grumbullimin dhe shfaqjen e k\u00ebtyre informacionit.<\/p>\n<p>Pra, ja p\u00ebrmbajtja e skedarit <code>.travis.yml<\/code>:<\/p>\n<pre><code class=\"plaintext\"># \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u044f\u0437\u044b\u043a\nlanguage: node_js\n\n# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e Node.js\nnode_js:\n\u00a0\u00a0- '12'\n\nservices:\n\u00a0\u00a0# \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 Docker\n\u00a0\u00a0- docker\n\ninstall:\n\u00a0\u00a0# \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\n\u00a0\u00a0- npm ci\n\nbefore_script:\n\u00a0\u00a0# \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\n\u00a0\u00a0- npm run dev &amp;\n\nscript:\n\u00a0\u00a0# \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b\n\u00a0\u00a0- npm run test<\/code><\/pre>\n<p>\nK\u00ebtu p\u00ebrfundojn\u00eb ato veprime q\u00eb ekzekutohen p\u00ebr t\u00eb gjitha deg\u00ebt e depozit\u00ebs dhe p\u00ebr pull request-et.<\/p>\n<h3>\u258dShp\u00ebrndarja<\/h3>\n<p>\nDuke marr\u00eb parasysh supozimin se t\u00eb gjitha testet automatizuese p\u00ebrfunduan me sukses, ne, gj\u00eb q\u00eb nuk \u00ebsht\u00eb e nevojshme, mund t\u00eb shp\u00ebrndajm\u00eb kodin n\u00eb serverin e prodhimit. Q\u00ebllimi yn\u00eb \u00ebsht\u00eb q\u00eb t\u00eb b\u00ebjm\u00eb k\u00ebt\u00eb vet\u00ebm p\u00ebr kodin nga dega <code>master<\/code>, ne japim sistemit udh\u00ebzimet p\u00ebrkat\u00ebse n\u00eb cil\u00ebsimet e implementimit. Para se t\u00eb provoni t\u00eb p\u00ebrdorni n\u00eb projektin tuaj kodin q\u00eb do t\u00eb shqyrtojm\u00eb m\u00eb posht\u00eb, do t\u00eb doja t'ju paralajm\u00ebroja se duhet t\u00eb keni nj\u00eb skritp real q\u00eb thirret p\u00ebr implementim.<\/p>\n<pre><code class=\"plaintext\">deploy:\n\u00a0\u00a0# Nd\u00ebrto konteinerin Docker dhe d\u00ebrgoje at\u00eb n\u00eb Docker Hub\n\u00a0\u00a0provider: script\n\u00a0\u00a0script: bash deploy.sh\n\u00a0\u00a0on:\n\u00a0\u00a0\u00a0\u00a0branch: master<\/code><\/pre>\n<p>\nSkritpi i implementimit zgjidh dy detyra:<\/p>\n<ul>\n<li>Nd\u00ebrtimi, etiketimi dhe d\u00ebrgimi i imazhit n\u00eb Docker Hub me mjetin CI (n\u00eb rastin ton\u00eb \u00ebsht\u00eb Travis CI).<\/li>\n<li>Ngarkimi i imazhit n\u00eb server, ndalimi i konteinerit t\u00eb vjet\u00ebr dhe nisja e t\u00eb riut (n\u00eb rastin ton\u00eb serveri punon n\u00eb platform\u00ebn DigitalOcean).<\/li>\n<\/ul>\n<p>\nS\u00eb pari, duhet t\u00eb konfigurojm\u00eb procesin automatike t\u00eb nd\u00ebrtimit, etiketimit dhe d\u00ebrgimit t\u00eb imazhit n\u00eb Docker Hub. T\u00eb gjitha k\u00ebto jan\u00eb shum\u00eb t\u00eb ngjashme me ato q\u00eb kemi b\u00ebr\u00eb me dor\u00eb, p\u00ebrve\u00e7 se k\u00ebtu na nevojitet nj\u00eb strategji p\u00ebr t\u00eb caktuar etiketat unike p\u00ebr imazhet dhe automatizimi i hyrjes n\u00eb sistem. Kam pasur v\u00ebshtir\u00ebsi me disa detaje t\u00eb skritpit t\u00eb implementimit, si\u00e7 jan\u00eb strategjia e etiketimeve, hyrja n\u00eb sistem, kodimi i \u00e7el\u00ebsave SSH, vendosja e lidhjes SSH. Por, p\u00ebr fat t\u00eb mir\u00eb, i dashuri im \u00ebsht\u00eb shum\u00eb i af\u00ebrt me bash-in, ashtu si me shum\u00eb gj\u00ebra t\u00eb tjera. Ai m\u00eb ndihmoi t\u00eb shkruaj k\u00ebt\u00eb skritp.<\/p>\n<p>Pra, pjesa e par\u00eb e skritpit \u00ebsht\u00eb d\u00ebrgimi i imazhit n\u00eb Docker Hub. Ta b\u00ebsh k\u00ebt\u00eb \u00ebsht\u00eb mjaft e thjesht\u00eb. Schema e etiketimeve q\u00eb kam p\u00ebrdorur parashikon kombinimin e hash-it git dhe etiket\u00ebs git, n\u00ebse ekziston. Kjo siguron krijimin e nj\u00eb etikete unike dhe leht\u00ebson identifikimin e nd\u00ebrtimit nga i cili bazohet. <code>DOCKER_USERNAME<\/code> dhe <code>DOCKER_PASSWORD<\/code> \u2014 jan\u00eb variabla t\u00eb p\u00ebrdoruesve t\u00eb ambientit q\u00eb mund t\u00eb caktohen p\u00ebrmes nd\u00ebrfaqes s\u00eb Travis CI. Travis CI automatikisht do t\u00eb p\u00ebrpunoj\u00eb t\u00eb dh\u00ebnat e ndjeshme n\u00eb m\u00ebnyr\u00eb q\u00eb ato t\u00eb mos bien n\u00eb duar t\u00eb gabuara.<\/p>\n<p>Ja pjesa e par\u00eb e skritpit <code>deploy.sh<\/code>.<\/p>\n<pre><code class=\"plaintext\">#!\/bin\/sh\nset -e # \u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0448\u0438\u0431\u043e\u043a\n\nIMAGE=&quot;&lt;username&gt;\/&lt;repository&gt;&quot; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 # \u041e\u0431\u0440\u0430\u0437 Docker\nGIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-\u0445\u044d\u0448 \u0438 \u0442\u0435\u0433\u0438\n\n# \u0421\u0431\u043e\u0440\u043a\u0430 \u0438 \u0442\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0437\u0430\ndocker build -t ${IMAGE}:${GIT_VERSION} .\ndocker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest\n\n# \u0412\u0445\u043e\u0434 \u0432 Docker Hub \u0438 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0431\u0440\u0430\u0437\u0430\necho &quot;${DOCKER_PASSWORD}&quot; | docker login -u &quot;${DOCKER_USERNAME}&quot; --password-stdin\ndocker push ${IMAGE}:${GIT_VERSION}<\/code><\/pre>\n<p>\nT\u00eb dh\u00ebnat se cila do t\u00eb jet\u00eb pjesa e dyt\u00eb e skritpit, varen krejt\u00ebsisht nga cili host po p\u00ebrdorni dhe se si \u00ebsht\u00eb organizuar lidhja me t\u00eb. N\u00eb rastin tim, pasi po p\u00ebrdor Digital Ocean, komandat q\u00eb p\u00ebrdoren p\u00ebr t'u lidhur me serverin jan\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/digitalocean\/doctl\">doctl<\/a><\/noindex>. Kur punoni me Aws do t\u00eb p\u00ebrdoret utilitar <code>aws<\/code>, e k\u00ebshtu me radh\u00eb.<\/p>\n<p>Konfigurimi i serverit nuk ishte shum\u00eb i komplikuar. K\u00ebshtu, kam konfiguruar nj\u00eb droplet t\u00eb bazuar n\u00eb imazhin baz\u00eb. Duhet t\u00eb theksoj se sistemi q\u00eb kam zgjedhur k\u00ebrkon nj\u00eb instalim manual nj\u00eb her\u00eb t\u00eb Docker-it dhe nj\u00eb aktivizim manual nj\u00eb her\u00eb t\u00eb Docker-it. Un\u00eb p\u00ebrdora Ubuntu 18.04 p\u00ebr t\u00eb instaluar Docker, k\u00ebshtu q\u00eb ju, n\u00ebse gjithashtu p\u00ebrdorni Ubuntu, p\u00ebr t\u00eb b\u00ebr\u00eb t\u00eb nj\u00ebjt\u00ebn gj\u00eb, mund t\u00eb ndiqni <noindex><a rel=\"nofollow\" href=\"https:\/\/phoenixnap.com\/kb\/how-to-install-docker-on-ubuntu-18-04\">k\u00ebt\u00eb<\/a><\/noindex> udh\u00ebzimin e thjesht\u00eb.<\/p>\n<p>Nuk po flas k\u00ebtu p\u00ebr komandat specifike p\u00ebr sh\u00ebrbimin, pasi ky aspekt mund t\u00eb ndryshoj\u00eb shum\u00eb n\u00eb raste t\u00eb ndryshme. Un\u00eb do t\u00eb jap vet\u00ebm nj\u00eb plan t\u00eb p\u00ebrgjithsh\u00ebm t\u00eb veprimeve, t\u00eb kryera pas lidhjes p\u00ebrmes SSH n\u00eb serverin ku do t\u00eb zhvillohet projekti:<\/p>\n<ul>\n<li>Duhet t\u00eb gjeni kontejnerin q\u00eb \u00ebsht\u00eb aktualisht n\u00eb pun\u00eb dhe ta ndaloni at\u00eb.<\/li>\n<li>Pastaj duhet t\u00eb aktivizoni nj\u00eb kontejner t\u00eb ri n\u00eb sfond.<\/li>\n<li>Do t'ju duhet t\u00eb vendosni portin lokal t\u00eb serverit n\u00eb vler\u00ebn <code>80<\/code> \u2014 kjo do t\u00eb lejoj\u00eb hyrjen n\u00eb faqe n\u00eb adres\u00ebn e tipit <code>example.com<\/code>, pa specifikuar portin, dhe jo t\u00eb p\u00ebrdorni adres\u00ebn si <code>example.com:5000<\/code>.<\/li>\n<li>dhe, m\u00eb n\u00eb fund, duhet t\u00eb fshini t\u00eb gjith\u00eb kontejner\u00ebt dhe imazhet e vjetra.<\/li>\n<\/ul>\n<p>\nJa vazhdimi i skriptit.<\/p>\n<pre><code class=\"plaintext\"># \u041d\u0430\u0439\u0442\u0438 ID \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\nCONTAINER_ID=$(docker ps | grep takenote | cut -d&quot; &quot; -f1)\n\n# \u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439, \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443\ndocker stop ${CONTAINER_ID}\ndocker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}\ndocker system prune -a -f<\/code><\/pre>\n<p><\/p>\n<h2>Disa gj\u00ebra p\u00ebr t\u00eb cilat duhet t\u00eb jepni v\u00ebmendje<\/h2>\n<p>\nMund t\u00eb ndodh\u00eb q\u00eb kur t\u00eb lidhemi me serverin p\u00ebrmes SSH nga Travis CI, do t\u00eb shihni nj\u00eb paralajm\u00ebrim q\u00eb nuk do t\u00eb lejoj\u00eb vazhdimin e instalimit, pasi sistemi do t\u00eb pres\u00eb reagimin e p\u00ebrdoruesit.<\/p>\n<pre><code class=\"plaintext\">Autenticiteti i host-it '&lt;hostname&gt; (&lt;IP address&gt;)' nuk mund t\u00eb vendoset.\nShenja e \u00e7el\u00ebsit RSA \u00ebsht\u00eb &lt;key fingerprint&gt;.\nA jeni t\u00eb sigurt se d\u00ebshironi t\u00eb vazhdoni lidhjen (po\/jo)?<\/code><\/pre>\n<p>\nM\u00ebsova se mund t\u00eb kodoj \u00e7el\u00ebsin e vargut n\u00eb base64 p\u00ebr ta ruajtur n\u00eb nj\u00eb form\u00eb q\u00eb mund t\u00eb punojm\u00eb leht\u00ebsisht dhe n\u00eb m\u00ebnyr\u00eb t\u00eb sigurt me t\u00eb. N\u00eb faz\u00ebn e instalimit, mund t\u00eb dekodoj \u00e7el\u00ebsin publik dhe ta ruaj n\u00eb skedarin <code>known_hosts<\/code> p\u00ebr t\u00eb eliminur gabimin e p\u00ebrshkruar m\u00eb sip\u00ebr.<\/p>\n<pre><code class=\"plaintext\">echo &lt;public key&gt; | base64 # shfaq &lt;\u00e7el\u00ebsi publik i koduar n\u00eb base64&gt;<\/code><\/pre>\n<p>\nN\u00eb praktik\u00eb, kjo komand\u00eb mund t\u00eb duket k\u00ebshtu:<\/p>\n<pre><code class=\"plaintext\">echo \"123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom\/BWDSU\nGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3\nPbv7kOdJ\/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK\/7XA\nt3FaoJoAsncM1Q9x5+3V0Ww68\/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw\/Pb0rwert\/En\nmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z\/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx\nNrRFi9wrf+M7Q== you@example.com\" | base64<\/code><\/pre>\n<p>\nJa si duket ajo q\u00eb ajo jep \u2014 nj\u00eb varg n\u00eb kodimin base64:<\/p>\n<pre><code class=\"plaintext\">MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==<\/code><\/pre>\n<p>\nKjo tenho \u00e9 tim 'de simptoma, se qi shum\u00eb, chun mui panasit<\/p>\n<pre><code class=\"plaintext\">installo:\n\u00a0\u00a0- echo  | base64 -d &gt;&gt; $HOME\/.ssh\/known_hosts<\/code><\/pre>\n<p>\nI nj\u00ebjti qasje mund t\u00eb p\u00ebrdoret me \u00e7el\u00ebsin privat kur krijoni lidhjen, pasi p\u00ebr t'u aksesuar serverin ju nevojitet mjaftuesh\u00ebm \u00e7el\u00ebsi privat. Nd\u00ebrsa punoni me \u00e7el\u00ebsin, duhet t\u00eb siguroni ruajtjen e tij t\u00eb sigurt n\u00eb variabl\u00ebn e mjedisit Travis CI, dhe zgjedhjen q\u00eb t\u00eb mos shfaqet askund.<\/p>\n<p>Nj\u00eb gj\u00eb tjet\u00ebr q\u00eb duhet t\u00eb keni parasysh \u00ebsht\u00eb se mund t\u00eb keni nevoj\u00eb t\u00eb ekzekutoni t\u00eb gjith\u00eb skriptin e shp\u00ebrndarjes, i paraqitur si nj\u00eb varg, p\u00ebr shembull \u2014 me ndihm\u00ebn e <code>doctl<\/code>. Kjo mund t\u00eb k\u00ebrkoj\u00eb disa p\u00ebrpjekje shtes\u00eb.<\/p>\n<pre><code class=\"plaintext\">doctl compute ssh  --ssh-command \"t\u00eb gjitha komandat do jen\u00eb k\u00ebtu &amp;&amp; k\u00ebtu\"<\/code><\/pre>\n<p><\/p>\n<h2>TLS\/SSL dhe balancimi i ngarkes\u00ebs<\/h2>\n<p>\nPas asaj q\u00eb b\u00ebra gjith\u00e7ka q\u00eb p\u00ebrmendi m\u00eb sip\u00ebr, problemi i fundit q\u00eb u shfaq ishte se serveri nuk kishte SSL. Duke p\u00ebrdorur serverin Node.js, p\u00ebr t\u00eb b\u00ebr\u00eb q\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-secure-a-containerized-node-js-application-with-nginx-let-s-encrypt-and-docker-compose\">t\u00eb punoj\u00eb<\/a><\/noindex> Nj\u00eb proksi i kthyer Nginx dhe Let\u2019s Encrypt k\u00ebrkon mjaft pun\u00eb.<\/p>\n<p>Nuk doja aspak t\u00eb b\u00ebja t\u00eb gjitha k\u00ebto konfigurime SSL manualisht, k\u00ebshtu q\u00eb thjesht krijova nj\u00eb balancues ngarkesash dhe regjistrova informacionin mbi t\u00eb n\u00eb DNS. N\u00eb rastin e DigitalOcean, p\u00ebr shembull, krijimi i nj\u00eb certifikate t\u00eb vet\u00eb-n\u00ebnshkruar q\u00eb p\u00ebrdit\u00ebsohet automatikisht n\u00eb balancuesin e ngarkesave \u00ebsht\u00eb nj\u00eb procedur\u00eb e thjesht\u00eb, falas dhe e shpejt\u00eb. Ky qasje ka nj\u00eb avantazh shtes\u00eb, q\u00eb \u00ebsht\u00eb se n\u00ebse \u00ebsht\u00eb e nevojshme, lejon t\u00eb konfigurohen shum\u00eb leht\u00eb SSL n\u00eb shum\u00eb servera q\u00eb punojn\u00eb prapa balancuesit t\u00eb ngarkesave. Ky i fundit b\u00ebn q\u00eb serverat t\u00eb mos \"mendojn\u00eb\" p\u00ebr SSL, por t\u00eb p\u00ebrdorin, si zakonisht, portin <code>80<\/code>. Pra, konfigurimi i SSL n\u00eb balancuesin e ngarkesave \u00ebsht\u00eb shum\u00eb m\u00eb i leht\u00eb dhe m\u00eb i p\u00ebrshtatsh\u00ebm se metodat alternative t\u00eb konfigurimit t\u00eb SSL.<\/p>\n<p>Tani \u00ebsht\u00eb e mundur t\u00eb mbyllet n\u00eb server t\u00eb gjitha portet q\u00eb pranojn\u00eb lidhje hyr\u00ebse - p\u00ebrve\u00e7 portit <code>80<\/code>, q\u00eb p\u00ebrdoret p\u00ebr komunikimin me balancuesin e ngarkesave, dhe portin <code>22<\/code> p\u00ebr SSH. Si pasoj\u00eb, p\u00ebrpjekja p\u00ebr t'u qasur drejtp\u00ebrdrejt n\u00eb server n\u00ebp\u00ebrmjet portave t\u00eb tjer\u00eb, p\u00ebrve\u00e7 k\u00ebtyre dyve, do t\u00eb d\u00ebshtoj\u00eb.<\/p>\n<h2>P\u00ebrfundime<\/h2>\n<p>\nPas faktit q\u00eb un\u00eb b\u00ebra gjith\u00e7ka q\u00eb p\u00ebrmenda n\u00eb k\u00ebt\u00eb material, as platforma Docker dhe konceptet e automatizuar t\u00eb CI\/CD nuk m\u00eb frik\u00ebsonin m\u00eb. Arrita t\u00eb konfigur nj\u00eb varg t\u00eb integrimit t\u00eb vazhduesh\u00ebm, gjat\u00eb t\u00eb cilit testimi i kodit p\u00ebrfundohet para se t\u00eb kaloj\u00eb n\u00eb prodhim dhe automatizimi i vendosjes s\u00eb kodit n\u00eb server. Gjith\u00e7ka kjo \u00ebsht\u00eb ende relativisht e re p\u00ebr mua, dhe jam e sigurt se ka m\u00ebnyra p\u00ebr ta p\u00ebrmir\u00ebsuar procesin tim t\u00eb pun\u00ebs automatizuar dhe p\u00ebr ta b\u00ebr\u00eb at\u00eb m\u00eb efikas. Prandaj, n\u00ebse keni ndonj\u00eb ide lidhur me k\u00ebt\u00eb - lajm\u00ebroni. <noindex><a rel=\"nofollow\" href=\"mailto:hello@taniarascia.com\">mua<\/a><\/noindex> Shpresoj se ky artikull ju ndihmoi n\u00eb pun\u00ebt tuaja. Dua t\u00eb besoj se pas leximit t\u00eb tij, keni m\u00ebsuar aq sa m\u00ebsova un\u00eb gjat\u00eb gjith\u00eb procesit me gjith\u00e7ka q\u00eb p\u00ebrshkrova n\u00eb t\u00eb.<\/p>\n<p><b>P.S.<\/b> N\u00eb tonin <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/marketplace#order\">marketin ton\u00eb<\/a><\/noindex> ka nj\u00eb imazh <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/marketplace\/docker#advantages\">Docker<\/a><\/noindex>, i cili instalohet me nj\u00eb klik. Ju mund t\u00eb kontrolloni funksionimin e kontejner\u00ebve n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/\">VPS<\/a><\/noindex>. T\u00eb gjith\u00eb klient\u00ebt e rinj u ofrohen falas 3 dit\u00eb p\u00ebr prov\u00eb.<\/p>\n<p><b>T\u00eb nderuar lexues!<\/b> A p\u00ebrdorni teknologjit\u00eb CI\/CD n\u00eb projektet tuaja?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Krijimi i nj\u00eb zinxhiri CI\/CD dhe automatizimi i pun\u00ebs me Docker\" src=\"\/wp-content\/uploads\/2020\/02\/3fbfa90ea56a3d9b6b89ba945eb94570.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/488668\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430 \u043c\u043e\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 90-\u0445. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u0411\u044b\u043b Apache-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u0449\u0435\u043c \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u043e\u0439\u0442\u0438 \u043f\u043e FTP, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u043d\u0435\u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 ftp:\/\/ftp.example.com. \u041f\u043e\u0442\u043e\u043c \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0438\u043c\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u0438 \u0432\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u0440\u0443\u0433\u0438\u0435 \u0431\u044b\u043b\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0430, \u0432\u0441\u0451 \u0442\u043e\u0433\u0434\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":69352,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-69351","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=\"\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430 \u043c\u043e\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 90-\u0445. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e.\" \/>\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\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker\" \/>\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\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 CI\/CD-\u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Docker | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430 \u043c\u043e\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 90-\u0445. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker\" \/>\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=\"2020-02-18T11:44:06+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:15:00+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\udd47Krijimi i nj\u00eb vargu CI\/CD dhe automatizimi i pun\u00ebs me Docker | ProHoster","description":"Un\u00eb shkrova faqet e mia t\u00eb para n\u00eb fund t\u00eb viteve '90. At\u00ebher\u00eb, duke i \u00e7uar ato n\u00eb gjendje pune ishte shum\u00eb e thjesht\u00eb.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","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\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 CI\/CD-\u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Docker | ProHoster","og:description":"\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430 \u043c\u043e\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0430\u0439\u0442\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 90-\u0445. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","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":"2020-02-18T11:44:06+00:00","article:modified_time":"2020-03-03T13:15:00+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"69351","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:24:45","updated":"2026-08-11 12:50: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\/69351","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=69351"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/69351\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/69352"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=69351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=69351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=69351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}