{"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\/et\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","title":{"rendered":"CI\/CD-ahela loomine ja t\u00f6\u00f6 automatiseerimine Dockeriga","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ma kirjutasin oma esimesed veebilehed 90ndate l\u00f5pus. Siis oli neid k\u00e4ivitada v\u00e4ga lihtne. \u00dcks Apache-server m\u00f5nel jagatud hostimisel, sellele serverile sai sisse logida FTP kaudu, kirjutades brauserisse midagi sellist nagu <code>ftp:\/\/ftp.example.com<\/code>. Siis tuli sisestada nimi ja parool ning laadida failid serverisse. Need olid teised ajad, k\u00f5ik oli siis lihtsam kui praegu.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/488668\/\"><img decoding=\"async\" alt=\"CI\/CD-ahela loomine ja t\u00f6\u00f6 automatiseerimine Dockeriga\" src=\"\/wp-content\/uploads\/2020\/02\/0861cdd82770ef4695ffac7a09777c52.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Viimase kahek\u00fcmne aasta jooksul on palju muutunud. Veebilehed on keerukamaks l\u00e4inud, neid tuleb enne tootmisse saatmist koguda. \u00dcksik server on muutunud paljususeks serveriteks, mis t\u00f6\u00f6tavad koormuse tasakaalustajate taga, ja versioonihalduss\u00fcsteemide kasutamine on saanud tavaliseks.<\/p>\n<p>Minu isikliku projekti jaoks oli mul eriline konfiguratsioon. Ja ma teadsin, et mul on vaja v\u00f5imalust saata veebilehte tootmisse, tehes ainult \u00fche toimingu: koodi salvestamine harusse. <code>master<\/code> GitHubis. Ma teadsin ka, et minu v\u00e4ikeses veebirakenduses t\u00f6\u00f6 tagamiseks ei soovi ma hallata suurt Kubernetes'i klastrit, kasutada Docker Swarmi tehnoloogiat v\u00f5i hoida serverite parki koos podide, agentide ja muude keerukustega. T\u00f6\u00f6 maksimaalse lihtsuse saavutamiseks pidin tutvuma CI\/CD-ga.<\/p>\n<p>Kui teil on v\u00e4ike projekt (antud juhul Node.js projekt) ja soovite teada, kuidas automatiseerida selle projekti juurutamist, tehes nii, et l\u00e4htekood, mis on hoidlas, vastaks t\u00e4pselt sellele, mis t\u00f6\u00f6tab tootmises, siis arvan, et see artikkel v\u00f5ib teid huvitada.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Eeltingimused<\/h2>\n<p>\nOodatakse, et selle artikli lugejal on p\u00f5hiteadmised k\u00e4surea kasutamisest ja Bash-skriptide kirjutamisest. Tal on samuti vajalikud kontod. <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">Travis CI<\/a><\/noindex> ja <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<h2>Eesm\u00e4rgid<\/h2>\n<p>\nMa ei \u00fctle, et see artikkel v\u00f5iks \u00fcldiselt kandideerida \"\u00f5ppejuhiste\" tiitlile. See on pigem dokument, milles ma r\u00e4\u00e4gin sellest, mida olen \u00f5ppinud, ja kirjeldan enda poolt aktsepteeritavat koodi testimise ja juurutamise protsessi tootmises, mis toimub \u00fche automatiseeritud etapi k\u00e4igus.<\/p>\n<p>Selliseks kujunes minu t\u00f6\u00f6protsess.<\/p>\n<p>Koodi, mis saadetakse mistahes repositooriumi harusse peale <code>master<\/code>, teostatakse j\u00e4rgmised toimingud:<\/p>\n<ul>\n<li>Projekti ehitamine Travis CI-s.<\/li>\n<li>Teostatakse k\u00f5ik moodulitestid, integratsioonitestid ja risttestid.<\/li>\n<\/ul>\n<p>\nAinult koodi, mis j\u00f5uab <code>master<\/code>, puhul teostatakse j\u00e4rgmist:<\/p>\n<ul>\n<li>K\u00f5ik eeltoodud, pluss\u2026<\/li>\n<li>Dockeri pildi koostamine, l\u00e4htudes praegusest koodist, seadistustest ja keskkonnast.<\/li>\n<li>Pildi paigutamine Docker Hub-i.<\/li>\n<li>\u00dchendamine tootmiserveriga.<\/li>\n<li>Pildi allalaadimine Docker Hub-ist serverisse.<\/li>\n<li>Praeguse konteineri peatamine ja uue k\u00e4ivitamine, mis p\u00f5hineb uuel pildil.<\/li>\n<\/ul>\n<p>\nKui te ei tea Dockerist, piltidest ja konteineritest mitte midagi \u2014 \u00e4rge muretsege. Ma r\u00e4\u00e4gin sellest k\u00f5ik.<\/p>\n<h2>Mis on CI\/CD?<\/h2>\n<p>\nCI\/CD l\u00fchend t\u00e4histab \u201econtinuous integration\/continuous deployment\u201c \u2013 \u201ekatkestamata integratsioon\/katkestamata juurutamine\u201c.<\/p>\n<h3>\u258dKatkestamata integratsioon<\/h3>\n<p>\nKatkestamata integratsioon on protsess, mille k\u00e4igus arendajad teevad muudatusi projekti peamises koodihaldusmaterjalis (tavaliselt haru <code>master<\/code>). Selle k\u00e4igus tagatakse koodi kvaliteet automaatsete testide kaudu.<\/p>\n<h3>\u258dKatkestamata juurutamine<\/h3>\n<p>\nKatkestamata juurutamine on koodi sagedane automaatne juurutamine tootmises. CI\/CD l\u00fchendi teine osa lahti seletatakse m\u00f5nikord kui \u201econtinuous delivery\u201c (\u201ekatkestamata kohaletoimetamine\u201c). See t\u00e4hendab \u00fcldiselt sama, mis \u201ekatkestamata juurutamine\u201c, kuid \u201ekatkestamata kohaletoimetamine\u201c eeldab k\u00e4sitsi kinnitust muudatuste tegemiseks enne projekti juurutamise protsessi k\u00e4ivitamist.<\/p>\n<h2>Alustamine<\/h2>\n<p>\nRakendus, milles ma seda k\u00f5ike \u00f5ppisin, nimetatakse <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/taniarascia\/takenote\">TakeNote<\/a><\/noindex>. See on veebiprojekt, mille kallal ma t\u00f6\u00f6tan, et teha m\u00e4rkmeid. Alguses p\u00fc\u00fcdsin ma luua <noindex><a rel=\"nofollow\" href=\"https:\/\/jamstack.org\/\">JAMStack<\/a><\/noindex>- projekt v\u00f5i lihtsalt frontend-rakendus ilma serverita, et kasutada standardseid hostimise ja projektide juurutamise v\u00f5imalusi, mida pakub <noindex><a rel=\"nofollow\" href=\"https:\/\/www.netlify.com\/\">Netlify<\/a><\/noindex>. Kui rakenduse keerukus kasvas, pidin looma selle serveripoolse osa, mis t\u00e4hendas, et mul oleks vaja v\u00e4lja t\u00f6\u00f6tada oma strateegia automatiseeritud integreerimise ja rakenduse automatiseeritud juurutamise jaoks.<\/p>\n<p>Minu puhul on rakendus Express-server, mis t\u00f6\u00f6tab Node.js keskkonnas, teenindades \u00fches\u00f5nalist React-rakendust ja toetades turvalist serveripoolset API-d. See arhitektuur j\u00e4rgib strateegiat, mida v\u00f5ib leida <noindex><a rel=\"nofollow\" href=\"https:\/\/www.taniarascia.com\/full-stack-cookies-localstorage-react-express\/\">sellest<\/a><\/noindex> t\u00e4iendavast f\u00fcllstack-i autentimise juhendist.<\/p>\n<p>Konsulteerisin <noindex><a rel=\"nofollow\" href=\"http:\/\/qualitytesting.tech\/\">s\u00f5braga<\/a><\/noindex>, kes on automatiseerimise ekspert, ja k\u00fcsisin temalt, mida peaksin tegema, et k\u00f5ik toimiks nii, nagu ma soovin. Ta viskas mulle idee, kuidas peaks v\u00e4lja n\u00e4gema automatiseeritud t\u00f6\u00f6protsess, nagu on kirjeldatud k\u00e4esoleva artikli jaotises \"Eesm\u00e4rgid\". See, et seadsin endale sarnased eesm\u00e4rgid, t\u00e4hendas, et pean \u00f5ppima, kuidas Dockerit kasutada.<\/p>\n<h2>Docker<\/h2>\n<p>\nDocker on t\u00f6\u00f6riist, mis konteineritehnoloogia abil v\u00f5imaldab lihtsasti rakendusi jagada ning neid sama keskkonna sees juurutada ja k\u00e4ivitada, isegi kui Docker ise t\u00f6\u00f6tab erinevates keskkondades. Alustamiseks pidin hankima endale Docker CLI (komandirealise liidese) t\u00f6\u00f6riistad. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/install\/\">Juhend<\/a><\/noindex> Docker installimiseks ei saa nimetada v\u00e4ga selgeks ja arusaadavaks, kuid sellest saab teada, et esimese sammu tegemiseks tuleb alla laadida Docker Desktop (Maci v\u00f5i Windowsi jaoks).<\/p>\n<p>Docker Hub on umbes nagu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/\">GitHub<\/a><\/noindex> git-repositooriumide jaoks v\u00f5i register <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/\">npm<\/a><\/noindex> JavaScripti pakettide jaoks. See on veebirepositoorium Docker-piltide jaoks. Just selle kaudu \u00fchendub Docker Desktop.<\/p>\n<p>Nii et Dockeriga alustamiseks on vaja teha kaks asja:<\/p>\n<ul>\n<li>Installige <noindex><a rel=\"nofollow\" href=\"https:\/\/www.docker.com\/get-started\">Docker Desktop<\/a><\/noindex>.<\/li>\n<li>Registreeruge <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>\nSeej\u00e4rel saate kontrollida Docker CLI toimimist, k\u00e4ivitades j\u00e4rgmise k\u00e4su Docker'i versiooni kontrollimiseks:<\/p>\n<pre><code class=\"plaintext\">docker -v<\/code><\/pre>\n<p>\nSeej\u00e4rel logige sisse Docker Hub'i, sisestades, kui teilt k\u00fcsitakse, oma kasutajanime ja parooli:<\/p>\n<pre><code class=\"plaintext\">docker login<\/code><\/pre>\n<p>\nDockerit kasutamiseks peate m\u00f5istma piltide ja konteinerite kontseptsioone.<\/p>\n<h3>\u258dPildid<\/h3>\n<p>\nPilt on nagu plaan, mis sisaldab juhiseid konteineri kokkupanemiseks. See on muutumatu failis\u00fcsteemi ja rakenduse seadete snapshot. Arendajad saavad h\u00f5lpsasti pilte vahetada.<\/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>\nSee k\u00e4sk v\u00e4ljastab tabeli j\u00e4rgmise pealkirjaga:<\/p>\n<pre><code class=\"plaintext\">REPOSITORY \u00a0 \u00a0 TAG \u00a0 \u00a0 IMAGE ID \u00a0 \u00a0 CREATED \u00a0 \u00a0 SIZE\n---<\/code><\/pre>\n<p>\nJ\u00e4tkame m\u00f5ne k\u00e4skluse n\u00e4idete uurimist samas formaadis \u2014 esmalt on k\u00e4sk koos kommentaariga ja seej\u00e4rel on n\u00e4ide, mida see v\u00f5ib v\u00e4lja anda.<\/p>\n<h3>\u258dKonteinerid<\/h3>\n<p>\nKonteiner on teadetav pakett, mis sisaldab k\u00f5ike, mis vajalik rakenduse k\u00e4itamiseks. Selle l\u00e4henemisega t\u00f6\u00f6tab rakendus alati sama s\u00f5ltumata infrastruktuurist: eraldatud keskkonnas ja samas keskkonnas. See t\u00e4hendab, et erinevates keskkondades k\u00e4ivitatakse sama pildi eksemplare.<\/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>\u258dSildid<\/h3>\n<p>\nSilt on n\u00e4itaja konkreetse pildi versioonile.<\/p>\n<h3>\u258dDocker'i k\u00e4skude l\u00fchike \u00fclevaade<\/h3>\n<p>\nSiin on \u00fclevaade m\u00f5nest sageli kasutatavast Docker'i k\u00e4skudest.<\/p>\n<p>Meeskond<\/p>\n<p>Kontekst<\/p>\n<p>Tegevus<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/build\/\">docker build<\/a><\/noindex><\/p>\n<p>Pilt<\/p>\n<p>Pildi koostamine Dockerfile'ist<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/tag\/\">docker tag<\/a><\/noindex><\/p>\n<p>Pilt<\/p>\n<p>Pildi sildistamine<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/images\/\">docker images<\/a><\/noindex><\/p>\n<p>Pilt<\/p>\n<p>Piltide loendi v\u00e4ljastamine<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/run\/\">docker run<\/a><\/noindex><\/p>\n<p>Konteiner<\/p>\n<p>Konteineri k\u00e4ivitamine pildi p\u00f5hjal<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/push\/\">docker push<\/a><\/noindex><\/p>\n<p>Pilt<\/p>\n<p>Pildi saatmine registrisse<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/about:blank\">docker pull<\/a><\/noindex><\/p>\n<p>Pilt<\/p>\n<p>Pildi allalaadimine registrist<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/ps\/\">docker ps<\/a><\/noindex><\/p>\n<p>Konteiner<\/p>\n<p>Konteinerite loendi v\u00e4ljastamine<\/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>Pilt\/Konteiner<\/p>\n<p>Kasutamata konteinide ja piltide eemaldamine<\/p>\n<h3>\u258dDockerfile<\/h3>\n<p>\nMa tean, kuidas kohalikult rakendust produtsiooniks k\u00e4ivitada. Mul on Webpack-i konfiguratsioon, mis on m\u00f5eldud valmis React-rakenduse koostamiseks. Edasi on mul k\u00e4sk, mis k\u00e4ivitab Node.js-p\u00f5hise serveri porti <code>5000<\/code>. See n\u00e4eb v\u00e4lja nii:<\/p>\n<pre><code class=\"plaintext\">npm i          # s\u00f5ltuvuste installimine\nnpm run build # React-i rakenduse koostamine\nnpm run start # Node-serveri k\u00e4ivitamine<\/code><\/pre>\n<p>\nOluline on m\u00e4rkida, et mul ei ole selle materjali jaoks n\u00e4idisrakendust. Kuid siia sobib katsetamiseks \u00fcksk\u00f5ik milline lihtne Node-rakendus.<\/p>\n<p>Konteineri kasutamiseks peate andma Dockerile juhised. Seda tehakse faili kaudu, mida nimetatakse <code>Dockerfile<\/code>, mis asub projekti p\u00f5hikaustas. See fail n\u00e4ib alguses \u00fcsna arusaamatu.<\/p>\n<p>Kuid see, mis seal on, kirjeldab lihtsalt eriliste k\u00e4sudega midagi, mis sarnaneb t\u00f6\u00f6keskkonna seadistamisega. Siin on m\u00f5ned neist k\u00e4skudest:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#from\">FROM<\/a><\/noindex> \u2014 See k\u00e4sk k\u00e4ivitab faili. Selles m\u00e4\u00e4ratakse aluskuju, mille p\u00f5hjal konteiner ehitatakse.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#copy\">COPY<\/a><\/noindex> \u2014 Failide kopeerimine kohaliku allika ja konteineri vahel.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#workdir\">WORKDIR<\/a><\/noindex> \u2014 T\u00f6\u00f6katalooge seadmine j\u00e4rgmiste k\u00e4su jaoks.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#run\">RUN<\/a><\/noindex> \u2014 K\u00e4skude k\u00e4ivitamine.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#expose\">EXPOSE<\/a><\/noindex> \u2014 Porti seadmine.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/#entrypoint\">ENTRYPOINT<\/a><\/noindex> \u2014 Teostatava k\u00e4su m\u00e4\u00e4ramine.<\/li>\n<\/ul>\n<p>\n<code>Dockerfile<\/code> v\u00f5ib n\u00e4ha umbes nii:<\/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>\nValitud p\u00f5hja p\u00f5hjal v\u00f5ib osutuda vajalikuks installida t\u00e4iendavaid s\u00f5ltuvusi. M\u00f5ned p\u00f5hjad (nagu Node Alpine Linux) on loodud v\u00f5imalikult kompaktseks. Tulemuseks v\u00f5ib olla, et neis puuduvad m\u00f5ned programmid, mida te ootate.<\/p>\n<h3>\u258dKonteineri ehitamine, sildistamine ja k\u00e4ivitamine<\/h3>\n<p>\nKohalik konteineri ehitamine ja k\u00e4ivitamine \u2014 see on p\u00e4rast seda, kui meil on <code>Dockerfile<\/code>, \u00fcsna lihtsad \u00fclesanded. Enne pildi saatmist Docker Hub'i tuleb see kohapeal testida.<\/p>\n<h3>\u258dEhitamine<\/h3>\n<p>\nEsimese sammuna tuleb ehitada <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/build\/\">pildi<\/a><\/noindex>, m\u00e4\u00e4rates nime ja, mitte kohustuslikult, sildi (kui sild ei ole m\u00e4\u00e4ratud, m\u00e4\u00e4rab s\u00fcsteem automaatselt pildile sildi <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>\nSelle k\u00e4su t\u00e4itmisel saab j\u00e4lgida, kuidas Docker ehitab pilti.<\/p>\n<pre><code class=\"plaintext\">Saadan ehituskonteksti Docker daemonile \u00a0 2.88MB\nSamm 1\/9 : FROM node:12-alpine\n\u00a0---&gt; ...ehitusetapid on k\u00e4imas...\nEhitamine \u00f5nnestus 123456789123\nEhitamine sildistatud &lt;image&gt;:&lt;tag&gt;<\/code><\/pre>\n<p>\nEhitamine v\u00f5ib v\u00f5tta paar minutit \u2014 see s\u00f5ltub sellest, kui palju s\u00f5ltuvusi teil on. P\u00e4rast ehitamise l\u00f5petamist saate k\u00e4ivitada k\u00e4su <code>docker images<\/code> ja vaadata oma uue pildi kirjeldust.<\/p>\n<pre><code class=\"plaintext\">REPOSITORY          TAG               IMAGE ID              CREATED              SIZE\n             latest            123456789123        About a minute ago   x.xxGB<\/code><\/pre>\n<p><\/p>\n<h3>\u258dK\u00e4ivitamine<\/h3>\n<p>\nPilt on loodud. See t\u00e4hendab, et selle alusel saab konteineri k\u00e4ivitada. Kuna soovin, et mul oleks juurdep\u00e4\u00e4s konteineris t\u00f6\u00f6levale rakendusele aadressilt <code>localhost:5000<\/code>, siis m\u00e4\u00e4rasin vasakul paaris <code>5000:5000<\/code> j\u00e4rgmises k\u00e4sus <code>5000<\/code>. Paremal on konteineri port.<\/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>\nN\u00fc\u00fcd, kui konteiner on loodud ja k\u00e4ivitatud, saab kasutada k\u00e4sku <code>docker ps<\/code> konteineri \u00fclevaate vaatamiseks (v\u00f5i v\u00f5ib kasutada k\u00e4sku <code>docker ps -a<\/code>, mis kuvab teavet k\u00f5igi konteiners, mitte ainult t\u00f6\u00f6tavate kohta).<\/p>\n<pre><code class=\"plaintext\">CONTAINER ID\u00a0 \u00a0 \u00a0 \u00a0 IMAGE               COMMAND\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 CREATED              STATUS                  \u00a0 \u00a0 PORTS                    NAMES\n987654321234\u00a0 \u00a0 \u00a0 \u00a0 &lt;image&gt;             &quot;\/bin\/sh -c 'npm run\u2026&quot; \u00a0 6 seconds ago        Up 6 seconds            \u00a0 \u00a0 0.0.0.0:5000-&gt;5000\/tcp   stoic_darwin<\/code><\/pre>\n<p>\nKui minna n\u00fc\u00fcd aadressile <code>localhost:5000<\/code> \u2014 saab n\u00e4ha t\u00f6\u00f6tava rakenduse lehte, mis n\u00e4eb v\u00e4lja t\u00e4pselt sama nagu tootmis\u00fcmp\u00e4rves t\u00f6\u00f6tava rakenduse leht.<\/p>\n<h3>\u258dSildi m\u00e4\u00e4ramine ja avaldamine<\/h3>\n<p>\nEttevalmistatakse, et kasutada \u00fchte loodud pilti tootmisserveris, peab meil olema v\u00f5imalus laadida see pilt Docker Hubist. See t\u00e4hendab, et k\u00f5igepealt tuleb luua Docker Hubis projekti jaoks hoidla. P\u00e4rast seda on meil koht, kuhu pilt saata. Pilt tuleb nimetada nii, et selle nimi algab meie kasutajanimega Docker Hubis. Peale seda tuleb hoidla nimi. Nime l\u00f5pus v\u00f5ib olla mis tahes silt. Allpool on n\u00e4idatud n\u00e4ide piltide nimetamisest selle skeemi j\u00e4rgi.<\/p>\n<p>N\u00fc\u00fcd saame luua pildi, andes talle uue nime ja kasutades k\u00e4sku <code>docker push<\/code> selle saatmiseks Docker Hubi hoidlasse.<\/p>\n<pre><code class=\"plaintext\">docker build -t \/: .\ndocker tag \/: \/:latest\ndocker push \/:\n\n# Praktiliselt v\u00f5ib see v\u00e4lja n\u00e4ha n\u00e4iteks nii:\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>\nKui k\u00f5ik l\u00e4heb h\u00e4sti, on pilt saadaval Docker Hubis ja selle saab lihtsalt laadida serverisse v\u00f5i edastada teistele arendajatele.<\/p>\n<h2>J\u00e4rgmised sammud<\/h2>\n<p>\nK\u00e4esolevaks ajaks oleme veendunud, et rakendus Docker-konteinerina t\u00f6\u00f6tab kohapeal. Oleme konteineri \u00fcles laadinud Docker Hubi. See k\u00f5ik t\u00e4hendab, et oleme juba v\u00e4ga h\u00e4sti eesm\u00e4rgi poole edenenud. N\u00fc\u00fcd tuleb lahendada veel kaks k\u00fcsimust:<\/p>\n<ul>\n<li>CI-t\u00f6\u00f6riista seadistamine koodi testimiseks ja juurutamiseks.<\/li>\n<li>Tootmiserveri seadistamine nii, et see saaks meie koodi laadida ja k\u00e4ivitada.<\/li>\n<\/ul>\n<p>\nMeie puhul kasutatakse CI\/CD lahendusena <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">Travis CI<\/a><\/noindex>. Serverina kasutatakse \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/\">DigitalOcean<\/a><\/noindex>.<\/p>\n<p>Tuleb m\u00e4rkida, et siin on v\u00f5imalik kasutada ka teisi teenuste kombinatsioone. N\u00e4iteks Travis CI asemel v\u00f5ib kasutada CircleCI v\u00f5i Github Actions. Ja DigitalOcean'i asemel \u2014 AWS v\u00f5i Linode.<\/p>\n<p>Otsustasime t\u00f6\u00f6tada Travis CI-ga, ja selles teenuses on mul juba m\u00f5ned seadistused olemas. Seega r\u00e4\u00e4gin n\u00fc\u00fcd l\u00fchidalt, kuidas seda t\u00f6\u00f6ks ette valmistada.<\/p>\n<h2>Travis CI<\/h2>\n<p>\nTravis CI on t\u00f6\u00f6riist koodi testimiseks ja juurutamiseks. Ei olnud soovist minna s\u00fcvitsi Travis CI seadistamise n\u00fcanssidega, kuna iga projekt on ainulaadne ja see ei too erilist kasu. Kuid r\u00e4\u00e4gin p\u00f5hialustest, mis v\u00f5imaldavad teil alustada, kui otsustate kasutada Travis CI-d. \u00dcksk\u00f5ik, kas valite Travis CI, CircleCI, Jenkins v\u00f5i midagi muud, kasutatakse sarnaseid seadistusmeetodeid.<\/p>\n<p>Kuna alustada Travis CI kasutamist, minge aadressile <noindex><a rel=\"nofollow\" href=\"https:\/\/travis-ci.org\/\">projekti veebilehe<\/a><\/noindex> ja looge konto. Seej\u00e4rel integreerige Travis CI oma GitHubi kontoga. Seadistamise k\u00e4igus peate n\u00e4itama repositooriumi, millega soovite automatiseeritud t\u00f6\u00f6d teha, ning andma sellele juurdep\u00e4\u00e4su. (Kasutades GitHubi, kuid olen kindel, et Travis CI saab integreeruda ka BitBucketi, GitLabi ja teiste sarnaste teenustega).<\/p>\n<p>Iga kord, kui Travis CI alustab t\u00f6\u00f6d, k\u00e4ivitub server, mis t\u00e4idab konfiguratsioonifailis m\u00e4\u00e4ratud k\u00e4ske, sealhulgas vastavate harude repositooriumi juurutamist.<\/p>\n<h3>\u258d\u00dclesande eluts\u00fckkel<\/h3>\n<p>\nTravis CI konfiguratsioonifail, mida nimetatakse <code>.travis.yml<\/code> ja ja hoitav, mis asub projekti juurkaustas, toetab s\u00fcndmuste kontseptsiooni <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.travis-ci.com\/user\/job-lifecycle\/\">eluring<\/a><\/noindex> \u00fclesanne. Siin on need s\u00fcndmused, esitatud j\u00e4rjekorras, milles need juhtuvad:<\/p>\n<ul>\n<li><code>apt lisandmoodulid<\/code><\/li>\n<li><code>vahem\u00e4lu komponendid<\/code><\/li>\n<li><code>enne_installeerimist<\/code><\/li>\n<li><code>install<\/code><\/li>\n<li><code>before_script<\/code><\/li>\n<li><code>script<\/code><\/li>\n<li><code>enne_vahem\u00e4lu<\/code><\/li>\n<li><code>p\u00e4rast_\u00f5nnestumist v\u00f5i p\u00e4rast_eba\u00f5nnestumist<\/code><\/li>\n<li><code>enne_deployimist<\/code><\/li>\n<li><code>deploy<\/code><\/li>\n<li><code>p\u00e4rast_deployimist<\/code><\/li>\n<li><code>p\u00e4rast_skripti<\/code><\/li>\n<\/ul>\n<p><\/p>\n<h3>\u258dTestimine<\/h3>\n<p>\nKonfiguratsioonifailis kavatsen seadistada kohaliku Travis CI serveri. Keeleks valisin Node 12 versiooni ja n\u00e4itasin s\u00fcsteemile, et see peab installima s\u00f5ltuvused, mis on vajalikud Docker'i kasutamiseks.<\/p>\n<p>K\u00f5ik, mis on loetletud <code>.travis.yml<\/code>, k\u00e4ivitatakse k\u00f5ikide pull-p\u00e4ringute puhul k\u00f5igis ladude harudes, v\u00e4lja arvatud juhul, kui on m\u00e4\u00e4ratud teisiti. See on kasulik omadus, kuna see t\u00e4hendab, et saame testida kogu koodi, mis laekub ladudele. See aitab teada, kas kood on valmis haru kirjutamiseks <code>master<\/code>, ja ei riku projekti ehitamise protsessi. Selles globaalsetes seadistustes installin k\u00f5ik kohalikult, k\u00e4ivitan Webpack arendaja serveri taustal (see on minu t\u00f6\u00f6protsessi spetsiifika) ja sooritan testid.<\/p>\n<p>Kui soovite, et teie ladudes kuvataks koodi katte teabe ikoone, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.taniarascia.com\/display-build-status-and-test-coverage\/\">siin<\/a><\/noindex> v\u00f5ite leida l\u00fchikese juhendi Jest'i, Travis CI ja Coveralls'i kasutamiseks nende andmete kogumiseks ja esitamiseks.<\/p>\n<p>Nii et siin on faili sisu <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>\nSiin l\u00f5pevad k\u00f5ik tegevused, mida t\u00e4idetakse k\u00f5igi hoidla harude ja pull-k\u00fcsimuste jaoks.<\/p>\n<h3>\u258dDeployment<\/h3>\n<p>\nEeldades, et k\u00f5ik automatiseeritud testid on edukalt l\u00f5petatud, saame vajadusel koodi tootmisse serverisse edastada. Kuna soovime seda teha ainult haru koodiga <code>master<\/code>, anname s\u00fcsteemile vastavad juhised paigaldamise seadetes. Enne kui proovite oma projektis koodi, millest edasi r\u00e4\u00e4gime, sooviksin teid hoiatada, et teil peab olema reaalne skript, mida kasutatakse paigaldamiseks.<\/p>\n<pre><code class=\"plaintext\">deploy:\n  # Koguda Docker konteiner ja saata see Docker Hub'isse\n  provider: script\n  script: bash deploy.sh\n  on:\n    branch: master<\/code><\/pre>\n<p>\nPaigaldusskript t\u00e4idab kahte \u00fclesannet:<\/p>\n<ul>\n<li>Konteineri koostamine, sildistamine ja saatmine Docker Hub'i CI-t\u00f6\u00f6riista (meie puhul Travis CI) abil.<\/li>\n<li>Pildi laadimine serverisse, vana konteineri peatamine ja uue k\u00e4ivitamine (meie puhul t\u00f6\u00f6tab server DigitalOcean'i platvormil).<\/li>\n<\/ul>\n<p>\nEsiteks tuleb seadistada automaatne build'i, m\u00e4rgistamise ja pildi saatmise protsess Docker Hub'i. K\u00f5ik see sarnaneb v\u00e4ga sellele, mida oleme juba k\u00e4sitsi teinud, v\u00e4lja arvatud see, et siin on meil vaja strateegiat, kuidas m\u00e4\u00e4rata piltidele unikaalsed m\u00e4rgid ja automatiseerida sisselogimist. Mul olid m\u00f5ned probleemid deploy skripti detailidega, nagu m\u00e4rgistamisstrateegia, sisselogimine, SSH v\u00f5tmete kodeerimine, SSH \u00fchenduse loomine. \u00d5nneks on mu poiss-s\u00f5ber bashiga v\u00e4ga osav, nagu ka paljude muude asjadega. Ta aitas mul selle skripti kirjutada.<\/p>\n<p>Nii et skripti esimene osa \u2014 see on pildi saatmine Docker Hub'i. Seda on suhteliselt lihtne teha. Minu kasutatud m\u00e4rgistusmeetod p\u00f5hineb git-hash'i ja git-m\u00e4rgise, kui see eksisteerib, kombineerimisel. See tagab unikaalse m\u00e4rgi loomise ja lihtsustab build'i tuvastamist, millele see p\u00f5hineb. <code>DOCKER_USERNAME<\/code> ja <code>DOCKER_PASSWORD<\/code> \u2014 need on kasutaja keskkonnamuutujad, mille saab seada Travis CI liidese kaudu. Travis CI k\u00e4sitleb automaatselt salajasi andmeid nii, et need ei satuks valedesse k\u00e4tesse.<\/p>\n<p>Siin on skripti esimene osa <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>\nTeise osa skripti sisu s\u00f5ltub t\u00e4ielikult sellest, millist hostimist kasutate ja kuidas sellele on \u00fchendus korraldatud. Minu puhul kasutan ma Digital Ocean'i, kus serveriga \u00fchendamiseks kasutatakse k\u00e4ske <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/digitalocean\/doctl\">doctl<\/a><\/noindex>. AWS-i puhul kasutatakse t\u00f6\u00f6riista <code>aws<\/code>, ja nii edasi.<\/p>\n<p>Serveri seadistamine ei olnud eriti keeruline. Nii s\u00e4ttisin ma dropleti, mis p\u00f5hines p\u00f5hiversioonil. Tuleb m\u00e4rkida, et valitud s\u00fcsteem vajab Docker'i \u00fchekordset k\u00e4sitsi installimist ja Docker'i \u00fchekordset k\u00e4sitsi k\u00e4ivitamist. Mina kasutasin Docker'i installimiseks Ubuntu 18.04, seega kui kasutate samuti Ubuntu't, v\u00f5ite lihtsalt j\u00e4rgida <noindex><a rel=\"nofollow\" href=\"https:\/\/phoenixnap.com\/kb\/how-to-install-docker-on-ubuntu-18-04\">seda<\/a><\/noindex> lihtsat juhendit.<\/p>\n<p>Ma ei r\u00e4\u00e4gi siin konkreetsetest k\u00e4skudest teenusele, kuna see aspekt v\u00f5ib erinevatel juhtudel olla v\u00e4ga erinev. Toon lihtsalt v\u00e4lja \u00fcldise tegevuskava, mis tuleb l\u00e4bi viia p\u00e4rast SSH kaudu serverisse \u00fchendamist, kus projekt k\u00e4ivitatakse:<\/p>\n<ul>\n<li>Peate leidma konteineri, mis praegu t\u00f6\u00f6tab, ja peatama selle.<\/li>\n<li>Seej\u00e4rel peate taustal k\u00e4ivitama uue konteineri.<\/li>\n<li>Kohalik serveri port tuleb seada v\u00e4\u00e4rtusele <code>80<\/code> \u2014 see v\u00f5imaldab p\u00e4\u00e4seda veebisaidile aadressil <code>example.com<\/code>, ilma pordi m\u00e4\u00e4ramiseta, mitte kasutades aadressi nagu <code>example.com:5000<\/code>.<\/li>\n<li>Ja l\u00f5puks tuleb eemaldada k\u00f5ik vanad konteinerid ja pildid.<\/li>\n<\/ul>\n<p>\nSiin on skripti j\u00e4tk.<\/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>M\u00f5ned asjad, millele tasub t\u00e4helepanu p\u00f6\u00f6rata<\/h2>\n<p>\nV\u00f5ib juhtuda, et kui \u00fchendate end serveriga SSH kaudu Travis CI-st, n\u00e4ete hoiatust, mis takistab paigaldamise j\u00e4tkamist, kuna s\u00fcsteem ootab kasutaja reaktsiooni.<\/p>\n<pre><code class=\"plaintext\">The authenticity of host ' ()' can't be established.\nRSA key fingerprint is .\nAre you sure you want to continue connecting (yes\/no)?<\/code><\/pre>\n<p>\nOlen teada saanud, et stringi v\u00f5tme saab kodeerida base64 formaati, et salvestada see sellisel viisil, millega on mugav ja usaldusv\u00e4\u00e4rne t\u00f6\u00f6tada. Installimise etapis saab avaliku v\u00f5tme dekodeerida ja salvestada faili <code>known_hosts<\/code> et vabaneda eeltoodud veast.<\/p>\n<pre><code class=\"plaintext\">echo  | base64 # v\u00e4ljastab .<\/code><\/pre>\n<p>\nTavas praktikas v\u00f5ib see k\u00e4sk v\u00e4lja n\u00e4ha selline:<\/p>\n<pre><code class=\"plaintext\">echo &quot;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&quot; | base64<\/code><\/pre>\n<p>\nNii on, kuidas see v\u00e4lja n\u00e4eb \u2014 rida base64-koodis:<\/p>\n<pre><code class=\"plaintext\">MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2punMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==<\/code><\/pre>\n<p>\nSiin on k\u00e4sk, millest varem r\u00e4\u00e4giti<\/p>\n<pre><code class=\"plaintext\">install:\n  - echo  | base64 -d &gt;&gt; $HOME\/.ssh\/known_hosts<\/code><\/pre>\n<p>\nSama l\u00e4henemist v\u00f5ib kasutada ka privaatv\u00f5tme puhul \u00fchenduse loomisel, kuna serverisse p\u00e4\u00e4semiseks v\u00f5ib teil olla vajalik privaatv\u00f5ti. T\u00f6\u00f6 k\u00e4igus v\u00f5tmega tuleb lihtsalt kindlustada selle turvaline hoidmine Travis CI keskkonnamuutujas ning et see ei v\u00e4ljenduks kunagi.<\/p>\n<p>Veel \u00fcks asi, millele tasub t\u00e4helepanu p\u00f6\u00f6rata, on see, et peate v\u00f5ib-olla k\u00e4ivitama kogu juurutusskripti, esitatuna \u00fches reas, n\u00e4iteks \u2014 kasutades <code>doctl<\/code>. See v\u00f5ib n\u00f5uda m\u00f5ningaid t\u00e4iendavaid j\u00f5upingutusi.<\/p>\n<pre><code class=\"plaintext\">doctl compute ssh &lt;droplet&gt; --ssh-command &quot;\u0432\u0441\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u0437\u0434\u0435\u0441\u044c &amp;&amp; \u0437\u0434\u0435\u0441\u044c&quot;<\/code><\/pre>\n<p><\/p>\n<h2>TLS\/SSL ja koormuse tasakaalustamine<\/h2>\n<p>\nP\u00e4rast seda, kui ma tegin k\u00f5ike eelnevat, oli viimane probleem, millega ma silmitsi seisn, see, et serveril puudus SSL. Kuna kasutan Node.js serverit, et lasta <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\u00f6\u00f6tada<\/a><\/noindex> Nginxi p\u00f6\u00f6rdproksil ja Let\u2019s Encrypt'il on vaja palju vaeva n\u00e4ha.<\/p>\n<p>Ma ei soovinud neid SSL-seadeid k\u00e4sitsi teha, seet\u00f5ttu l\u00f5in lihtsalt koormustasakaidaja ja salvestasin selle andmed DNS-i. N\u00e4iteks DigitalOceanis on automaatselt uueneva isesigneeritud sertifikaadi loomine koormustasakaidajal lihtne, tasuta ja kiire protseduur. Selle l\u00e4henemise eeliste hulka kuulub ka asjaolu, et see v\u00f5imaldab vajadusel v\u00e4ga lihtsalt seadistada SSL-i paljudele serveritele, mis t\u00f6\u00f6tavad koormustasakaidja taga. See t\u00e4hendab, et serverid ei pea SSL-i osas \u00fcldse \u201emuretsema\u201d, kuid v\u00f5ivad siiski kasutada porti tavap\u00e4raselt. <code>80<\/code>Nii et SSL-i seadistamine koormustasakaidjal on tunduvalt lihtsam ja mugavam kui alternatiivsed SSL-i seadistamise meetodid.<\/p>\n<p>N\u00fc\u00fcd saab serveris sulgeda k\u00f5ik sisenevaid \u00fchendusi aktsepteerivad pordid \u2014 v\u00e4lja arvatud port <code>80<\/code>, mida kasutatakse koormustasakaidjaga suhtlemiseks, ja port <code>22<\/code> SSH jaoks. Seet\u00f5ttu eba\u00f5nnestub otse serverisse p\u00f6\u00f6rdumine mistahes pordile, v\u00e4lja arvatud need kaks.<\/p>\n<h2>Kokkuv\u00f5te<\/h2>\n<p>\nP\u00e4rast seda, kui olin teinud k\u00f5ike, millest selles materjalis r\u00e4\u00e4kisin, ei h\u00e4irinud mind enam ei platvorm Docker ega automatiseeritud CI\/CD ahelate kontseptsioonid. Olin suutnud seadistada pideva integreerimise ahela, mille k\u00e4igus testitakse koodi enne selle j\u00f5udmist tootmisse ja toimub automaatne koodi juurutamine serverisse. See k\u00f5ik on minu jaoks veel suhteliselt uus ja olen kindel, et on olemas viise, kuidas oma automatiseeritud t\u00f6\u00f6protsessi parandada ja efektiivsemaks muuta. Seet\u00f5ttu, kui teil on selle kohta ideid \u2014 andke <noindex><a rel=\"nofollow\" href=\"mailto:hello@taniarascia.com\">mulle<\/a><\/noindex> teada. Loodan, et see artikkel aitas teid teie tegemistes. Soovin uskuda, et lugedes sellest, \u00f5ppisite te sama palju, kui mina, kui sellega tegelema hakkasin.<\/p>\n<p><b>P.S.<\/b> Meie <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/marketplace#order\">turul<\/a><\/noindex> on olemas pilt <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/marketplace\/docker#advantages\">Docker<\/a><\/noindex>, mis installitakse \u00fche kl\u00f5psuga. Saate kontrollida konteinerite t\u00f6\u00f6d <noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/\">VPS<\/a><\/noindex>. K\u00f5igile uutele klientidele antakse tasuta 3 p\u00e4eva katsetamiseks.<\/p>\n<p><b>Lugupidamisega lugejad!<\/b> Kasutate tehnoloogiaid CI\/CD oma projektides?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"CI\/CD-ahela loomine ja t\u00f6\u00f6 automatiseerimine Dockeriga\" src=\"\/wp-content\/uploads\/2020\/02\/3fbfa90ea56a3d9b6b89ba945eb94570.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Allikas: <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 4.9.10 - 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. \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\" \/>\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\/et\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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. \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/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\udd47CI\/CD ahela loomine ja t\u00f6\u00f6 automatiseerimine Dockeriga | ProHoster","description":"Ma alustasin oma esimeseid veebisaite 90-ndate l\u00f5pus. Toona oli neid t\u00f6\u00f6le saada v\u00e4ga lihtne. Oli Apache-server m\u00f5nes jagatud hostimises, millele sai ligi FTP kaudu, kirjutades brauseri aadressiribale midagi sellist nagu ftp:\/\/ftp.example.com. Siis tuli sisestada kasutajanimi ja parool ning laadida failid serverisse. Need olid teised ajad, k\u00f5ik oli siis.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/sozdanie-ci-cd-czepochki-i-avtomatizacziya-raboty-s-docker","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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. \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","og:url":"https:\/\/prohoster.info\/et\/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":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 19:24:45","updated":"2022-09-28 11:40:45"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/69351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=69351"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/69351\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/69352"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=69351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=69351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=69351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}