{"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\/hu\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund","title":{"rendered":"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Miel\u0151tt egy \u00faj funkci\u00f3 \u00e9lesbe ker\u00fcl, a bonyolult orkestr\u00e1torok \u00e9s CI\/CD vil\u00e1g\u00e1ban hossz\u00fa utat kell megtennie a pillanatt\u00f3l a tesztel\u00e9sig \u00e9s a kisz\u00e1ll\u00edt\u00e1sig. R\u00e9gen el\u00e9g volt az \u00faj f\u00e1jlokat FTP-n felt\u00f6lteni (de most m\u00e1r senki sem csin\u00e1lja \u00edgy, igaz?), \u00e9s a \"telep\u00edt\u00e9si\" folyamat m\u00e1sodpercekbe telt. Most azonban merge k\u00e9rd\u00e9st kell k\u00e9sz\u00edteni, \u00e9s eltart egy ideig, am\u00edg a funkci\u00f3 eljut a felhaszn\u00e1l\u00f3khoz.<\/p>\n<p><\/p>\n<p>Ennek az \u00fatnak egy r\u00e9sze a Docker-image-ek \u00f6ssze\u00e1ll\u00edt\u00e1sa. N\u00e9ha az \u00f6ssze\u00e1ll\u00edt\u00e1s percekig, n\u00e9ha pedig hossz\u00fa percekig tart, ami nehezen mondhat\u00f3 norm\u00e1lisnak. Ebben a cikkben egy egyszer\u0171 alkalmaz\u00e1st fogunk csomagolni egy image-be, alkalmazunk n\u00e9h\u00e1ny m\u00f3dszert az \u00f6ssze\u00e1ll\u00edt\u00e1s felgyors\u00edt\u00e1s\u00e1ra, \u00e9s megvizsg\u00e1ljuk e m\u00f3dszerek m\u0171k\u00f6d\u00e9s\u00e9nek r\u00e9szleteit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" 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>J\u00f3 tapasztalataink vannak a h\u00edrszolg\u00e1ltat\u00e1sok weboldalainak l\u00e9trehoz\u00e1s\u00e1ban \u00e9s t\u00e1mogat\u00e1s\u00e1ban: <noindex><a rel=\"nofollow\" href=\"https:\/\/tass.ru\/\">TASS<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/thebell.io\/\">The Bell<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/novayagazeta.ru\/\">\"\u00daj \u00dajs\u00e1g\"<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/republic.ru\/\">Republic<\/a><\/noindex>\u2026 Nemr\u00e9giben \u00faj weboldallal b\u0151v\u00edtett\u00fck a portf\u00f3li\u00f3nkat, amely az \u00e9lesben fut\u00f3 <noindex><a rel=\"nofollow\" href=\"https:\/\/reminder.media\">Reminder<\/a><\/noindex>. Mik\u00f6zben gyorsan kidolgoztuk az \u00faj funkci\u00f3kat \u00e9s jav\u00edtottuk a r\u00e9gi hib\u00e1kat, a lass\u00fa telep\u00edt\u00e9s nagy probl\u00e9m\u00e1v\u00e1 v\u00e1lt.<\/p>\n<p><\/p>\n<p>A telep\u00edt\u00e9st GitLab-on v\u00e9gezz\u00fck. \u00d6ssze\u00e1ll\u00edtjuk az image-eket, felt\u00f6ltj\u00fck a GitLab Registry-be, majd \u00e9lesben telep\u00edtj\u00fck \u0151ket. Ebben a folyamatban a legid\u0151ig\u00e9nyesebb a image-ek \u00f6ssze\u00e1ll\u00edt\u00e1sa. P\u00e9ld\u00e1ul optimaliz\u00e1l\u00e1s n\u00e9lk\u00fcl minden backend \u00f6ssze\u00e1ll\u00edt\u00e1s 14 percig tartott.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/043bc8ad67c34e1c7bd705433c5e4e77.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u00e9g\u00fcl vil\u00e1goss\u00e1 v\u00e1lt, hogy \u00edgy nem lehet tov\u00e1bb \u00e9lni, \u00e9s nekil\u00e1ttunk kider\u00edteni, mi\u00e9rt tart ennyi ideig az image-ek \u00f6ssze\u00e1ll\u00edt\u00e1sa. V\u00e9g\u00fcl siker\u00fclt az \u00f6ssze\u00e1ll\u00edt\u00e1si id\u0151t 30 m\u00e1sodpercre cs\u00f6kkenteni!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/d035eb1c7b95e0345a110ee59f472693.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ehhez a cikkhez, hogy ne k\u00f6t\u0151dj\u00fcnk a Reminder k\u00f6rnyezet\u00e9hez, n\u00e9zz\u00fcnk meg egy p\u00e9ld\u00e1t egy \u00fcres Angular alkalmaz\u00e1s \u00f6ssze\u00e1ll\u00edt\u00e1s\u00e1ra. Teh\u00e1t hozzuk l\u00e9tre az alkalmaz\u00e1sunkat:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">ng n app<\/code><\/pre>\n<p><\/p>\n<p>Hozz\u00e1adjuk a PWA-t (hiszen halad\u00f3k vagyunk):<\/p>\n<p><\/p>\n<pre><code class=\"bash\">ng add @angular\/pwa --project app<\/code><\/pre>\n<p><\/p>\n<p>Mik\u00f6zben let\u00f6lt\u0151dik a rengeteg npm-csomag, n\u00e9zz\u00fck meg, hogyan n\u00e9z ki a docker-image. A Docker lehet\u0151v\u00e9 teszi, hogy alkalmaz\u00e1sokat csomagoljunk \u00e9s egy izol\u00e1lt k\u00f6rnyezetben, \u00fagynevezett kont\u00e9nerben futtassuk \u0151ket. Az izol\u00e1ci\u00f3nak k\u00f6sz\u00f6nhet\u0151en egyszerre t\u00f6bb kont\u00e9ner is futhat egy szerveren. A kont\u00e9nerek l\u00e9nyegesen k\u00f6nnyebbek, mint a virtu\u00e1lis g\u00e9pek, mivel k\u00f6zvetlen\u00fcl a rendszer magj\u00e1ban futnak. Ahhoz, hogy elind\u00edtsuk a kont\u00e9nert az alkalmaz\u00e1sunkkal, el\u0151sz\u00f6r l\u00e9tre kell hoznunk egy image-et, amelybe mindent csomagolunk, amire az alkalmaz\u00e1sunk m\u0171k\u00f6d\u00e9s\u00e9hez sz\u00fcks\u00e9g van. Az image l\u00e9nyeg\u00e9ben a f\u00e1jlrendszer lenyomata. P\u00e9ld\u00e1ul n\u00e9zz\u00fck a Dockerfile-t:<\/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>A Dockerfile egy utas\u00edt\u00e1sk\u00e9szlet; amikor ezeket v\u00e9grehajtja, a Docker a f\u00e1jlrendszeren t\u00e1rolja a m\u00f3dos\u00edt\u00e1sokat, \u00e9s r\u00e1juk rakja az el\u0151z\u0151 r\u00e9tegeket. Minden parancs l\u00e9trehozza a saj\u00e1t r\u00e9teg\u00e9t. A k\u00e9sz k\u00e9p a r\u00e9tegek \u00f6sszegy\u00far\u00e1sa.<\/p>\n<p><\/p>\n<p>Fontos tudni: minden r\u00e9teget a Docker k\u00e9pes gyors\u00edtani. Ha semmi nem v\u00e1ltozott az el\u0151z\u0151 build \u00f3ta, a Docker a kor\u00e1bban elk\u00e9sz\u00fclt r\u00e9teget veszi figyelembe a parancs v\u00e9grehajt\u00e1sa helyett. Mivel a sebess\u00e9g n\u00f6veked\u00e9se a cache haszn\u00e1lat\u00e1b\u00f3l sz\u00e1rmazik, a build sebess\u00e9g\u00e9nek m\u00e9r\u00e9sekor csak a cache-elt k\u00e9pek \u00e9p\u00edt\u00e9s\u00e9re figyel\u00fcnk. Teh\u00e1t, l\u00e9p\u00e9sr\u0151l l\u00e9p\u00e9sre:<\/p>\n<p><\/p>\n<ol>\n<li>T\u00f6r\u00f6lj\u00fck a helyi k\u00e9peket, hogy az el\u0151z\u0151 fut\u00e1sok ne befoly\u00e1solj\u00e1k a tesztet.<br \/>\n<code>docker rmi $(docker images -q)<\/code><\/li>\n<li>Ind\u00edtsuk el a buildet el\u0151sz\u00f6r.<br \/>\n<code>time docker build -t app .<\/code><\/li>\n<li>M\u00f3dos\u00edtjuk a f\u00e1jlt src\/index.html \u2014 szimul\u00e1lva egy programoz\u00f3 munk\u00e1j\u00e1t.<\/li>\n<li>Ind\u00edtjuk a buildet m\u00e1sodszor.<br \/>\n<code>time docker build -t app .<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>Ha a k\u00e9pek buildel\u00e9s\u00e9hez sz\u00fcks\u00e9ges k\u00f6rnyezetet megfelel\u0151en konfigur\u00e1ltuk (err\u0151l kicsit k\u00e9s\u0151bb), a Docker a build elind\u00edt\u00e1sakor m\u00e1r sok cache-t fog haszn\u00e1lni. C\u00e9lunk, hogy megtanuljuk a cache-t haszn\u00e1lni, hogy a build a lehet\u0151 leggyorsabban menjen v\u00e9gbe. Felt\u00e9telezve, hogy a cache n\u00e9lk\u00fcli buildet csak egyszer, az els\u0151 alkalommal hajtjuk v\u00e9gre, azt figyelmen k\u00edv\u00fcl hagyhatjuk, mennyire lass\u00fa volt az els\u0151 alkalom. A tesztjeink szempontj\u00e1b\u00f3l a m\u00e1sodik build fontos, amikor a cache-ek m\u00e1r felmelegedtek, \u00e9s k\u00e9szen \u00e1llunk a s\u00fctem\u00e9ny s\u00fct\u00e9s\u00e9re. Mindazon\u00e1ltal n\u00e9h\u00e1ny tipp az els\u0151 buildre is hat\u00e1ssal lesz.<\/p>\n<p><\/p>\n<p>Tegy\u00fck a fent le\u00edrt Dockerfile-t a projekt mapp\u00e1j\u00e1ba, \u00e9s ind\u00edtsuk el a buildet. Minden bemutatott r\u00e9szlet a k\u00f6nnyebb olvashat\u00f3s\u00e1g \u00e9rdek\u00e9ben lett r\u00f6vid\u00edtve.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nK\u00fcld\u00e9s a build kontextus\u00e1t a Docker d\u00e9monnak 409MB\n1\/5. l\u00e9p\u00e9s: FROM node:12.16.2\n\u00c1llapot: \u00dajabb image let\u00f6ltve a node:12.16.2-hez\n2\/5. l\u00e9p\u00e9s: WORKDIR \/app\n3\/5. l\u00e9p\u00e9s: COPY . .\n4\/5. l\u00e9p\u00e9s: RUN npm ci\n1357 csomag hozz\u00e1adva 22.47s alatt\n5\/5. l\u00e9p\u00e9s: RUN npm run build --prod\nD\u00e1tum: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Id\u0151: 37581ms\nSikeresen \u00e9p\u00edtve c8c279335f46\nSikeresen c\u00edmk\u00e9zve app:latest\n\nval\u00f3s 5m4.541s\nfelhaszn\u00e1l\u00f3 0m0.000s\nrendszer 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>M\u00f3dos\u00edtjuk a src\/index.html tartalm\u00e1t \u00e9s ind\u00edtjuk m\u00e1sodszor.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nK\u00fcld\u00e9s a build kontextus\u00e1t a Docker d\u00e9monnak 409MB\n1\/5. l\u00e9p\u00e9s: FROM node:12.16.2\n2\/5. l\u00e9p\u00e9s: WORKDIR \/app\n ---&gt; Cache haszn\u00e1lata\n3\/5. l\u00e9p\u00e9s: COPY . .\n4\/5. l\u00e9p\u00e9s: RUN npm ci\n1357 csomag hozz\u00e1adva 22.47s alatt\n5\/5. l\u00e9p\u00e9s: RUN npm run build --prod\nD\u00e1tum: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Id\u0151: 37902ms\nSikeresen \u00e9p\u00edtve 79f335df92d3\nSikeresen c\u00edmk\u00e9zve app:latest\n\nval\u00f3s 3m33.262s\nfelhaszn\u00e1l\u00f3 0m0.000s\nrendszer 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>Ahhoz, hogy megn\u00e9zz\u00fck, elk\u00e9sz\u00fclt-e a k\u00e9p, futtassuk a parancsot <code>docker images<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED              SIZE\napp          latest   79f335df92d3   K\u00f6r\u00fclbel\u00fcl egy perce   1.74GB<\/code><\/pre>\n<p><\/p>\n<p>A Docker build takes all files in the current context and sends them to its daemon. <code>Sending build context to Docker daemon 409MB<\/code>. The build context is specified as the last argument of the build command. In our case, this is the current directory \u2014 \".\" \u2014 and Docker pulls everything we have in this folder. 409 MB is a lot: let's think about how to fix this.<\/p>\n<p><\/p>\n<h2 id=\"umenshaem-kontekst\">Reducing the context<\/h2>\n<p><\/p>\n<p>To reduce the context, there are two options. Either place all the files needed for the build in a separate folder and specify that folder as the context for Docker. This may not always be convenient, so there's a way to specify exceptions: what should not be included in the context. For this, we will add a .dockerignore file to the project and specify what is not needed for the build:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">.git\n\/node_modules<\/code><\/pre>\n<p><\/p>\n<p>and run the build again:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nSending build context to Docker daemon 607.2kB\nStep 1\/5 : FROM node:12.16.2\nStep 2\/5 : WORKDIR \/app\n ---&gt; Using cache\nStep 3\/5 : COPY . .\nStep 4\/5 : RUN npm ci\nadded 1357 packages in 22.47s\nStep 5\/5 : RUN npm run build --prod\nDate: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Time: 37313ms\nSuccessfully built 4942f010792a\nSuccessfully tagged app:latest\n\nreal 1m47.763s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>607.2 KB is much better than 409 MB. And we also reduced the image size from 1.74 to 1.38 GB:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED         SIZE\napp          latest   4942f010792a   3 minutes ago   1.38GB<\/code><\/pre>\n<p><\/p>\n<p>Let's try to further reduce the image size.<\/p>\n<p><\/p>\n<h2 id=\"ispolzuem-alpine\">Using Alpine<\/h2>\n<p><\/p>\n<p>Another way to save on image size is to use a smaller parent image. The parent image is the image on which our image is based. The lower layer is specified by the command <code>FROM<\/code> in the Dockerfile. In our case, we are using an image based on Ubuntu that already has nodejs installed. And it weighs ...<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ docker images -a | grep node\nnode 12.16.2 406aa3abbc6c 17 minutes ago 916MB<\/code><\/pre>\n<p><\/p>\n<p>... almost a gigabyte. You can significantly reduce the size by using an image based on Alpine Linux. Alpine is a very small Linux. The Docker image for nodejs based on Alpine weighs only 88.5 MB. So let's replace our fat parent image:<\/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>We had to install some stuff that is necessary for building the application. Yes, Angular doesn't build without Python \u00af(\u00b0_o)\\\/\u00af<\/p>\n<p><\/p>\n<p>But the image size dropped by 150 MB:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED          SIZE\napp          latest   aa031edc315a   22 minutes ago   761MB<\/code><\/pre>\n<p><\/p>\n<p>Let's go further.<\/p>\n<p><\/p>\n<h2 id=\"multisteydzh-sborka\">Multi-stage build<\/h2>\n<p><\/p>\n<p>Not everything that is in the image is needed in production.<\/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>A seg\u00edts\u00e9g\u00e9vel <code>docker run app ls -lah<\/code> Elind\u00edtottunk egy kont\u00e9nert a saj\u00e1t k\u00e9pm\u00e1sunk alapj\u00e1n. <code>app<\/code> \u00e9s v\u00e9grehajtottuk benne a parancsot <code>ls -lah<\/code>, ezt k\u00f6vet\u0151en a kont\u00e9ner befejezte a m\u0171k\u00f6d\u00e9s\u00e9t.<\/p>\n<p><\/p>\n<p>A produkci\u00f3hoz csak a mapp\u00e1ra van sz\u00fcks\u00e9g\u00fcnk <code>dist<\/code>. A f\u00e1jlokat valahogy ki kell adni. Ind\u00edthatunk egy HTTP-szervert node.js-en. De egyszer\u0171s\u00edt\u00fcnk. Tal\u00e1lj\u00e1tok ki a n\u00e9gy '\u044b' bet\u0171t tartalmaz\u00f3 orosz sz\u00f3t. Helyes! \u042b\u043d\u0436\u044b\u043d\u044b\u043a\u0441\u044b. V\u00e1lasszuk ki az nginx k\u00e9pet, tegy\u00fck bele a mapp\u00e1t <code>dist<\/code> \u00e9s egy egyszer\u0171 konfigur\u00e1ci\u00f3t:<\/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>Ezt a multi-stage build seg\u00edt nek\u00fcnk megval\u00f3s\u00edtani. M\u00f3dos\u00edtjuk a Dockerfile-t:<\/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>Most k\u00e9t utas\u00edt\u00e1sunk van <code>FROM<\/code> a Dockerfile-ban, mindegyik saj\u00e1t \u00e9p\u00edt\u00e9si szakasz\u00e1t ind\u00edtja el. Az els\u0151t nevezt\u00fck <code>Torrentek:<\/code>, az utols\u00f3 FROM-t\u00f3l kezdve k\u00e9sz\u00fcl a v\u00e9gs\u0151 k\u00e9pm\u00e1sunk. Az utols\u00f3 l\u00e9p\u00e9sben \u00e1tm\u00e1soljuk az el\u0151z\u0151 szakaszban k\u00e9sz\u00edtett artefaktumot a v\u00e9gs\u0151 nginx k\u00e9pm\u00e1sba. A k\u00e9pm\u00e1s m\u00e9rete jelent\u0151sen cs\u00f6kkent:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">REPOSITORY   TAG      IMAGE ID       CREATED          SIZE\napp          latest   2c6c5da07802   29 minutes ago   36MB<\/code><\/pre>\n<p><\/p>\n<p>Ind\u00edtsuk el a kont\u00e9nert a k\u00e9pm\u00e1sunkkal, \u00e9s gy\u0151z\u0151dj\u00fcnk meg r\u00f3la, hogy minden m\u0171k\u00f6dik:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">docker run -p8080:80 app<\/code><\/pre>\n<p><\/p>\n<p>A -p8080:80 opci\u00f3val a 8080-as portot az otthoni g\u00e9p\u00fcnk\u00f6n a kont\u00e9ner 80-as portj\u00e1ra ir\u00e1ny\u00edtottuk, ahol az nginx fut. Nyissuk meg a b\u00f6ng\u00e9sz\u0151ben <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080\/<\/a><\/noindex> \u00e9s l\u00e1thatjuk az alkalmaz\u00e1sunkat. Minden m\u0171k\u00f6dik!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/ab37d9576a84954f4e4860dd49a75f3d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A k\u00e9pm\u00e1s m\u00e9ret\u00e9nek cs\u00f6kkent\u00e9se 1.74 GB-r\u00f3l 36 MB-ra jelent\u0151sen ler\u00f6vid\u00edti az alkalmaz\u00e1sunk sz\u00e1ll\u00edt\u00e1si idej\u00e9t a produkci\u00f3ba. De t\u00e9rj\u00fcnk vissza az \u00e9p\u00edt\u00e9si id\u0151re.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nSending build context to Docker daemon 608.8kB\nStep 1\/11 : FROM node:12.16.2-alpine3.11 as builder\nStep 2\/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++\n ---&gt; Using cache\nStep 3\/11 : WORKDIR \/app\n ---&gt; Using cache\nStep 4\/11 : COPY . .\nStep 5\/11 : RUN npm ci\nadded 1357 packages in 47.338s\nStep 6\/11 : RUN npm run build --prod\nDate: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Time: 39948ms\n ---&gt; 27f1479221e4\nStep 7\/11 : FROM nginx:stable-alpine\nStep 8\/11 : WORKDIR \/app\n ---&gt; Using cache\nStep 9\/11 : RUN rm \/etc\/nginx\/conf.d\/default.conf\n ---&gt; Using cache\nStep 10\/11 : COPY nginx\/static.conf \/etc\/nginx\/conf.d\n ---&gt; Using cache\nStep 11\/11 : COPY --from=builder \/app\/dist\/app .\nSuccessfully built d201471c91ad\nSuccessfully tagged app:latest\n\nreal 2m17.700s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<h2 id=\"menyaem-poryadok-sloyov\">Megv\u00e1ltoztatjuk a r\u00e9tegek sorrendj\u00e9t<\/h2>\n<p><\/p>\n<p>Az els\u0151 h\u00e1rom l\u00e9p\u00e9s m\u00e1r cache-elt (tipp: <code>Using cache<\/code>). A negyedik l\u00e9p\u00e9sben a projekt \u00f6sszes f\u00e1jl\u00e1t \u00e1tm\u00e1solj\u00e1k, az \u00f6t\u00f6dik l\u00e9p\u00e9sben a f\u00fcgg\u0151s\u00e9gek telep\u00edt\u00e9se t\u00f6rt\u00e9nik <code>RUN npm ci<\/code> \u2014 \u00f6sszesen 47,338 m\u00e1sodperc. Mi\u00e9rt kellene minden alkalommal \u00fajra telep\u00edteni a f\u00fcgg\u0151s\u00e9geket, ha azok nagyon ritk\u00e1n v\u00e1ltoznak? N\u00e9zz\u00fck meg, mi\u00e9rt nem ker\u00fcltek elt\u00e1rol\u00e1sra a gyors\u00edt\u00f3t\u00e1rban. Az a helyzet, hogy a Docker r\u00e9tegr\u0151l r\u00e9tegre ellen\u0151rzi, hogy megv\u00e1ltozott-e a parancs \u00e9s a hozz\u00e1 kapcsol\u00f3d\u00f3 f\u00e1jlok. A negyedik l\u00e9p\u00e9sben \u00e1tm\u00e1soljuk a projekt\u00fcnk \u00f6sszes f\u00e1jlj\u00e1t, \u00e9s ezek k\u00f6z\u00f6tt term\u00e9szetesen vannak v\u00e1ltoz\u00e1sok, \u00edgy a Docker nemcsak hogy nem veszi az ezt a r\u00e9teget a gyors\u00edt\u00f3t\u00e1rb\u00f3l, hanem az \u00f6sszes k\u00f6vetkez\u0151t sem! Tekints\u00fck \u00e1t, hogyan m\u00f3dos\u00edthatn\u00e1nk a Dockerfile-t.<\/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>El\u0151sz\u00f6r a package.json \u00e9s a package-lock.json f\u00e1jlok m\u00e1sol\u00f3dnak, majd telep\u00edtj\u00fck a f\u00fcgg\u0151s\u00e9geket, \u00e9s csak ezut\u00e1n m\u00e1soljuk az eg\u00e9sz projektet. Az eredm\u00e9ny:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ time docker build -t app .\nA build kontextus\u00e1nak k\u00fcld\u00e9se a Docker d\u00e9monnak 608,8 kB\nStep 1\/12 : FROM node:12.16.2-alpine3.11 as builder\nStep 2\/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++\n ---&gt; Using cache\nStep 3\/12 : WORKDIR \/app\n ---&gt; Using cache\nStep 4\/12 : COPY package*.json .\/\n ---&gt; Using cache\nStep 5\/12 : RUN npm ci\n ---&gt; Using cache\nStep 6\/12 : COPY . .\nStep 7\/12 : RUN npm run build --prod\nD\u00e1tum: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Id\u0151: 38287ms\n ---&gt; 1b9448c73558\nStep 8\/12 : FROM nginx:stable-alpine\nStep 9\/12 : WORKDIR \/app\n ---&gt; Using cache\nStep 10\/12 : RUN rm \/etc\/nginx\/conf.d\/default.conf\n ---&gt; Using cache\nStep 11\/12 : COPY nginx\/static.conf \/etc\/nginx\/conf.d\n ---&gt; Using cache\nStep 12\/12 : COPY --from=builder \/app\/dist\/app .\nSikeresen l\u00e9trehozva: a44dd7c217c3\nSikeresen c\u00edmk\u00e9zve: app:latest\n\nval\u00f3di 0m46.497s\nuser 0m0.000s\nsys 0m0.000s<\/code><\/pre>\n<p><\/p>\n<p>46 m\u00e1sodperc a 3 perc helyett \u2014 sokkal jobb! Fontos a r\u00e9tegek megfelel\u0151 sorrendje: el\u0151sz\u00f6r m\u00e1soljuk azt, ami nem v\u00e1ltozik, majd azt, ami ritk\u00e1n v\u00e1ltozik, v\u00e9g\u00fcl pedig azt, ami gyakran.<\/p>\n<p><\/p>\n<p>Ezut\u00e1n n\u00e9h\u00e1ny sz\u00f3 a k\u00e9pek CI\/CD rendszerekben t\u00f6rt\u00e9n\u0151 l\u00e9trehoz\u00e1s\u00e1r\u00f3l.<\/p>\n<p><\/p>\n<h2 id=\"ispolzovanie-predyduschih-obrazov-dlya-kesha\">El\u0151z\u0151 k\u00e9pek haszn\u00e1lata gyors\u00edt\u00f3t\u00e1rk\u00e9nt<\/h2>\n<p><\/p>\n<p>Ha valamilyen SaaS megold\u00e1st haszn\u00e1lunk a buildhez, akkor a helyi Docker gyors\u00edt\u00f3t\u00e1r \u00fcres \u00e9s friss lehet. Ahhoz, hogy a Dockernek legyen honnan elvenni a felt\u00f6lt\u00f6tt r\u00e9tegeket, adjunk neki egy kor\u00e1bban elk\u00e9sz\u00fclt k\u00e9pet.<\/p>\n<p><\/p>\n<p>N\u00e9zz\u00fck meg p\u00e9ld\u00e1ul az alkalmaz\u00e1sunk GitHub Actions-ban t\u00f6rt\u00e9n\u0151 buildel\u00e9s\u00e9t. Haszn\u00e1ljunk egy ilyen konfigur\u00e1ci\u00f3t<\/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>A k\u00e9pet k\u00e9t perc \u00e9s 20 m\u00e1sodperc alatt \u00e9p\u00edtj\u00fck \u00e9s toljuk a GitHub Packages-be:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/76b81216922f7ef2c4e777b60238acd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Most m\u00f3dos\u00edtsuk az \u00e9p\u00edt\u00e9st, hogy a kor\u00e1bban elk\u00e9sz\u00fclt k\u00e9pek alapj\u00e1n cache-t haszn\u00e1ljunk:<\/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>El\u0151sz\u00f6r is el kell mondani, mi\u00e9rt ind\u00edtunk el k\u00e9t parancsot. <code>build<\/code>Az\u00e9rt, mert a multi-stage build sor\u00e1n az eredm\u00e9ny egy r\u00e9tegcsomag lesz az utols\u00f3 stagb\u0151l. Ezzel egy\u00fctt az el\u0151z\u0151 r\u00e9tegek nem ker\u00fclnek az image-be. Ez\u00e9rt, ha a v\u00e9gs\u0151 k\u00e9pet a kor\u00e1bbi buildb\u0151l haszn\u00e1ljuk, a Docker nem tal\u00e1lja meg a k\u00e9sz r\u00e9tegeket a Node.js image \u00e9p\u00edt\u00e9s\u00e9hez (builder stage). E probl\u00e9ma megold\u00e1s\u00e1ra egy k\u00f6zbens\u0151 image-t hozunk l\u00e9tre. <code>$IMAGE_NAME-builder-stage<\/code> \u00e9s felt\u00f6ltj\u00fck a GitHub Packages-be, hogy a k\u00f6vetkez\u0151 buildn\u00e9l cache forr\u00e1sk\u00e9nt felhaszn\u00e1lhassuk.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/acaa70ae528589f4be2258650d8eb5de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Az \u00f6sszes \u00e9p\u00edt\u00e9si id\u0151 egy \u00e9s f\u00e9l percre cs\u00f6kkent. F\u00e9l perc alatt az el\u0151z\u0151 k\u00e9pek leh\u00edv\u00e1s\u00e1ra van sz\u00fcks\u00e9g.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnoe-sozdanie-obrazov\">El\u0151zetes k\u00e9pk\u00e9sz\u00edt\u00e9s<\/h2>\n<p><\/p>\n<p>Egy m\u00e1sik m\u00f3dja a Docker tiszta gyors\u00edt\u00f3t\u00e1r\u00e1nak probl\u00e9m\u00e1j\u00e1nak megold\u00e1s\u00e1ra az, hogy n\u00e9h\u00e1ny r\u00e9teget \u00e1thelyez\u00fcnk egy m\u00e1sik Dockerfile-ba, k\u00fcl\u00f6n \u00f6ssze\u00e1ll\u00edtjuk, felt\u00f6ltj\u00fck a Container Registry-be, \u00e9s sz\u00fcl\u0151k\u00e9nt haszn\u00e1ljuk.<\/p>\n<p><\/p>\n<p>Saj\u00e1t nodejs k\u00e9pet k\u00e9sz\u00edt\u00fcnk az Angular-alkalmaz\u00e1s \u00f6ssze\u00e1ll\u00edt\u00e1s\u00e1hoz. L\u00e9trehozzuk a projektben a Dockerfile.node f\u00e1jlt.<\/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>K\u00e9sz\u00edt\u00fcnk \u00e9s felt\u00f6lt\u00fcnk nyilv\u00e1nos k\u00e9pet a Docker Hub-ra:<\/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>Most a f\u0151 Dockerfile-unkban haszn\u00e1ljuk a k\u00e9sz k\u00e9pet:<\/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>A p\u00e9ld\u00e1nkban a build id\u0151 nem cs\u00f6kkent, de az el\u0151re elk\u00e9sz\u00edtett k\u00e9pek hasznosak lehetnek, ha sok projekted van, \u00e9s mindegyikben azonos f\u00fcgg\u0151s\u00e9geket kell telep\u00edteni.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"N\u00e9h\u00e1ny tipp a Docker-k\u00e9pf\u00e1jlok gyorsabb l\u00e9trehoz\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul ak\u00e1r 30 m\u00e1sodperc alatt\" src=\"\/wp-content\/uploads\/2020\/05\/5b4e4bd1d4b96a3f07305d2dd0f6d680.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>T\u00f6bb m\u00f3dszert is megvizsg\u00e1ltunk a Docker-k\u00e9pek buildel\u00e9s\u00e9nek felgyors\u00edt\u00e1s\u00e1ra. Ha azt szeretn\u00e9d, hogy a telep\u00edt\u00e9s gyors legyen, pr\u00f3b\u00e1ld alkalmazni a projektedben:<\/p>\n<p><\/p>\n<ul>\n<li>a kontextus cs\u00f6kkent\u00e9se;<\/li>\n<li>kism\u00e9ret\u0171 sz\u00fcl\u0151k\u00e9pek haszn\u00e1lata;<\/li>\n<li>multistage build;<\/li>\n<li>az utas\u00edt\u00e1sok sorrendj\u00e9nek megv\u00e1ltoztat\u00e1sa a Dockerfile-ban a gyors\u00edt\u00f3t\u00e1r hat\u00e9kony felhaszn\u00e1l\u00e1s\u00e1hoz;<\/li>\n<li>a gyors\u00edt\u00f3t\u00e1r be\u00e1ll\u00edt\u00e1sa CI\/CD rendszerekben;<\/li>\n<li>el\u0151re elk\u00e9sz\u00edtett k\u00e9pek.<\/li>\n<\/ul>\n<p><\/p>\n<p>Rem\u00e9lem, hogy a p\u00e9lda seg\u00edt meg\u00e9rteni, hogyan m\u0171k\u00f6dik a Docker, \u00e9s hogy optim\u00e1lisan be tudod \u00e1ll\u00edtani a telep\u00edt\u00e9sedet. A cikk p\u00e9ld\u00e1inak kipr\u00f3b\u00e1l\u00e1s\u00e1hoz k\u00e9sz\u00fclt egy repository. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devopsprodigy\/test-docker-build\">https:\/\/github.com\/devopsprodigy\/test-docker-build<\/a><\/noindex>.<\/p>\n<p>Forr\u00e1s: <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.3 - 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\/hu\/blog\/administrirovanie\/neskolko-sovetov-o-tom-kak-uskorit-sborku-docker-obrazov-naprimer-do-30-sekund\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"hu_HU\" \/>\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\/hu\/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\udd47N\u00e9h\u00e1ny tipp a Docker-k\u00e9pek buildel\u00e9s\u00e9nek felgyors\u00edt\u00e1s\u00e1hoz. P\u00e9ld\u00e1ul 30 m\u00e1sodperc alatt | ProHoster","description":"Miel\u0151tt a funkci\u00f3 \u00e9les k\u00f6rnyezetbe ker\u00fclne, napjaink bonyolult orkestr\u00e1torai \u00e9s CI\/CD folyamatai miatt hossz\u00fa utat kell megtennie a commit-t\u00f3l a tesztel\u00e9sig \u00e9s a sz\u00e1ll\u00edt\u00e1sig.","canonical_url":"https:\/\/prohoster.info\/hu\/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":"hu_HU","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\/hu\/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\/hu\/wp-json\/wp\/v2\/posts\/81600","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/comments?post=81600"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/81600\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media\/81601"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media?parent=81600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/categories?post=81600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/tags?post=81600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}