{"id":81600,"date":"2020-05-15T01:42:41","date_gmt":"2020-05-14T23:42:41","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund"},"modified":"2020-05-15T01:42:41","modified_gmt":"2020-05-14T23:42:41","slug":"neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund","title":{"rendered":"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Para se funksioni t\u00eb arrij\u00eb n\u00eb prodhim, n\u00eb koh\u00ebn ton\u00eb t\u00eb orkestrator\u00ebve kompleks\u00eb dhe CI\/CD, duhet t\u00eb kaloj\u00eb nj\u00eb rrug\u00eb t\u00eb gjat\u00eb nga komiti deri te testimet dhe dor\u00ebzimi. M\u00eb par\u00eb, mund t\u00eb d\u00ebrgohej vet\u00ebm skedar\u00eb t\u00eb rinj p\u00ebrmes FTP (nuk e b\u00ebn m\u00eb askush k\u00ebt\u00eb, t\u00eb v\u00ebrtet\u00eb?), dhe procesi i \"deplojimit\" zgjaste sekonda. Tani, \u00ebsht\u00eb e nevojshme t\u00eb krijosh nj\u00eb k\u00ebrkes\u00eb bashkimi dhe t\u00eb pres\u00ebsh nj\u00eb koh\u00eb t\u00eb konsiderueshme derisa funksioni t\u00eb arrij\u00eb te p\u00ebrdoruesit.<\/p>\n<p><\/p>\n<p>Nj\u00eb pjes\u00eb e k\u00ebsaj rruge \u00ebsht\u00eb nd\u00ebrtimi i imazhit Docker. Ndonj\u00ebher\u00eb, nd\u00ebrtimi zgjat minuta, ndonj\u00ebher\u00eb \u2014 dhjet\u00ebra minuta, gj\u00eb q\u00eb \u00ebsht\u00eb e v\u00ebshtir\u00eb t\u00eb quhet normale. N\u00eb k\u00ebt\u00eb artikull do t\u00eb marrim nj\u00eb aplikacion t\u00eb thjesht\u00eb q\u00eb do ta paketojm\u00eb n\u00eb nj\u00eb imazh, do t\u00eb aplikojm\u00eb disa metoda p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin dhe do t\u00eb shqyrtojm\u00eb nuancat e funksionit t\u00eb k\u00ebtyre metodave.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/7d4775ca1ac64735dfcaba205416da50.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Ne kemi p\u00ebrvoj\u00eb t\u00eb mir\u00eb n\u00eb krijimin dhe mb\u00ebshtetje t\u00eb faqeve t\u00eb lajmeve: <noindex><a rel=\"nofollow\" href=\"https:\/\/tass.ru\/\">\u0422\u0410\u0421\u0421<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/thebell.io\/\">The Bell<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/novayagazeta.ru\/\">&quot;Gazeta N\u00ebn\u00eb Tereza&quot;<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/republic.ru\/\">Republic<\/a><\/noindex>\u2026 Kosha vitin e kaluar e kemi zgjeruar portofolin ton\u00eb duke l\u00ebshuar n\u00eb prodhim faqen <noindex><a rel=\"nofollow\" href=\"https:\/\/reminder.media\">Reminder<\/a><\/noindex>. Dhe derisa punonim shpejt p\u00ebr funksione t\u00eb reja dhe riparimin e defekteve t\u00eb vjetra, nj\u00eb proces i ngadalt\u00eb i deploy-it u b\u00eb nj\u00eb problem i madh.<\/p>\n<p><\/p>\n<p>Ne e b\u00ebjm\u00eb deploy-in n\u00eb GitLab. Ng\u00ebrthejm\u00eb imazhet, i shtyjm\u00eb n\u00eb GitLab Registry dhe i l\u00ebshojm\u00eb n\u00eb prodhim. N\u00eb k\u00ebt\u00eb list\u00eb, gj\u00ebja m\u00eb e gjat\u00eb \u00ebsht\u00eb nd\u00ebrtimi i imazheve. P\u00ebr shembull, pa optimizim \u00e7do nd\u00ebrtim i backend zgjaste 14 minuta.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/043bc8ad67c34e1c7bd705433c5e4e77.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00eb fund, u b\u00eb e qart\u00eb se k\u00ebshtu nuk mund t\u00eb vazhdohet, dhe u ul\u00ebm p\u00ebr t\u00eb kuptuar pse imazhet po nd\u00ebrtohen aq gjat\u00eb. N\u00eb p\u00ebrfundim, arrit\u00ebm ta reduktojm\u00eb koh\u00ebn e nd\u00ebrtimit deri n\u00eb 30 sekonda!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/d035eb1c7b95e0345a110ee59f472693.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00ebr k\u00ebt\u00eb artikull, p\u00ebr ta b\u00ebr\u00eb m\u00eb t\u00eb thjesht\u00eb, do t\u00eb shikojm\u00eb shembujt e nd\u00ebrtimit t\u00eb nj\u00eb aplikacioni t\u00eb pap\u00ebrfunduar n\u00eb Angular. Pra, le t\u00eb krijojm\u00eb aplikacionin ton\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">ng n app<\/code><\/pre>\n<p><\/p>\n<p>E shtojm\u00eb PWA (ne jemi progresiv\u00eb):<\/p>\n<p><\/p>\n<pre><code class=\"bash\">ng add @angular\/pwa --project app<\/code><\/pre>\n<p><\/p>\n<p>Nd\u00ebrsa shkarkohen miliona paketa npm, le t\u00eb kuptojm\u00eb se si \u00ebsht\u00eb organizuar imazhi docker. Docker ofron mund\u00ebsin\u00eb p\u00ebr t\u00eb paketuar aplikacione dhe p\u00ebr t'i ekzekutuar ato n\u00eb nj\u00eb ambient t\u00eb izoluar, i njohur si kontejner. Fal\u00eb izolimit, \u00ebsht\u00eb e mundur t\u00eb ekzekutohen shum\u00eb kontejner\u00eb nj\u00ebkoh\u00ebsisht n\u00eb nj\u00eb server. Kontejner\u00ebt jan\u00eb ndjesh\u00ebm m\u00eb t\u00eb leht\u00eb se makinat virtuale, pasi ata ekzekutohen drejtp\u00ebrdrejt mbi b\u00ebrtham\u00ebn e sistemit. P\u00ebr t\u00eb ekzekutuar nj\u00eb kontejner me aplikacionin ton\u00eb, fillimisht duhet t\u00eb krijojm\u00eb nj\u00eb imazh, ku do t\u00eb paketojm\u00eb gjith\u00e7ka q\u00eb \u00ebsht\u00eb e nevojshme p\u00ebr funksionimin e aplikacionit ton\u00eb. N\u00eb thelb, imazhi \u00ebsht\u00eb nj\u00eb kopje e sistemit t\u00eb skedar\u00ebve. P\u00ebr shembull, le t\u00eb marrim Dockerfile:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM node:12.16.2\nWORKDIR \/app\nCOPY . .\nRUN npm ci\nRUN npm run build --prod<\/code><\/pre>\n<p><\/p>\n<p>Dockerfile \u00ebsht\u00eb nj\u00eb grup udh\u00ebzimesh; duke ekzekutuar secil\u00ebn prej tyre, Docker do t\u00eb ruaj\u00eb ndryshimet n\u00eb sistemin e skedar\u00ebve dhe do t'i mbivendos\u00eb ato mbi ato t\u00eb m\u00ebparshme. \u00c7do komand\u00eb krijon nj\u00eb shtres\u00eb t\u00eb vet\u00ebn. Dhe imazhi i p\u00ebrfunduar \u00ebsht\u00eb kombinimi i k\u00ebtyre shtresave.<\/p>\n<p><\/p>\n<p>\u00c7far\u00eb \u00ebsht\u00eb e r\u00ebnd\u00ebsishme t\u00eb dihet: Docker mund t\u00eb cache \u00e7do shtres\u00eb. N\u00ebse nuk ka ndryshime q\u00eb nga nd\u00ebrtimi i m\u00ebparsh\u00ebm, Docker do t\u00eb marr\u00eb shtres\u00ebn q\u00eb \u00ebsht\u00eb p\u00ebrgatitur m\u00eb par\u00eb, n\u00eb vend q\u00eb t\u00eb ekzekutoj\u00eb komand\u00ebn. Duke marr\u00eb parasysh se p\u00ebrfitimi kryesor n\u00eb shpejt\u00ebsin\u00eb e nd\u00ebrtimit do t\u00eb jet\u00eb p\u00ebr shkak t\u00eb p\u00ebrdorimit t\u00eb cache-it, n\u00eb matjet e shpejt\u00ebsis\u00eb do t\u00eb p\u00ebrqendrohemi n\u00eb nd\u00ebrtimin e imazhit me cache t\u00eb gatsh\u00ebm. Pra, hapat jan\u00eb:<\/p>\n<p><\/p>\n<ol>\n<li>Fshijm\u00eb imazhet lokal, n\u00eb m\u00ebnyr\u00eb q\u00eb nd\u00ebrtimet e m\u00ebparshme t\u00eb mos ndikojn\u00eb n\u00eb testim.<br \/>\n<code>docker rmi $(docker images -q)<\/code><\/li>\n<li>Ekzekutojm\u00eb nd\u00ebrtimin p\u00ebr her\u00eb t\u00eb par\u00eb.<br \/>\n<code>time docker build -t app .<\/code><\/li>\n<li>Ndryshojm\u00eb skedarin src\/index.html \u2014 simulim i pun\u00ebs s\u00eb programuesit.<\/li>\n<li>Ekzekutojm\u00eb nd\u00ebrtimin p\u00ebr her\u00eb t\u00eb dyt\u00eb.<br \/>\n<code>time docker build -t app .<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>N\u00ebse konfiguroni mjedisin p\u00ebr nd\u00ebrtimin e imazheve si\u00e7 duhet (p\u00ebr k\u00ebt\u00eb do t\u00eb flasim m\u00eb posht\u00eb), Docker n\u00eb fillim do t\u00eb ket\u00eb shum\u00eb cache. Detyra jon\u00eb \u00ebsht\u00eb t\u00eb m\u00ebsojm\u00eb se si t\u00eb p\u00ebrdorim cache-in n\u00eb m\u00ebnyr\u00eb q\u00eb nd\u00ebrtimi t\u00eb kaloj\u00eb sa m\u00eb shpejt. Duke pasur parasysh se ne supozojm\u00eb se nd\u00ebrtimi pa cache ndodh vet\u00ebm nj\u00eb her\u00eb \u2014 hera e par\u00eb \u2014 ndoshta mund ta injorojm\u00eb se sa i ngadalsh\u00ebm ishte ky her\u00eb i par\u00eb. N\u00eb testet, e r\u00ebnd\u00ebsishme \u00ebsht\u00eb nd\u00ebrtimi i dyt\u00eb, kur cache-t jan\u00eb ngrohur dhe ne jemi gati p\u00ebr t\u00eb pjekur tort\u00ebn ton\u00eb. Megjithat\u00eb, disa k\u00ebshilla do t\u00eb ndikojn\u00eb edhe n\u00eb nd\u00ebrtimin e par\u00eb.<\/p>\n<p><\/p>\n<p>V\u00ebm\u00eb Dockerfile, t\u00eb p\u00ebrshkruar m\u00eb sip\u00ebr, n\u00eb dosjen e projektit dhe nis\u00ebm nd\u00ebrtimin. T\u00eb gjitha listimet e dh\u00ebna jan\u00eb shkurtuar p\u00ebr leht\u00ebsim t\u00eb leximit.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nD\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb demonin Docker 409MB\nHapi 1\/5 : FROM node:12.16.2\nStatus: Shkarkuar imazhin m\u00eb t\u00eb ri p\u00ebr node:12.16.2\nHapi 2\/5 : WORKDIR \/app\nHapi 3\/5 : COPY . .\nHapi 4\/5 : RUN npm ci\nu shtuan 1357 paketa n\u00eb 22.47s\nHapi 5\/5 : RUN npm run build --prod\nData: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37581ms\nNd\u00ebrsa u nd\u00ebrtua me sukses c8c279335f46\nNd\u00ebrsa u etiketua me sukses app:latest\n\nreal 5m4.541s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>Ndryshojm\u00eb p\u00ebrmbajtjen e src\/index.html dhe ekzekutojm\u00eb p\u00ebr her\u00eb t\u00eb dyt\u00eb.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nD\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb demonin Docker 409MB\nHapi 1\/5 : FROM node:12.16.2\nHapi 2\/5 : WORKDIR \/app\n ---&gt; Duke p\u00ebrdorur cache\nHapi 3\/5 : COPY . .\nHapi 4\/5 : RUN npm ci\nu shtuan 1357 paketa n\u00eb 22.47s\nHapi 5\/5 : RUN npm run build --prod\nData: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37902ms\nNd\u00ebrsa u nd\u00ebrtua me sukses 79f335df92d3\nNd\u00ebrsa u etiketua me sukses app:latest\n\nreal 3m33.262s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>P\u00ebr t\u00eb par\u00eb n\u00ebse kemi arritur imazhin, ekzekutojm\u00eb komand\u00ebn <code>docker images<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED              SIZE\napp          latest   79f335df92d3   Rreth nj\u00eb minut\u00eb m\u00eb par\u00eb   1.74GB<\/code><\/pre>\n<p><\/p>\n<p>Para se t\u00eb niste nd\u00ebrtimi, Docker merr t\u00eb gjitha skedar\u00ebt n\u00eb kontekstin aktual dhe i d\u00ebrgon demonit t\u00eb vet <code>D\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb demonin Docker 409MB<\/code>. Konteksti p\u00ebr nd\u00ebrtim p\u00ebrcaktohet si argumenti p\u00ebrfundimtar i komand\u00ebs build. N\u00eb rastin ton\u00eb, kjo \u00ebsht\u00eb direktoria aktuale \u2014 \u00ab.\u00bb, \u2014 dhe Docker merr gjith\u00e7ka q\u00eb kemi n\u00eb k\u00ebt\u00eb dosje. 409 MB \u00ebsht\u00eb shum\u00eb: le t\u00eb mendojm\u00eb se si mund ta rregullojm\u00eb k\u00ebt\u00eb.<\/p>\n<p><\/p>\n<h2 id=\"umenshaem-kontekst\">Kemi nevoj\u00eb t\u00eb zvog\u00eblojm\u00eb kontekstin<\/h2>\n<p><\/p>\n<p>P\u00ebr t\u00eb zvog\u00ebluar kontekstin, ka dy mund\u00ebsi. Ose t\u00eb vendosim t\u00eb gjitha skedar\u00ebt e nevojsh\u00ebm p\u00ebr nd\u00ebrtim n\u00eb nj\u00eb dosje t\u00eb ve\u00e7ant\u00eb dhe t\u2019i japim Docker-it kontekstin vet\u00ebm p\u00ebr k\u00ebt\u00eb dosje. Kjo ndonj\u00ebher\u00eb nuk \u00ebsht\u00eb e p\u00ebrshtatshme, k\u00ebshtu q\u00eb \u00ebsht\u00eb e mundur t\u00eb specifikojm\u00eb p\u00ebrjashtime: \u00e7far\u00eb nuk duhet t\u00eb merret n\u00eb kontekst. P\u00ebr k\u00ebt\u00eb, do t\u00eb vendosim nj\u00eb skedar .dockerignore n\u00eb projekt dhe do t\u00eb specifikojm\u00eb se \u00e7far\u00eb nuk nevojitet p\u00ebr nd\u00ebrtim:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">.git\n\/node_modules<\/code><\/pre>\n<p><\/p>\n<p>dhe do t\u00eb nis\u00eb nd\u00ebrtimin p\u00ebrs\u00ebri:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nD\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb Docker daemon 607.2kB\nHapi 1\/5 : NGA node:12.16.2\nHapi 2\/5 : WORKDIR \/app\n ---&gt; P\u00ebrdorimi i cache\nHapi 3\/5 : COPY . .\nHapi 4\/5 : RUN npm ci\nshtuar 1357 pacakgevo n\u00eb 22.47s\nHapi 5\/5 : RUN npm run build --prod\nData: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37313ms\nSuksessh\u00ebm i nd\u00ebrtuar 4942f010792a\nSuksessh\u00ebm i etiketuar app:latest\n\nreal 1m47.763s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>607.2 KB \u2014 shum\u00eb m\u00eb mir\u00eb se 409 MB. Dhe gjithashtu ne zvog\u00ebluam madh\u00ebsin\u00eb e imazhit nga 1.74 n\u00eb 1.38GB:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED         SIZE\napp          latest   4942f010792a   3 minuta m\u00eb par\u00eb   1.38GB<\/code><\/pre>\n<p><\/p>\n<p>Le t\u00eb p\u00ebrpiqemi t\u00eb zvog\u00eblojm\u00eb p\u00ebrs\u00ebri madh\u00ebsin\u00eb e imazhit.<\/p>\n<p><\/p>\n<h2 id=\"ispolzuem-alpine\">P\u00ebrdorim Alpine<\/h2>\n<p><\/p>\n<p>Nj\u00eb mund\u00ebsi tjet\u00ebr p\u00ebr t\u00eb kursyer n\u00eb madh\u00ebsin\u00eb e imazhit \u00ebsht\u00eb p\u00ebrdorimi i nj\u00eb imazhi prind t\u00eb vog\u00ebl. Imazhi prind \u00ebsht\u00eb ai nga i cili p\u00ebrgatitet imazhi yn\u00eb. Shtresa e poshtme specifikohet me komand\u00ebn <code>FROM<\/code> n\u00eb Dockerfile. N\u00eb rastin ton\u00eb ne po p\u00ebrdorim nj\u00eb imazh q\u00eb bazohet n\u00eb Ubuntu, ku tashm\u00eb \u00ebsht\u00eb instaluar nodejs. Dhe peshon ...<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ docker images -a | grep node\nnode 12.16.2 406aa3abbc6c 17 minuta m\u00eb par\u00eb 916MB<\/code><\/pre>\n<p><\/p>\n<p>... pothuajse nj\u00eb gigabajt. Duke p\u00ebrdorur nj\u00eb imazh t\u00eb bazuar n\u00eb Alpine Linux, mund t\u00eb zvog\u00eblojm\u00eb ndjesh\u00ebm madh\u00ebsin\u00eb. Alpine \u00ebsht\u00eb nj\u00eb sistem shum\u00eb t\u00eb vog\u00ebl linux. Imazhi Docker p\u00ebr nodejs q\u00eb bazohet n\u00eb alpine peshon vet\u00ebm 88.5 MB. Prandaj, le t\u00eb z\u00ebvend\u00ebsojm\u00eb imazhin ton\u00eb t\u00eb b\u00ebr\u00eb r\u00ebnd\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM node:12.16.2-alpine3.11\nRUN apk --no-cache --update --virtual build-dependencies add \n    python \n    make \n    g++\nWORKDIR \/app\nCOPY . .\nRUN npm ci\nRUN npm run build --prod<\/code><\/pre>\n<p><\/p>\n<p>Na duhej t\u00eb instalonim disa gj\u00ebra q\u00eb ishin t\u00eb nevojshme p\u00ebr nd\u00ebrtimin e aplikacionit. Po, Angular nuk nd\u00ebrtot pa Python \u00af(\u00b0_o)\/\u00af<\/p>\n<p><\/p>\n<p>Por p\u00ebr shkak t\u00eb k\u00ebsaj madh\u00ebsia e imazhit u zvog\u00eblua me 150 MB:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED          SIZE\napp          latest   aa031edc315a   22 minuta m\u00eb par\u00eb   761MB<\/code><\/pre>\n<p><\/p>\n<p>Shk\u00ebmbejm\u00eb kthim t\u00eb tjer\u00eb.<\/p>\n<p><\/p>\n<h2 id=\"multisteydzh-sborka\">Nd\u00ebrtimi me etapa t\u00eb shumta<\/h2>\n<p><\/p>\n<p>Nuk gjith\u00e7ka q\u00eb ndodhet n\u00eb imazh na nevojitet n\u00eb prodhim.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ docker run app ls -lah\ntotal 576K\ndrwxr-xr-x 1 root root 4.0K Apr 16 19:54 .\ndrwxr-xr-x 1 root root 4.0K Apr 16 20:00 ..\n-rwxr-xr-x 1 root root 19 Apr 17 2020 .dockerignore\n-rwxr-xr-x 1 root root 246 Apr 17 2020 .editorconfig\n-rwxr-xr-x 1 root root 631 Apr 17 2020 .gitignore\n-rwxr-xr-x 1 root root 181 Apr 17 2020 Dockerfile\n-rwxr-xr-x 1 root root 1020 Apr 17 2020 README.md\n-rwxr-xr-x 1 root root 3.6K Apr 17 2020 angular.json\n-rwxr-xr-x 1 root root 429 Apr 17 2020 browserslist\ndrwxr-xr-x 3 root root 4.0K Apr 16 19:54 dist\ndrwxr-xr-x 3 root root 4.0K Apr 17 2020 e2e\n-rwxr-xr-x 1 root root 1015 Apr 17 2020 karma.conf.js\n-rwxr-xr-x 1 root root 620 Apr 17 2020 ngsw-config.json\ndrwxr-xr-x 1 root root 4.0K Apr 16 19:54 node_modules\n-rwxr-xr-x 1 root root 494.9K Apr 17 2020 package-lock.json\n-rwxr-xr-x 1 root root 1.3K Apr 17 2020 package.json\ndrwxr-xr-x 5 root root 4.0K Apr 17 2020 src\n-rwxr-xr-x 1 root root 210 Apr 17 2020 tsconfig.app.json\n-rwxr-xr-x 1 root root 489 Apr 17 2020 tsconfig.json\n-rwxr-xr-x 1 root root 270 Apr 17 2020 tsconfig.spec.json\n-rwxr-xr-x 1 root root 1.9K Apr 17 2020 tslint.json<\/code><\/pre>\n<p><\/p>\n<p>Me <code>docker run app ls -lah<\/code> ne e startuam kontejnerin sipas imazhit ton\u00eb <code>app<\/code> dhe ekzekutuam komand\u00ebn <code>ls -lah<\/code>, pas s\u00eb cil\u00ebs kontejneri p\u00ebrfundoi pun\u00ebn e tij.<\/p>\n<p><\/p>\n<p>N\u00eb prodhim na nevojitet vet\u00ebm dosja <code>dist<\/code>. Duke qen\u00eb se skedar\u00ebt duhet t\u00eb d\u00ebrgohen jasht\u00eb. Mund t\u00eb nisnim nj\u00eb server HTTP n\u00eb nodejs. Por ne do ta b\u00ebjm\u00eb m\u00eb s\u00eb lehti. Merrni nj\u00eb imazh nga nginx dhe vendosni at\u00eb n\u00eb dosje <code>dist<\/code> dhe nj\u00eb konfigurim t\u00eb vog\u00ebl:<\/p>\n<p><\/p>\n<pre><code class=\"nginx\">server {\n    listen 80 default_server;\n    server_name localhost;\n    charset utf-8;\n    root \/app\/dist;\n\n    location \/ {\n        try_files $uri $uri\/ \/index.html;\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Kjo e gjith\u00eb do t\u00eb na ndihmoj\u00eb me nd\u00ebrtim t\u00eb shum\u00ebfisht\u00eb. Le t\u00eb ndryshojm\u00eb Dockerfile-n\u00eb ton\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM node:12.16.2-alpine3.11 as builder\nRUN apk --no-cache --update --virtual build-dependencies add \n    python \n    make \n    g++\nWORKDIR \/app\nCOPY . .\nRUN npm ci\nRUN npm run build --prod\n\nFROM nginx:1.17.10-alpine\nRUN rm \/etc\/nginx\/conf.d\/default.conf\nCOPY nginx\/static.conf \/etc\/nginx\/conf.d\nCOPY --from=builder \/app\/dist\/app .<\/code><\/pre>\n<p><\/p>\n<p>Tani kemi dy instruksione <code>FROM<\/code> n\u00eb Dockerfile, secila prej tyre nis nj\u00eb faz\u00eb nd\u00ebrtimi t\u00eb saj. E para e quajt\u00ebm <code>builder<\/code>, nd\u00ebrsa duke filluar nga FROM e fundit do t\u00eb p\u00ebrgatitet imazhi yn\u00eb p\u00ebr fund. Hapi p\u00ebrfundimtar \u00ebsht\u00eb t\u00eb kopjojm\u00eb artikujt e nd\u00ebrtimit nga faza p\u00ebrfundimtare n\u00eb imazhin p\u00ebrfundimtar me nginx. Madh\u00ebsia e imazhit ra duksh\u00ebm:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED          SIZE\napp          latest   2c6c5da07802   29 minuta m\u00eb par\u00eb   36MB<\/code><\/pre>\n<p><\/p>\n<p>Le t\u00eb startojm\u00eb kontejnerin me imazhin ton\u00eb dhe t\u00eb sigurohemi se gjith\u00e7ka funksionon:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">docker run -p8080:80 app<\/code><\/pre>\n<p><\/p>\n<p>Me opsionin -p8080:80 ne kaluam portin 8080 n\u00eb makin\u00ebn ton\u00eb host n\u00eb portin 80 brenda kontejnerit, ku \u00ebsht\u00eb nginx. Hapni n\u00eb shfletues <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080\/<\/a><\/noindex> dhe shikoni aplikacionin ton\u00eb. Gjith\u00e7ka funksionon!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/ab37d9576a84954f4e4860dd49a75f3d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zvog\u00eblimi i madh\u00ebsis\u00eb s\u00eb imazhit nga 1.74 GB n\u00eb 36 MB redukton ndjesh\u00ebm koh\u00ebn e dor\u00ebzimit t\u00eb aplikacionit tuaj n\u00eb prodhim. Por le t\u00eb kthehemi te koha e nd\u00ebrtimit.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nD\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb Docker daemon 608.8kB\nHapi 1\/11 : NGA node:12.16.2-alpine3.11 si nd\u00ebrtues\nHapi 2\/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++\n ---&gt; P\u00ebrdorimi i cache\nHapi 3\/11 : WORKDIR \/app\n ---&gt; P\u00ebrdorim i cache\nHapi 4\/11 : COPY . .\nHapi 5\/11 : RUN npm ci\nshtuar 1357 pacakgevo n\u00eb 47.338s\nHapi 6\/11 : RUN npm run build --prod\nData: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Koha: 39948ms\n ---&gt; 27f1479221e4\nHapi 7\/11 : NGA nginx:stable-alpine\nHapi 8\/11 : WORKDIR \/app\n ---&gt; P\u00ebrdorim i cache\nHapi 9\/11 : RUN rm \/etc\/nginx\/conf.d\/default.conf\n ---&gt; P\u00ebrdorim i cache\nHapi 10\/11 : COPY nginx\/static.conf \/etc\/nginx\/conf.d\n ---&gt; P\u00ebrdorim i cache\nHapi 11\/11 : COPY --from=builder \/app\/dist\/app .\nSuksessh\u00ebm i nd\u00ebrtuar d201471c91ad\nSuksessh\u00ebm i etiketuar app:latest\n\nreal 2m17.700s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<h2 id=\"menyaem-poryadok-sloyov\">Ndryshojm\u00eb rendin e shtresave<\/h2>\n<p><\/p>\n<p>Tri hapat e par\u00eb ishin t\u00eb ruajtura (referenca <code>P\u00ebrdorimi i cache<\/code>). N\u00eb hapin e kat\u00ebrt kopjohen t\u00eb gjith\u00eb skedar\u00ebt e projektit dhe n\u00eb hapin e pest\u00eb instalohet var\u00ebsit\u00eb <code>EJEP npm ci<\/code> \u2014 t\u00ebr\u00ebsisht 47.338s. Pse t\u00eb instalosh var\u00ebsit\u00eb p\u00ebrs\u00ebri \u00e7do her\u00eb, n\u00ebse ato ndryshojn\u00eb shum\u00eb rrall\u00eb? Le t\u00eb shohim se pse ato nuk u ruajt\u00ebn n\u00eb cache. Problemi \u00ebsht\u00eb se Docker kontrollon nivel pas niveli p\u00ebr t\u00eb par\u00eb n\u00ebse komandat dhe skedar\u00ebt q\u00eb lidhen me to kan\u00eb ndryshuar. N\u00eb hapin e kat\u00ebrt ne kopjojm\u00eb t\u00eb gjith\u00eb skedar\u00ebt e projektit ton\u00eb dhe mes tyre, sigurisht, ka ndryshime, prandaj Docker jo vet\u00ebm q\u00eb nuk merr nga cache ky nivel, por edhe t\u00eb gjith\u00eb ata q\u00eb e ndjekin! Le t\u00eb b\u00ebjm\u00eb disa ndryshime t\u00eb vogla n\u00eb Dockerfile.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM node:12.16.2-alpine3.11 as builder\nRUN apk --no-cache --update --virtual build-dependencies add \n    python \n    make \n    g++\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm ci\nCOPY . .\nRUN npm run build --prod\n\nFROM nginx:1.17.10-alpine\nRUN rm \/etc\/nginx\/conf.d\/default.conf\nCOPY nginx\/static.conf \/etc\/nginx\/conf.d\nCOPY --from=builder \/app\/dist\/app .<\/code><\/pre>\n<p><\/p>\n<p>S\u00eb pari kopjohen package.json dhe package-lock.json, pastaj instalohen var\u00ebsit\u00eb, dhe vet\u00ebm pasi b\u00ebhet kjo, kopjohet e gjith\u00eb projekti. Si rezultat:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nD\u00ebrgimi i kontekstit t\u00eb nd\u00ebrtimit n\u00eb daemonin e Docker 608.8kB\nHapi 1\/12 : FROM node:12.16.2-alpine3.11 as builder\nHapi 2\/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++\n ---&gt; Duke p\u00ebrdorur cache\nHapi 3\/12 : WORKDIR \/app\n ---&gt; Duke p\u00ebrdorur cache\nHapi 4\/12 : COPY package*.json .\/\n ---&gt; Duke p\u00ebrdorur cache\nHapi 5\/12 : RUN npm ci\n ---&gt; Duke p\u00ebrdorur cache\nHapi 6\/12 : COPY . .\nHapi 7\/12 : RUN npm run build --prod\nData: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Koha: 38287ms\n ---&gt; 1b9448c73558\nHapi 8\/12 : FROM nginx:stable-alpine\nHapi 9\/12 : WORKDIR \/app\n ---&gt; Duke p\u00ebrdorur cache\nHapi 10\/12 : RUN rm \/etc\/nginx\/conf.d\/default.conf\n ---&gt; Duke p\u00ebrdorur cache\nHapi 11\/12 : COPY nginx\/static.conf \/etc\/nginx\/conf.d\n ---&gt; Duke p\u00ebrdorur cache\nHapi 12\/12 : COPY --from=builder \/app\/dist\/app .\nNd\u00ebrtuar me sukses a44dd7c217c3\nEtiketuar me sukses app:latest\n\nreal 0m46.497s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>46 sekonda n\u00eb vend t\u00eb 3 minutash \u2014 shum\u00eb m\u00eb mir\u00eb! Renditja e sakt\u00eb e niveleve \u00ebsht\u00eb e r\u00ebnd\u00ebsishme: s\u00eb pari kopjojm\u00eb at\u00eb q\u00eb nuk ndryshon, pastaj at\u00eb q\u00eb ndryshon rrall\u00eb, dhe n\u00eb fund \u2014 at\u00eb q\u00eb ndryshon shpesh.<\/p>\n<p><\/p>\n<p>M\u00eb pas disa fjal\u00eb p\u00ebr nd\u00ebrtimin e imazheve n\u00eb sistemet CI\/CD.<\/p>\n<p><\/p>\n<h2 id=\"ispolzovanie-predyduschih-obrazov-dlya-kesha\">P\u00ebrdorimi i imazheve t\u00eb m\u00ebparshme p\u00ebr cache<\/h2>\n<p><\/p>\n<p>N\u00ebse ne p\u00ebrdorim nj\u00eb zgjidhje SaaS p\u00ebr nd\u00ebrtim, at\u00ebher\u00eb cache lokal i Docker-it mund t\u00eb jet\u00eb i past\u00ebr dhe i ri. Q\u00eb Docker t\u00eb ket\u00eb nga t\u00eb cilat t\u00eb marr\u00eb nivelet e gatuara, jepni atij imazhin e m\u00ebparsh\u00ebm t\u00eb nd\u00ebrtuar.<\/p>\n<p><\/p>\n<p>Le t\u00eb marrim p\u00ebr shembull nd\u00ebrtimin e aplikacionit ton\u00eb n\u00eb GitHub Actions. P\u00ebrdorim k\u00ebt\u00eb konfigurim:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">on:\n  push:\n    branches:\n      - master\n\nname: Test docker build\n\njobs:\n  deploy:\n    name: Build\n    runs-on: ubuntu-latest\n    env:\n      IMAGE_NAME: docker.pkg.github.com\/${{ github.repository }}\/app\n      IMAGE_TAG: ${{ github.sha }}\n\n    steps:\n    - name: Checkout\n      uses: actions\/checkout@v2\n\n    - name: Login to GitHub Packages\n      env:\n        TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      run: |\n        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN\n\n    - name: Build\n      run: |\n        docker build \n          -t $IMAGE_NAME:$IMAGE_TAG \n          -t $IMAGE_NAME:latest \n          .\n\n    - name: Push image to GitHub Packages\n      run: |\n        docker push $IMAGE_NAME:latest\n        docker push $IMAGE_NAME:$IMAGE_TAG\n\n    - name: Logout\n      run: |\n        docker logout docker.pkg.github.com<\/code><\/pre>\n<p><\/p>\n<p>Imazhi nd\u00ebrtohet dhe d\u00ebrgohet n\u00eb GitHub Packages n\u00eb dy minuta e 20 sekonda:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/76b81216922f7ef2c4e777b60238acd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tani le t\u00eb ndryshojm\u00eb nd\u00ebrtimin n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb p\u00ebrdoret cache i bazuar n\u00eb imazhet e m\u00ebparshme t\u00eb nd\u00ebrtuara:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">on:\n  push:\n    branches:\n      - master\n\nname: Test docker build\n\njobs:\n  deploy:\n    name: Build\n    runs-on: ubuntu-latest\n    env:\n      IMAGE_NAME: docker.pkg.github.com\/${{ github.repository }}\/app\n      IMAGE_TAG: ${{ github.sha }}\n\n    steps:\n    - name: Checkout\n      uses: actions\/checkout@v2\n\n    - name: Login to GitHub Packages\n      env:\n        TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      run: |\n        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN\n\n    - name: Pull latest images\n      run: |\n        docker pull $IMAGE_NAME:latest || true\n        docker pull $IMAGE_NAME-builder-stage:latest || true\n\n    - name: Images list\n      run: |\n        docker images\n\n    - name: Build\n      run: |\n        docker build \n          --target builder \n          --cache-from $IMAGE_NAME-builder-stage:latest \n          -t $IMAGE_NAME-builder-stage \n          .\n        docker build \n          --cache-from $IMAGE_NAME-builder-stage:latest \n          --cache-from $IMAGE_NAME:latest \n          -t $IMAGE_NAME:$IMAGE_TAG \n          -t $IMAGE_NAME:latest \n          .\n\n    - name: Push image to GitHub Packages\n      run: |\n        docker push $IMAGE_NAME-builder-stage:latest\n        docker push $IMAGE_NAME:latest\n        docker push $IMAGE_NAME:$IMAGE_TAG\n\n    - name: Logout\n      run: |\n        docker logout docker.pkg.github.com<\/code><\/pre>\n<p><\/p>\n<p>S\u00eb pari duhet t\u00eb flasim pse ekzekutohen dy komanda <code>nd\u00ebrto<\/code>. Problemi \u00ebsht\u00eb se n\u00eb nd\u00ebrtimin me shum\u00eb nivele, rezultati i imazhit do t\u00eb jet\u00eb nj\u00eb grup nivelesh nga niveli i fundit. Nivelet nga nivelet e m\u00ebparshme nuk do t\u00eb hyjn\u00eb n\u00eb imazh. Prandaj, kur p\u00ebrdorim imazhin p\u00ebrfundimtar nga nd\u00ebrtimi i m\u00ebparsh\u00ebm, Docker nuk do t\u00eb jet\u00eb n\u00eb gjendje t\u00eb gjej\u00eb nivelet e gatshme p\u00ebr nd\u00ebrtimin e imazhit me nodejs (niveli builder). P\u00ebr t\u00eb zgjidhur k\u00ebt\u00eb problem, krijohet nj\u00eb imazh ndihm\u00ebs <code>$IMAGE_NAME-builder-stage<\/code> dhe d\u00ebrgohet n\u00eb GitHub Packages, n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb mund t\u00eb p\u00ebrdoret n\u00eb nd\u00ebrtimin e m\u00ebvonsh\u00ebm si burim cache.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/acaa70ae528589f4be2258650d8eb5de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Koha e p\u00ebrgjithshme e nd\u00ebrtimit \u00ebsht\u00eb zvog\u00ebluar n\u00eb nj\u00eb minut\u00eb e gjysm\u00eb. Gjasht\u00ebmb\u00ebdhjet\u00eb minuta shpenzohen p\u00ebr t\u00eb t\u00ebrhequr imazhet e m\u00ebparshme.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnoe-sozdanie-obrazov\">Parazgjedhja e imazheve<\/h2>\n<p><\/p>\n<p>Nj\u00eb tjet\u00ebr m\u00ebnyr\u00eb p\u00ebr t\u00eb zgjidhur problemin e caches t\u00eb pastra t\u00eb Docker-it \u00ebsht\u00eb, disa nivele t'i transferosh n\u00eb nj\u00eb Dockerfile tjet\u00ebr, ta nd\u00ebrtosh at\u00eb ve\u00e7mas, ta d\u00ebrgosh n\u00eb Container Registry dhe ta p\u00ebrdor\u00ebsh si prind.<\/p>\n<p><\/p>\n<p>Krijojm\u00eb imazhin ton\u00eb nodejs p\u00ebr nd\u00ebrtimin e aplikacionit Angular. Krijojm\u00eb n\u00eb projekt Dockerfile.node<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM node:12.16.2-alpine3.11\nRUN apk --no-cache --update --virtual build-dependencies add \n    python \n    make \n    g++<\/code><\/pre>\n<p><\/p>\n<p>Nd\u00ebrtojm\u00eb dhe d\u00ebrgojm\u00eb imazhin publik n\u00eb Docker Hub:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">docker build -t exsmund\/node-for-angular -f Dockerfile.node .\ndocker push exsmund\/node-for-angular:latest<\/code><\/pre>\n<p><\/p>\n<p>Tani n\u00eb Dockerfile-in ton\u00eb kryesor p\u00ebrdorim imazhin e gatsh\u00ebm:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">FROM exsmund\/node-for-angular:latest as builder\n...<\/code><\/pre>\n<p><\/p>\n<p>N\u00eb shembujt tan\u00eb, koha e nd\u00ebrtimit nuk u shkurtua, por imazhet e krijuara paraprakisht mund t\u00eb jen\u00eb t\u00eb dobishme n\u00ebse keni shum\u00eb projekte dhe n\u00eb secilin prej tyre duhet t\u00eb vendosni var\u00ebsi t\u00eb nj\u00ebjta.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda.\" src=\"\/wp-content\/uploads\/2020\/05\/5b4e4bd1d4b96a3f07305d2dd0f6d680.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ne shqyrtuam disa metoda p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. N\u00ebse d\u00ebshironi q\u00eb deploy t\u00eb jet\u00eb i shpejt\u00eb, provoni t\u00eb aplikoni n\u00eb projektin tuaj:<\/p>\n<p><\/p>\n<ul>\n<li>reduktimi i kontekstit;<\/li>\n<li>p\u00ebrdorimi i imazheve t\u00eb vogla prind;<\/li>\n<li>nd\u00ebrtimi me shum\u00eb faza;<\/li>\n<li>ndryshimi i rendit t\u00eb udh\u00ebzimeve n\u00eb Dockerfile p\u00ebr t\u00eb shfryt\u00ebzuar efektivisht memorin\u00eb cache;<\/li>\n<li>konfigurimi i memoris\u00eb cache n\u00eb sistemet CI\/CD;<\/li>\n<li>krijimi paraprak i imazheve.<\/li>\n<\/ul>\n<p><\/p>\n<p>Shpresoj se p\u00ebrmes k\u00ebtij shembulli do t\u00eb kuptoni m\u00eb mir\u00eb se si funksionon Docker dhe do t\u00eb jeni n\u00eb gjendje ta konfiguroni optimalisht deploy-in tuaj. P\u00ebr t\u00eb eksperimentuar me shembujt e artikullit, \u00ebsht\u00eb krijuar nj\u00eb depozit\u00eb. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devopsprodigy\/test-docker-build\">https:\/\/github.com\/devopsprodigy\/test-docker-build<\/a><\/noindex>.<\/p>\n<p>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/501680\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0444\u0438\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434, \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 CI\/CD \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0434\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438. \u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043a\u0438\u043d\u0443\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u043e FTP (\u0442\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0430\u043a \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442, \u0432\u0435\u0440\u043d\u043e?), \u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u00ab\u0434\u0435\u043f\u043b\u043e\u044f\u00bb \u0437\u0430\u043d\u0438\u043c\u0430\u043b \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0422\u0435\u043f\u0435\u0440\u044c \u0436\u0435 \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c merge request \u0438 \u0436\u0434\u0430\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043f\u043e\u043a\u0430 \u0444\u0438\u0447\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":81601,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-81600","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0444\u0438\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434, \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 CI\/CD \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0434\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\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\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 Docker-\u043e\u0431\u0440\u0430\u0437\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e 30 \u0441\u0435\u043a\u0443\u043d\u0434 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0444\u0438\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434, \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 CI\/CD \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0434\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund\" \/>\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-05-14T23:42:41+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-14T23:42:41+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\udd47Disa k\u00ebshilla p\u00ebr t\u00eb p\u00ebrshpejtuar nd\u00ebrtimin e imazheve Docker. P\u00ebr shembull, deri n\u00eb 30 sekonda | ProHoster","description":"Para se funksioni t\u00eb arrij\u00eb n\u00eb prodhim, n\u00eb koh\u00ebn ton\u00eb t\u00eb orkestrator\u00ebve t\u00eb komplikuar dhe CI\/CD, ajo duhet t\u00eb kaloj\u00eb nj\u00eb udh\u00ebtim t\u00eb gjat\u00eb nga komiti deri te testet dhe dor\u00ebzimi.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund","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\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 Docker-\u043e\u0431\u0440\u0430\u0437\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e 30 \u0441\u0435\u043a\u0443\u043d\u0434 | ProHoster","og:description":"\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0444\u0438\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434, \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 CI\/CD \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0434\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund","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-05-14T23:42:41+00:00","article:modified_time":"2020-05-14T23:42:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"81600","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:55:42","updated":"2022-09-29 02:10:06","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\/81600","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=81600"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/81600\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/81601"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=81600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=81600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=81600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}