{"id":32217,"date":"2019-10-31T21:45:43","date_gmt":"2019-10-31T18:45:43","guid":{"rendered":"https:\/\/prohoster.info\/blog\/net-core-na-linux-devops-na-kone\/"},"modified":"2019-10-31T21:45:43","modified_gmt":"2019-10-31T18:45:43","slug":"net-core-na-linux-devops-na-kone","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core na Linuxu, DevOps na konju","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Razvijali smo DevOps koliko smo mogli. Bilo nas je 8, a Vasa je bio najja\u010di po Windowsu. Iznenada je Vasa oti\u0161ao, a meni je zada\u0107a bila pokrenuti novi projekt koji se bavi Windows razvojem. Kada sam stavio sav Windows razvoj na stol, shvatio sam da situacija boli...<\/p>\n<p>Tako po\u010dinje pri\u010da <b>Aleksandra Sin\u010dinova<\/b> na <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. Kada je iz kompanije oti\u0161ao vode\u0107i stru\u010dnjak za Windows, Aleksandar se zapitao \u0161to sada raditi. Naravno, pre\u0107i na Linux! Aleksandar \u0107e ispri\u010dati kako je uspio stvoriti presedan i prevesti dio Windows razvoja na Linux na primjeru realiziranog projekta sa 100.000 krajnjih korisnika.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKako lako i neprimjetno donijeti projekt u RPM, koriste\u0107i TFS, Puppet, Linux .NET core? Kako odr\u017eavati verzioniranje DB-a projekta kada razvoj prvi put \u010duje rije\u010di Postgres i Flyway, a rok je sutra? Kako integrirati s Dockerom? Kako motivirati .NET programere da se odrgnu od Windowsa i smoothija u korist Puppeta i Linuxa? Kako rije\u0161iti ideolo\u0161ke sukobe kad odr\u017eavanje Windowsa u produkciji nije opcija niti iz snova? O tome, kao i o Web Deploy, testiranju, CI, praksama kori\u0161tenja TFS-a u postoje\u0107im projektima, i naravno, o slomljenim \u0161takama i funkcionalnim rje\u0161enjima, detaljno govori Aleksandar.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"tZH9Ro9j9KQ\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/tZH9Ro9j9KQ\/hqdefault.jpg\" alt=\"Pogledajte video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nDakle, Vasa je oti\u0161ao, zadatak je na meni, a programeri \u010dekaju s vilama nestrpljivo. Kada sam kona\u010dno shvatio da Vasine povratka nema, krenuo sam na posao. Prvo sam ocijenio postotak Win VM-a u na\u0161em parku. Broj nije bio na strani Windowsa.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBudu\u0107i da aktivno razvijamo DevOps, shvatio sam da je potrebno ne\u0161to promijeniti u pristupu uvo\u0111enju nove aplikacije. Rje\u0161enje je bilo jedno - prevesti sve na Linux kad god je to mogu\u0107e. Google mi je pomogao - u to vrijeme .NET je ve\u0107 bio portiran na Linux, i shvatio sam da je to rje\u0161enje!<\/p>\n<h2>Za\u0161to .NET core u kombinaciji s Linuxom?<\/h2>\n<p>\nPostojalo je nekoliko razloga za to. Izme\u0111u \u201epla\u0107anja novca\u201c i \u201ene pla\u0107anja\u201c, ve\u0107ina \u0107e odabrati drugo - kao i ja. Licenca za MSDB ko\u0161ta oko 1000 $, odr\u017eavanje parka virtualnih ma\u0161ina Windows ko\u0161ta stotine dolara. Za veliku kompaniju to su veliki tro\u0161kovi. Zato <b>\u0161tednja\u00a0<\/b>\u2014<b> prvi razlog<\/b>. Nije najva\u017eniji, ali jedan od zna\u010dajnijih.<\/p>\n<p>Windows virtualne ma\u0161ine tro\u0161e vi\u0161e resursa od svojih Linux ro\u0111aka - <b>te\u0161ke su<\/b>. Uzimaju\u0107i u obzir veli\u010dinu velike kompanije, odabrali smo Linux.<\/p>\n<p><b>Sustav se jednostavno integrira u postoje\u0107i CI.<\/b>. Smatramo se progresivnim DevOps-ima, koristimo Bamboo, Jenkins i GitLab CI, pa se ve\u0107ina na\u0161eg rada vrti na Linuxu.<\/p>\n<p>Posljednji razlog je <b>prakti\u010dna podr\u0161ka. <\/b>Trebalo nam je smanjiti barijeru ulaska za 'podupira\u010de' \u2013 ljude koji razumiju tehni\u010dki dio, osiguravaju kontinuitet i podr\u017eavaju usluge druge linije. Ve\u0107 su bili upoznati sa stekom Linux, pa im je puno lak\u0161e razumjeti novi proizvod, podr\u017eavati ga i odr\u017eavati nego tro\u0161iti dodatne resurse kako bi se sna\u0161li s sli\u010dnom funkcionalno\u0161\u0107u softvera za Windows.<\/p>\n<h2>Zahtjevi<\/h2>\n<p>\nPrvo i najva\u017enije \u2013 <b>prikladnost novog rje\u0161enja za programere.<\/b>. Nisu svi bili spremni za promjene, osobito nakon spomenutog imena Linux. Programeri \u017eele svoju omiljenu Visual Studio, TFS s automatskim testovima za buildove i smoothie. Na\u010din na koji se isporu\u010duje u produkciju \u2013 njima nije va\u017eno. Zato smo odlu\u010dili ne mijenjati uobi\u010dajen postupak i ostaviti sve nepromijenjeno za Windows programere. <\/p>\n<p>Novi projekt treba <b>integrirati u postoje\u0107i CI.<\/b>. Pruge su ve\u0107 postojale i sav posao morao se obaviti uzimaju\u0107i u obzir parametre sustava upravljanja konfiguracijom, usvojene standarde isporuke i sustave nadzora.<\/p>\n<p><b>Jednostavnost podr\u0161ke i eksploatacije<\/b>, kao uvjet za minimalnu barijeru ulaska za sve nove sudionike iz razli\u010ditih odjela i odjela potpore.<\/p>\n<p><b>Rok je bio ju\u010der.<\/b>.<\/p>\n<h2>Grupa Win razvoja.<\/h2>\n<p>\nS \u010dim je tada radila Windows ekipa?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSada mogu sigurno re\u0107i da <b>IdentityServer4<\/b>\u00a0je fantasti\u010dna besplatna alternativa ADFS-u s sli\u010dnim mogu\u0107nostima, ili da <b>Entity Framework Core<\/b>\u00a0je raj za programera, gdje se ne treba zamarati pisanjem SQL skripti, ve\u0107 opisivati upite u Bazi podataka u terminima OOP-a. No tada, tijekom rasprave o planu akcije, na ovaj sam stek gledao kao na sumersko klimavo pismo prepoznaju\u0107i samo PostgreSQL i Git.<\/p>\n<p>U to vrijeme aktivno smo koristili <b>Puppet<\/b> kao sustav upravljanja konfiguracijom. U ve\u0107ini na\u0161ih projekata koristili smo <b>GitLab CI<\/b>, <b>Elastic<\/b>, uravnote\u017eili smo visoko optere\u0107ene usluge uz pomo\u0107 <b>HAProxy,<\/b> pratili smo sve uz pomo\u0107 <b>Zabbix,<\/b>spojili smo <b>Grafana<\/b> i\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, i sve je to radilo na hardveru\u00a0<b>HP<\/b> c\u00a0<b>ESXi.<\/b> na\u00a0<b>VMware<\/b>. Svi znamo \u2013 klasika \u017eanra.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPogledajmo i poku\u0161ajmo razumjeti \u0161to se doga\u0111alo prije nego \u0161to smo zapo\u010deli sve ove intervencije.<\/p>\n<h2>\u0160to se dogodilo<\/h2>\n<p>\nTFS je prili\u010dno mo\u0107an sustav koji ne samo da isporu\u010duje kod od developera do zavr\u0161ne proizvodne ma\u0161ine, ve\u0107 tako\u0111er ima skup alata za vrlo fleksibilnu integraciju s raznim servisima - za osiguranje CI na vi\u0161epplatformskom nivou.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nRanije su to bile samo prozore. TFS je koristio nekoliko Build agenata na kojima je bilo mnogo projekata. U svakom agentu bilo je 3-4 radnika kako bi se paralelizirale zadatke i optimizirao proces. Zatim, prema planovima izdanja, TFS je isporu\u010divao sve\u017ee napravljeni Build na Windows server aplikacija.<\/p>\n<h2>Na \u0161to smo \u017eeljeli do\u0107i<\/h2>\n<p>\nZa isporuku i razvoj koristimo TFS, a pokre\u0107emo aplikaciju na Linux Application serveru, a izme\u0111u njih je neka vrsta magije. Ovaj <b>Magic Box<\/b> je sr\u017e nadolaze\u0107eg posla. Prije nego \u0161to ga ra\u0161trkamo na dijelove, malo \u0107u se skloniti i re\u0107i nekoliko rije\u010di o aplikaciji.<\/p>\n<h2>Projekt<\/h2>\n<p>\nAplikacija pru\u017ea funkcionalnost za upravljanje unaprijed pla\u0107enim karticama. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Klijent<\/h3>\n<p>\nPostojala su dva tipa korisnika. <b>Prvi<\/b> dobio je pristup autoriziraju\u0107i se putem SSL SHA-2 certifikata. Drugi\u00a0<b>je imao pristup putem korisni\u010dkog imena i lozinke.<\/b> HAProxy<\/p>\n<h3>Dalje, klijentski zahtjev se slao u HAProxy, koji je rje\u0161avao sljede\u0107e zadatke:<\/h3>\n<p>\nprvotna autorizacija;<\/p>\n<ul>\n<li>terminiranje SSL;\n<\/li>\n<li>tuning HTTP zahtjeva;\n<\/li>\n<li>prijenos zahtjeva.\n<\/li>\n<li>Provjera klijentovog certifikata je i\u0161la putem lance. Mi smo\n<\/li>\n<\/ul>\n<p>\nauthority <b>i mo\u017eemo si priu\u0161titi to, jer sami izdavati certifikate klijentima usluge. <\/b>Obratite pa\u017enju na tre\u0107u to\u010dku, malo \u0107emo se kasnije vratiti na to.<\/p>\n<p>Backend<\/p>\n<h3>Backend smo planirali napraviti na Linuxu. Backend komunicira s bazom podataka, u\u010ditava potrebne popise privilegija i zatim, ovisno o privilegijama koje ima autorizirani korisnik, osigurava pristup za potpisivanje financijskih dokumenata i slanje na izvr\u0161enje, ili generiranje nekog izvje\u0161taja.<\/h3>\n<p>\nU\u0161teda s HAProxy<\/p>\n<h2>Osim dva konteksta kroz koja je svaki klijent prolazio, postojao je jo\u0161 kontekst identity.<\/h2>\n<p>\nkoji upravo omogu\u0107ava autorizaciju, to je besplatan i mo\u0107an pandan za <b>IdentityServer4<\/b> ADFS <b>Active Directory Federation Services\u00a0<\/b>\u2014<b> Zahtjev u identity obra\u0111ivao se u nekoliko koraka. Prvi korak -<\/b>.<\/p>\n<p>dolazio je u backend. <b>klijent<\/b> <b>upadati u\u00a0backend<\/b>, koji je razmjenjivao podatke s ovim poslu\u017eiteljem i provjeravao prisutnost tokena za klijenta. Ako nije pronalazio \u2013 zahtjev se vra\u0107ao natrag na kontekst iz kojeg je do\u0161ao, ali ve\u0107 s redirekcijom, i s redirekcijom i\u0161ao na identity.<\/p>\n<p>Drugi korak \u2013 zahtjev je stizao <b>na stranicu za autorizaciju u IdentityServer,<\/b> gdje se klijent registrirao, a u bazi podataka IdentityServer pojavljivao se taj dugo i\u0161\u010dekivani token. <\/p>\n<p>Tre\u0107i korak \u2013 <b>klijent je bio redirektiran natrag <\/b>na kontekst iz kojeg je do\u0161ao.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 ima jednu osobitost: <b>odgovor na povratni zahtjev vra\u0107a putem HTTP<\/b>. Koliko god se trudili s postavkom poslu\u017eitelja, koliko god se educirali dokumentacijom, svaki put smo dobivali po\u010detni zahtjev klijenta s URL-om koji je do\u0161ao putem HTTPS-a, a IdentityServer je vra\u0107ao isti taj kontekst, ali s HTTP. Bili smo u \u0161oku! I preusmjerili smo sve to preko konteksta identity na HAProxy, a u headerima smo morali modificirati protokol HTTP na HTTPS. <\/p>\n<p>U \u010demu je pobolj\u0161anje i gdje smo u\u0161tedjeli?<\/p>\n<blockquote><p>U\u0161tedjeli smo novac koriste\u0107i besplatno rje\u0161enje za autorizaciju grupe korisnika, resurse, jer nismo iznosili IdentityServer4 kao zasebnu nodu u zasebni segment, ve\u0107 smo ga koristili zajedno s backendom na istom poslu\u017eitelju gdje se vrti backend aplikacije.<\/p><\/blockquote>\n<p><\/p>\n<h2>Kako bi trebalo raditi<\/h2>\n<p>\nDakle, kao \u0161to sam obe\u0107ao \u2013 Magic Box. Ve\u0107 razumijemo da garantirano idemo prema Linuxu. Poka\u017eimo konkretne zadatke koje je trebalo rije\u0161iti.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Manifesti Puppet. <\/b>Kako bismo isporu\u010dili i upravljali konfiguracijom usluge i aplikacije, trebalo je napisati odli\u010dne recepte. Rolica s olovkom slikovito prikazuje koliko je brzo i kvalitetno to napravljeno.<\/p>\n<p><b>Na\u010din isporuke. <\/b>Standard je RPM. Svi razumiju da to u Linuxu ne mo\u017ee bez njega, ali sam projekt nakon gradnje predstavljao skup izvr\u0161nih DLL-datoteka. Bilo ih je oko 150, projekt je dovoljno te\u017eak. Jedino skladno rje\u0161enje je upakirati tu binarnu hrpu u RPM i iz nje kasnije razvijati aplikaciju.<\/p>\n<p><b>Verzioniranje. <\/b>Morali smo \u010desto objavljivati, i trebali smo odlu\u010diti kako formirati ime paketa. To je pitanje razine integracije s TFS-om. Build-agent je bio na Linuxu. Kada TFS po\u0161alje zadatak radniku na Build-agentu, tako\u0111er mu proslijedi i skup varijabli koje ulaze u environment procesa radnika. Ove varijable okru\u017eenja uklju\u010duju ime Build-a, ime verzije i druge varijable. Vi\u0161e o tome u odjeljku 'izrada RPM-paketa'.<\/p>\n<p><b>Postavljanje TFS-a<\/b> svelo se na postavljanje cjevovoda. Prije smo na Windows-agentima sastavljali sve Windows projekte, a sada se pojavljuje Linux-agent - Build-agent, koji treba uklju\u010diti u grupu sastavljanja, obogatiti nekim artefaktima, re\u0107i kakve vrste projekata \u0107e se sastavljati na ovom Build-agentu i nekako modificirati cjevovod.<\/p>\n<p><b>IdentityServer. <\/b>ADFS nije na\u0161 put, podr\u017eavamo Open Source.<\/p>\n<p>Pro\u0111imo kroz komponente.<\/p>\n<h2>Magic Box<\/h2>\n<p>\nSastoji se od \u010detiri dijela.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/22ea63bcf184046c15e034ec093352bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Linux Build-agent. <\/b>Linux, jer za njega sastavljamo - logi\u010dno. Ovaj dio je izvr\u0161avan u tri koraka.<\/p>\n<ul>\n<li><b>Postaviti radnike<\/b> i ne samo jednog, jer se predvi\u0111ao distribuirani rad na projektu.\n<\/li>\n<li><b>Instalirati .NET Core 1.x<\/b>. Za\u0161to ba\u0161 1.x, kada je ve\u0107 dostupna 2.0 u standardnom repozitoriju? Zato \u0161to je, kada smo zapo\u010deli razvoj, stabilna verzija bila 1.09, i odlu\u010deno je da \u0107e se projekt raditi na njoj.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>RPM-repozitorij. <\/b>RPM-paketi trebali su se negdje \u010duvati. Predvi\u0111eno je da \u0107emo koristiti isti korporativni RPM-repozitorij koji je dostupan svim Linux hostovima. Tako smo i u\u010dinili. Na serveru repozitorija postavljen je <b>webhook<\/b> koji je preuzimao potrebni RPM-paket iz nazna\u010denog mjesta. Verziju paketa webhook-u je javljala Build-agent.<\/p>\n<p><b>GitLab. <\/b>Pa\u017enja! GitLab se ovdje ne koristi od strane programera, ve\u0107 od strane odjela za opskrbu za kontrolu verzija aplikacije, verzija paketa, kontrolu stanja svih Linux ma\u0161ina, a u njemu se \u010duva receptura - svi manifesti Puppet. <\/p>\n<p><b>Puppet<\/b>\u00a0\u2014 razrje\u0161ava sve sporne trenutke i isporu\u010duje upravo onu konfiguraciju koju \u017eelimo, iz GitLab-a.<\/p>\n<p>Po\u010dinjemo s uranjanjem. Kako se doga\u0111a isporuka DLL u RPM?<\/p>\n<h3>Isporuka DDL u RPM<\/h3>\n<p>\nPretpostavimo da imamo rock zvijezdu razvoja na .NET-u. Koristi Visual Studio i stvara izdanak. Nakon toga ga u\u010ditava u Git, a Git ovdje je TFS-entitet, tj. to je repozitorij aplikacije s kojim radi programer.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNakon \u010dega TFS prepoznaje da je stigao novi commit. Koja aplikacija? U pode\u0161avanjima TFS-a postoji oznaka kojim resursima raspola\u017ee odre\u0111eni Build-agent. U ovom slu\u010daju prepoznaje da sastavljamo .NET Core projekt i bira Linux Build-agent iz bazena. <\/p>\n<p>Build-agent preuzima izvorne kodove, preuzima potrebne <b>zavisnosti<\/b> iz .NET repozitorijuma, npm itd. i nakon sastavljanja same aplikacije i kasnije pakiranja \u0161alje RPM-paket u RPM-repozitorij.<\/p>\n<p>S druge strane de\u0161ava se slede\u0107e. In\u017eenjer iz odeljenja za operacije se direktno bavi implementacijom projekta: menja verzije paketa u\u00a0<b>Hiera<\/b> u repozitoriju gde se \u010duva receptura aplikacije, nakon \u010dega Puppet aktivira <b>Yum<\/b>, preuzima novi paket iz repozitorija, i nova verzija aplikacije je spremna za upotrebu.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa re\u010dima je sve jednostavno, ali \u0161ta se de\u0161ava unutar samog Build-agenta?<\/p>\n<h3>Pakovanje DLL RPM<\/h3>\n<p>\nIzvorni kodovi projekta su dobijeni i zadatak za sastavljanje od TFS-a. Build-agent <b>pokre\u0107e sastavljanje samog projekta iz izvora<\/b>. Sastavljeni projekt je dostupan u obliku vi\u0161e <b>DLL datoteka<\/b>, koje su upakovane u zip-arhiv radi smanjenja optere\u0107enja na datote\u010dkom sistemu.<\/p>\n<p>ZIP-arhiv se \u0161alje <b>u direktorijum za sastavljanje RPM paketa.<\/b> Zatim Bash skripta inicijalizuje promenljive okru\u017eenja, pronalazi verziju Build-a, verziju projekta, putanju do direktorijuma za sastavljanje, i pokre\u0107e RPM-build. Po zavr\u0161etku sastavljanja paket se objavljuje u\u00a0<b>lokalnom repozitoriju<\/b>, koji se nalazi na Build-agentu.<\/p>\n<p>Zatim, sa Build-agenta na server u RPM-repozitorij <b>\u0161alje se JSON-upit<\/b> sa ozna\u010denim imenom verzije i build-a. Webhook, o kojem sam ranije pri\u010dao, preuzima ovaj paket iz lokalnog repozitorija na Build-agentu i \u010dini novu verziju dostupnom za instalaciju.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZa\u0161to je ovakav sistem dostave paketa u RPM repozitorij? Za\u0161to se ne mo\u017ee odmah poslati sastavljeni paket u repozitorij? Poenta je u tome \u0161to su to uslovi za obezbe\u0111ivanje sigurnosti. Ovakav scenario ograni\u010dava mogu\u0107nost neovla\u0161\u0107enog postavljanja RPM paketa od strane nepoznatih osoba na server koji je dostupan svim Linux ma\u0161inama.<\/p>\n<h2>Versioniranje Baze Podataka<\/h2>\n<p>\nNa konsultacijama sa razvojem otkriveno je da su programerima bli\u017ei MS SQL, ali u ve\u0107ini non-Windows projekata ve\u0107 smo koristili PostgreSQL. Po\u0161to smo ve\u0107 odlu\u010dili da se odreknemo svega pla\u0107enog, po\u010deli smo da koristimo PostgreSQL i ovde.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nU ovom dijelu \u017eelim objasniti kako smo provodili verzioniranje baze podataka i kako smo birali izme\u0111u Flyway-a i Entity Framework Core-a. Razmotrite njihove prednosti i nedostatke.<\/p>\n<h3>Nedostaci<\/h3>\n<p>\nFlyway ide samo u jednom smjeru, ne\u00a0<b>mo\u017eemo se vratiti natrag<\/b>\u00a0\u2014 to je zna\u010dajan nedostatak. Uspore\u0111ivati s Entity Framework Core-om mo\u017eemo po drugim parametrima \u2014 s gledi\u0161ta pogodnosti za programere. Pamtite, to smo stavili na prvo mjesto, a osnovni kriterij je bio ne mijenjati ni\u0161ta za Windows-razvoj.<\/p>\n<p>Za Flyway nam <b>trebala neka omotnica<\/b>, kako de\u010dki ne bi pisali <b>SQL upite<\/b>. Njima je mnogo bli\u017ee manipulirati terminima OOP-a. Napisali smo upute za rad s objektima baze podataka, generiran je SQL upit i izvr\u0161en. Nova verzija baze podataka je spremna, pro\u0161la je testiranje \u2014 sve radi, sve je dobro.<\/p>\n<p>Entity Framework Core ima nedostatak \u2014 pri velikim optere\u0107enjima on\u00a0<b>izgra\u0111uje neoptimalne SQL upite<\/b>, a optere\u0107enje baze podataka mo\u017ee biti zna\u010dajno. No kako imamo nezahtevnu uslugu, ne ra\u010dunamo optere\u0107enje u stotinama RPS, prihvatili smo te rizike i delegirali problem budu\u0107im nama.<\/p>\n<h3>Prednosti<\/h3>\n<p>\nEntity Framework Core <b>radi iz kutije i pogodan je za razvoj<\/b>, dok se Flyway <b>lako integri\u0161e u postoje\u0107i CI<\/b>. No, radimo to da bismo olak\u0161ali programerima :)<\/p>\n<h3>Postupak implementacije<\/h3>\n<p>\nPuppet vidi da dolazi do promjene verzije paketa me\u0111u kojima je i onaj koji odgovara za migraciju. Prvo instalira paket koji sadr\u017ei migracijske skripte i funkcionalnosti vezane uz bazu podataka. Nakon toga se restartuje aplikacija koja koristi bazu podataka. Slijedi instalacija preostalih komponenti. Redoslijed instalacije paketa i pokretanja aplikacija opisan je u manifestu Puppet-a.<\/p>\n<p>Aplikacije koriste osjetljive podatke, kao \u0161to su tokeni, lozinke za bazu podataka, sve to se povla\u010di u konfiguraciju s Puppet master-om, gdje se \u010duvaju u \u0161ifriranom obliku.<\/p>\n<h2>Problemi TFS-a<\/h2>\n<p>\nNakon \u0161to smo se definirali i shvatili da nam sve zapravo funkcionira, odlu\u010dio sam pogledati \u0161to se doga\u0111a sa sastavnicama u TFS-u u cjelini za odjel Win-razvoja za druge projekte \u2014 brzo li se sastavljamo\/objavljujemo, i otkrio zna\u010dajne probleme sa brzinom.<\/p>\n<p>Jedan od glavnih projekata sastavlja se 12-15 minuta \u2014 to je dugo, tako se ne mo\u017ee \u017eivjeti. Brza analiza pokazala je stra\u0161no optere\u0107enje po I\/O, i to na masivima.<\/p>\n<p>Analiziraju\u0107i per komponentu, izvojio sam tri \u017eari\u0161ta. Prvo \u2014 <b>\u00abKaspersky antivirus\u00bb<\/b>, koji na svim Windows Build agentima skenira izvore. Drugi \u2014 <b>Windows<\/b> <b>Indexer.<\/b> Nije bio isklju\u010den, a na Build agentima se u realnom vremenu indeksiralo sve u procesu deploya. <\/p>\n<p>Tre\u0107i \u2014 <b>Npm install. <\/b>Ispostavilo se da smo u ve\u0107ini Pipelines koristili upravo ovaj scenarij. \u0160to je lo\u0161e u tome? Procedura Npm install pokre\u0107e se prilikom formiranja stabla zavisnosti u\u00a0<b>package-lock.json<\/b>, gdje se bilje\u017ee verzije paketa koji \u0107e se koristiti za izgradnju projekta. Minus u tome je \u0161to Npm install svaki put povla\u010di aktuelne verzije paketa sa interneta, a to oduzima zna\u010dajno vreme u slu\u010daju velikog projekta.<\/p>\n<blockquote><p>Programeri ponekad eksperimenti\u0161u na lokalnom ra\u010dunaru kako bi proverili rad pojedinog dela ili projekta u celini. Ponekad se ispostavi da je sve dobro lokalno, ali prilikom izgradnje i deploya \u2014 ni\u0161ta ne radi. Po\u010dinjemo da istra\u017eujemo u \u010demu je problem \u2014 aha, razli\u010dite verzije paketa sa zavisnostima.<\/p><\/blockquote>\n<p><\/p>\n<h3>Re\u0161enje<\/h3>\n<p><\/p>\n<ul>\n<li>Izvori u isklju\u010denja AV.\n<\/li>\n<li>Isklju\u010divanje indeksacije.\n<\/li>\n<li>Prelazak na\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nPrednosti npm ci su u tome \u0161to\u00a0<b>stvaramo stablo zavisnosti jedini put<\/b>, i dobijamo mogu\u0107nost da obezbedimo programeru <b>aktuelnu listu paketa<\/b>, s kojom mo\u017ee koliko god \u017eeli eksperimentisati lokalno. To <b>\u0161tedi vreme<\/b> programerima koji pi\u0161u kod.<\/p>\n<h3>Konfiguracija<\/h3>\n<p>\nSada malo o konfiguraciji repozitorijuma. Istorijski, koristimo <b>Nexus<\/b> za upravljanje repozitorijumima, uklju\u010duju\u0107i <b>Internal REPO<\/b>. U ovu unutra\u0161nju repozitoriju dolaze svi komponenti koje koristimo za unutra\u0161nje potrebe, na primer, samoprojektovani monitoring.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core na Linuxu, DevOps na konju\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTako\u0111e koristimo <b>NuGet<\/b>, jer bolje ke\u0161ira u pore\u0111enju sa drugim paket menad\u017eerima.<\/p>\n<h3>Rezultat<\/h3>\n<p>\nNakon \u0161to smo optimizovali Build agente, prosek vremena izgradnje smanjen je sa 12 minuta na 7.<\/p>\n<blockquote><p>Ako zbrojimo sve ma\u0161ine koje bismo mogli koristiti za Windows, ali su preba\u010dene na Linux u ovom projektu, u\u0161tedeli smo oko $10.000. I to samo za licence, a ako uzmemo u obzir tro\u0161kove odr\u017eavanja \u2014 vi\u0161e.<\/p><\/blockquote>\n<p><\/p>\n<h2>Planovi<\/h2>\n<p>\nZa slede\u0107i kvartal planirali smo rad na optimizaciji isporuke koda.<\/p>\n<p><b>Prelazak na prebuild Docker-image<\/b>. TFS je sjajna stvar sa mno\u0161tvom pluginova koji omogu\u0107avaju integraciju u Pipeline, uklju\u010duju\u0107i i izgradnju po okida\u010du, recimo, Docker-imagea. Ovaj okida\u010d \u017eelimo da napravimo za ba\u0161 taj <b>package-lock.json<\/b>. Ako se iz bilo kojeg razloga promijeni sastav komponenti koji se koriste za izradu projekta - stvara se nova Docker slika. Ona se kasnije koristi za postavljanje kontejnera s izgra\u0111enom aplikacijom. Trenutno to nema, ali planiramo pre\u0107i na mikroservisnu arhitekturu u Kubernetesu, koja se aktivno razvija u na\u0161oj kompaniji i ve\u0107 dugo podr\u017eava produkcijska rje\u0161enja.<\/p>\n<h2>Sa\u017eetak<\/h2>\n<p>\nPozivam sve da zaborave Windows, ali to nije zbog toga \u0161to ne znam kako je pripremiti. Razlog je taj \u0161to je velika ve\u0107ina opensource rje\u0161enja - to je <b>Linux stack<\/b>. U\u0161tedjet \u0107ete na resursima <b>. Po mom mi\u0161ljenju, budu\u0107nost pripada Open Source rje\u0161enjima na Linuxu s jakom zajednicom.<\/b>Profil govornika Aleksandra Sin\u010dinova<\/p>\n<p><i>na GitHubu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">DevOps Conf<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">je konferencija o integraciji procesa razvoja, testiranja i operacija za profesionalce od profesionalaca. Upravo zato je projekt o kojem je Aleksandar pri\u010dao realiziran i funkcioni\u0161e, a na dan njegovog nastupa provedena su dva uspje\u0161na izdanja. Na<\/a><\/noindex>\u00a0DevOps Conf na RIT++\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">27. i 28. svibnja bit \u0107e jo\u0161 vi\u0161e sli\u010dnih slu\u010dajeva od prakti\u010dara. Jo\u0161 uvijek se mo\u017eete ukrcati u posljednji vlak i<\/a><\/noindex> podnijeti izlaganje <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">ili opu\u0161teno<\/a><\/noindex> rezervirati <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">ulaznicu. Vidimo se u Skolkovu!<\/a><\/noindex> \u201eGlazba pulsara\u201d, ili Kako zvu\u010de brzo rotiraju\u0107e neutronske zvijezde<\/p><\/blockquote>\n<p>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/oleg-bunin\/blog\/448496\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u044b\u00a0\u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8\u00a0\u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438\u00a0\u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e\u00a0Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430\u00a0\u0443\u00a0\u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041a\u043e\u0433\u0434\u0430 \u044f\u00a0\u0432\u044b\u0441\u044b\u043f\u0430\u043b \u043d\u0430\u00a0\u0441\u0442\u043e\u043b \u0432\u0435\u0441\u044c \u0441\u0442\u0435\u043a Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u043e\u00a0\u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u00a0\u2014 \u0431\u043e\u043b\u044c\u2026 \u0422\u0430\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u043d\u0447\u0438\u043d\u043e\u0432\u0430 \u043d\u0430 DevOpsConf. \u041a\u043e\u0433\u0434\u0430 \u0438\u0437\u00a0\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0443\u0448\u0435\u043b \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442 \u043f\u043e\u00a0Windows, \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0437\u0430\u0434\u0430\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u00a0Linux, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24043,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32217","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.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\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\/hr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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.NET Core \u043d\u0430 Linux, DevOps \u043d\u0430 \u043a\u043e\u043d\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:45:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:45:43+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\udd47.NET Core na Linuxu, DevOps na konju | ProHoster","description":"\ud83e\udd47.NET Core na Linuxu, DevOps na vrhuncu | ProHoster","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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.NET Core \u043d\u0430 Linux, DevOps \u043d\u0430 \u043a\u043e\u043d\u0435 | ProHoster","og:description":"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430.","og:url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:45:43+00:00","article:modified_time":"2019-10-31T18:45:43+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32217","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 09:49:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:02:47","updated":"2026-01-21 09:49:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}