{"id":76769,"date":"2020-04-04T13:42:27","date_gmt":"2020-04-04T11:42:27","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet"},"modified":"2020-04-04T13:42:27","modified_gmt":"2020-04-04T11:42:27","slug":"content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet","title":{"rendered":"Tagueamento baseado em conte\u00fado no compilador werf: por que e como isso funciona?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Tagueamento baseado em conte\u00fado no compilador werf: por que e como isso funciona?\" src=\"\/wp-content\/uploads\/2020\/04\/494346bbee96cc2b6c838491ba1c67fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex> \u2014 nossa ferramenta CLI do GitOps de c\u00f3digo aberto para compilar e entregar aplicativos no Kubernetes. No <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/493170\/\">lan\u00e7amento v1.1<\/a><\/noindex> foi apresentada uma nova funcionalidade no construtor de imagens: etiquetagem de imagens por conte\u00fado ou <i>content-based tagging<\/i>. At\u00e9 agora, o esquema t\u00edpico de etiquetagem no werf assumia a etiquetagem de imagens Docker por tag Git, branch Git ou commit Git. Mas todas essas esquemas possuem desvantagens que s\u00e3o completamente resolvidas pela nova estrat\u00e9gia de etiquetagem. Detalhes sobre isso e por que \u00e9 t\u00e3o bom est\u00e3o abaixo.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Implanta\u00e7\u00e3o de um conjunto de microsservi\u00e7os de um \u00fanico reposit\u00f3rio Git<\/h2>\n<p>\n\u00c9 comum a situa\u00e7\u00e3o em que um aplicativo \u00e9 dividido em muitos servi\u00e7os mais ou menos independentes. Os releases desses servi\u00e7os podem ocorrer de forma independente: um ou mais servi\u00e7os podem ser lan\u00e7ados ao mesmo tempo, enquanto os outros devem continuar funcionando sem quaisquer altera\u00e7\u00f5es. Mas, do ponto de vista de armazenamento de c\u00f3digo e gerenciamento de projeto, \u00e9 mais conveniente manter esses servi\u00e7os de aplicativos em um \u00fanico reposit\u00f3rio.<\/p>\n<p>H\u00e1 situa\u00e7\u00f5es em que os servi\u00e7os realmente s\u00e3o independentes e n\u00e3o est\u00e3o relacionados a um \u00fanico aplicativo. Nesse caso, eles estar\u00e3o localizados em projetos separados e seu lan\u00e7amento ser\u00e1 realizado atrav\u00e9s de processos CI\/CD distintos em cada um dos projetos.<\/p>\n<p>No entanto, na realidade, os desenvolvedores muitas vezes dividem um \u00fanico aplicativo em v\u00e1rios microsservi\u00e7os, mas criar um reposit\u00f3rio e um projeto separado para cada um... \u00e9 um excesso evidente. Este \u00e9 o cen\u00e1rio que ser\u00e1 abordado a seguir: v\u00e1rios desses microsservi\u00e7os est\u00e3o em um \u00fanico reposit\u00f3rio de projeto e os releases acontecem por meio de um \u00fanico processo em CI\/CD.<\/p>\n<h3>Etiquetagem por branch Git e tag Git<\/h3>\n<p>\nSuponha que a estrat\u00e9gia de etiquetagem mais comum seja <i>tag-or-branch<\/i>. Para branches Git, as imagens s\u00e3o etiquetadas com o nome da branch, para uma branch existe apenas uma imagem publicada no momento com o nome dessa branch. Para tags Git, as imagens s\u00e3o etiquetadas de acordo com o nome da tag.<\/p>\n<p>Ao criar uma nova tag Git \u2014 por exemplo, ao lan\u00e7ar uma nova vers\u00e3o \u2014 uma nova tag Docker ser\u00e1 criada para todas as imagens do projeto no Docker Registry:<\/p>\n<ul>\n<li> <code>myregistry.org\/myproject\/frontend:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/myservice1:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/myservice2:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/myservice3:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/myservice4:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/myservice5:v1.1.10<\/code><\/li>\n<li> <code>myregistry.org\/myproject\/database:v1.1.10<\/code><\/li>\n<\/ul>\n<p>\nEsses novos nomes de imagens s\u00e3o inseridos atrav\u00e9s de templates Helm na configura\u00e7\u00e3o do Kubernetes. Durante a execu\u00e7\u00e3o da implanta\u00e7\u00e3o pelo comando <code>werf deploy<\/code> ocorre a atualiza\u00e7\u00e3o do campo <code>image<\/code> nos manifests de recursos do Kubernetes e a reinicializa\u00e7\u00e3o dos recursos correspondentes devido \u00e0 mudan\u00e7a do nome da imagem.<\/p>\n<p><b>O problema<\/b>: no caso em que o conte\u00fado da imagem n\u00e3o mudou realmente desde a \u00faltima vers\u00e3o (tag do Git), mas apenas seu tag Docker, ocorre <i>um rein\u00edcio<\/i> extra desse aplicativo e, consequentemente, pode ocorrer algum downtime. Embora n\u00e3o houvesse raz\u00f5es reais para realizar esse rein\u00edcio.<\/p>\n<p>Como consequ\u00eancia, com a atual estrat\u00e9gia de tagging \u00e9 necess\u00e1rio criar v\u00e1rios reposit\u00f3rios Git separados e surge o problema da organiza\u00e7\u00e3o da implanta\u00e7\u00e3o desses m\u00faltiplos reposit\u00f3rios. De modo geral, essa estrat\u00e9gia acaba sendo sobrecarregada e complexa. \u00c9 melhor agrupar muitos servi\u00e7os em um \u00fanico reposit\u00f3rio e criar tags Docker que evitem rein\u00edcios desnecess\u00e1rios.<\/p>\n<h3>Tagueamento por commit do Git<\/h3>\n<p>\nNo werf, tamb\u00e9m existe uma estrat\u00e9gia de tagueamento relacionada aos commits do Git.<\/p>\n<p>O commit do Git \u00e9 um identificador do conte\u00fado do reposit\u00f3rio Git e depende do hist\u00f3rico de altera\u00e7\u00f5es dos arquivos no reposit\u00f3rio Git, portanto, parece l\u00f3gico us\u00e1-lo para tagueamento de imagens no Docker Registry.<\/p>\n<p>No entanto, o tagueamento por commit do Git tem as mesmas desvantagens que o de branches ou tags do Git:<\/p>\n<ul>\n<li> Um commit vazio pode ter sido criado que n\u00e3o altera arquivos, mas o tag Docker da imagem ser\u00e1 alterado.<\/li>\n<li> Um commit de merge pode ter sido criado que n\u00e3o altera arquivos, mas o tag Docker da imagem ser\u00e1 alterado.<\/li>\n<li> Um commit pode ter sido criado que altera arquivos no Git que n\u00e3o s\u00e3o importados na imagem, e o tag Docker da imagem ser\u00e1 novamente alterado.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Tagueamento pelo nome da branch do Git n\u00e3o reflete a vers\u00e3o da imagem<\/h2>\n<p>\nH\u00e1 tamb\u00e9m um problema relacionado \u00e0 estrat\u00e9gia de tagueamento por branches do Git.<\/p>\n<p>O tagueamento pelo nome da branch funciona desde que os commits dessa branch sejam coletados de forma sequencial em ordem cronol\u00f3gica.<\/p>\n<p>Se o usu\u00e1rio iniciar a reconstru\u00e7\u00e3o de um commit antigo associado a um determinado branch na configura\u00e7\u00e3o atual, o werf substituir\u00e1 a imagem pelo respectivo Docker tag da nova vers\u00e3o da imagem para o commit antigo. A partir desse momento, os Deployments que utilizam esse tag correm o risco, ao reiniciar os pods, de fazer pull de outra vers\u00e3o da imagem, resultando na perda de conex\u00e3o do nosso aplicativo com o sistema CI, levando \u00e0 desynchroniza\u00e7\u00e3o.<\/p>\n<p>Al\u00e9m disso, ao se fazer push de forma sequencial em um mesmo branch com um pequeno intervalo de tempo entre eles, um commit antigo pode ser constru\u00eddo depois de um mais recente: uma vers\u00e3o antiga da imagem pode sobrepor uma nova pela tag do branch do Git. Esses problemas podem ser resolvidos por um sistema CI\/CD (por exemplo, no GitLab CI, um pipeline \u00e9 acionado para a \u00faltima s\u00e9rie de commits). No entanto, nem todos os sistemas suportam isso, e deve haver uma forma mais confi\u00e1vel de evitar um problema t\u00e3o fundamental.<\/p>\n<h2>O que \u00e9 tagging baseado em conte\u00fado?<\/h2>\n<p>\nEnt\u00e3o, o que \u00e9 tagging baseado em conte\u00fado \u2014 a tagueamento de imagens por seu conte\u00fado.<\/p>\n<p>Para criar os Docker tags, n\u00e3o s\u00e3o utilizados os primitivas do Git (branch Git, tag Git...), mas sim um checksum associado a:<\/p>\n<ul>\n<li> <i>o conte\u00fado da imagem<\/i>. O identificador da tag da imagem reflete seu conte\u00fado. Ao construir uma nova vers\u00e3o, esse identificador n\u00e3o mudar\u00e1 se os arquivos da imagem n\u00e3o forem alterados;<\/li>\n<li> <i>a hist\u00f3ria de cria\u00e7\u00e3o dessa imagem no Git<\/i>. Imagens associadas a diferentes branches do Git e a diferentes hist\u00f3rias de constru\u00e7\u00e3o atrav\u00e9s do werf ter\u00e3o identificadores de tags diferentes.<\/li>\n<\/ul>\n<p>\nComo tal identificador de tag, temos uma <b>assinatura das fases da imagem<\/b>.<\/p>\n<p>Cada imagem consiste em um conjunto de fases: <code>Harvard University<\/code>, <code>before-install<\/code>, <code>git-archive<\/code>, <code>install<\/code>, <code>imports-after-install<\/code>, <code>before-setup<\/code>,\u2026 <code>git-latest-patch<\/code> etc. Cada fase tem um identificador que reflete seu conte\u00fado, \u2014 <b>assinatura da fase<\/b> <i>(stage signature)<\/i>.<\/p>\n<p>A imagem final, composta por essas fases, \u00e9 tagueada pela chamada assinatura do conjunto dessas fases \u2014 <b>stages signature<\/b>, \u2014 que \u00e9 geral para todas as fases da imagem.<\/p>\n<p>Cada imagem da configura\u00e7\u00e3o <code>werf.yaml<\/code> geralmente ter\u00e1 sua pr\u00f3pria assinatura e, consequentemente, a tag do Docker.<\/p>\n<p>A assinatura das fases resolve todos os problemas mencionados:<\/p>\n<ul>\n<li> \u00c9 resistente a commits vazios do Git.<\/li>\n<li> \u00c9 resistente a commits do Git que alteram arquivos que n\u00e3o s\u00e3o relevantes para a imagem.<\/li>\n<li> N\u00e3o leva ao problema de sobrescrever a vers\u00e3o atual da imagem ao reiniciar constru\u00e7\u00f5es para commits antigos do branch do Git.<\/li>\n<\/ul>\n<p>\nAgora essa \u00e9 a estrat\u00e9gia de tagueamento recomendada e \u00e9 usada por padr\u00e3o no werf para todos os sistemas CI.<\/p>\n<h2>Como ativar e usar no werf<\/h2>\n<p>\nA op\u00e7\u00e3o correspondente foi adicionada ao comando <code>werf publish<\/code>: <code>--tag-by-stages-signature=true|false<\/code><\/p>\n<p>Na sistema CI, a estrat\u00e9gia de tagueamento \u00e9 definida pelo comando <code>werf ci-env<\/code>. Anteriormente, um par\u00e2metro foi definido para isso <code>werf ci-env --tagging-strategy=tag-or-branch<\/code>. Agora, se essa op\u00e7\u00e3o for especificada <code>werf ci-env --tagging-strategy=stages-signature<\/code> ou n\u00e3o, o werf usar\u00e1, por padr\u00e3o, a estrat\u00e9gia de tagueamento <code>assinatura-dos-est\u00e1gios<\/code>. O comando <code>werf ci-env<\/code> automaticamente definir\u00e1 as flags necess\u00e1rias para o comando <code>werf build-and-publish<\/code> (ou <code>werf publish<\/code>), portanto, n\u00e3o \u00e9 necess\u00e1rio especificar op\u00e7\u00f5es adicionais para esses comandos.<\/p>\n<p>Por exemplo, o comando:<\/p>\n<pre><code class=\"plaintext\">werf publish --stages-storage :local --images-repo registry.hello.com\/web\/core\/system --tag-by-stages-signature<\/code><\/pre>\n<p>\n\u2026 pode criar as seguintes imagens:<\/p>\n<ul>\n<li> <code>registry.hello.com\/web\/core\/system\/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d<\/code><\/li>\n<li> <code>registry.hello.com\/web\/core\/system\/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6<\/code><\/li>\n<\/ul>\n<p>\nAqui <code>4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d<\/code> \u2014 \u00e9 a assinatura das fases da imagem <code>backend<\/code>, e <code>f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6<\/code> \u2014 assinatura das fases da imagem <code>frontend<\/code>.<\/p>\n<p>Ao usar fun\u00e7\u00f5es especiais <code>werf_container_image<\/code> e <code>werf_container_env<\/code> nos templates Helm, nada precisa ser alterado: essas fun\u00e7\u00f5es gerar\u00e3o automaticamente os nomes corretos das imagens.<\/p>\n<p>Exemplo de configura\u00e7\u00e3o no sistema CI:<\/p>\n<pre><code class=\"plaintext\">type multiwerf &amp;&amp; source &lt;(multiwerf use 1.1 beta)\ntype werf &amp;&amp; source &lt;(werf ci-env gitlab)\nwerf build-and-publish|deploy<\/code><\/pre>\n<p>\nMais informa\u00e7\u00f5es sobre a configura\u00e7\u00e3o est\u00e3o dispon\u00edveis na documenta\u00e7\u00e3o:<\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/v1.1\/documentation\/reference\/publish_process.html#%D1%82%D0%B5%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2-%D0%BF%D0%BE-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%BC%D0%BE%D0%BC%D1%83\">Guia \u2192 Publica\u00e7\u00e3o (publish)<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/v1.1\/documentation\/reference\/plugging_into_cicd\/overview.html#stages-signature\">Trabalhando com CI\/CD \u2192 Informa\u00e7\u00f5es gerais \u2192 stages-signature<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/v1.1\/documentation\/guides\/gitlab_ci_cd_integration.html#gitlab-ciyml\">Integra\u00e7\u00e3o com GitLab CI\/CD \u2192 .gitlab-ci.yml<\/a><\/noindex>.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Total<\/h2>\n<p><\/p>\n<ul>\n<li> A nova op\u00e7\u00e3o <code>werf publish --tag-by-stages-signature=true|false<\/code>.<\/li>\n<li> Novo valor da op\u00e7\u00e3o <code>werf ci-env --tagging-strategy=stages-signature|tag-or-branch<\/code> (se n\u00e3o especificado, o padr\u00e3o ser\u00e1 <code>assinatura-dos-est\u00e1gios<\/code>).<\/li>\n<li> Se anteriormente foram usadas op\u00e7\u00f5es de tagueamento por commits Git (<code>WERF_TAG_GIT_COMMIT<\/code> ou a op\u00e7\u00e3o <code>werf publish --tag-git-commit COMMIT<\/code>), \u00e9 obrigat\u00f3rio mudar para a estrat\u00e9gia de tagueamento <i>assinatura-dos-est\u00e1gios<\/i>.<\/li>\n<li> Novos projetos devem ser imediatamente migrados para o novo esquema de tagueamento.<\/li>\n<li> Projetos antigos ao serem migrados para o werf 1.1 devem ser mudados para o novo esquema de tagueamento, embora o antigo <i>tag-or-branch<\/i> ainda seja suportado.<\/li>\n<\/ul>\n<p>\nA tagging baseada no conte\u00fado resolve todos os problemas abordados no artigo:<\/p>\n<ul>\n<li> A resist\u00eancia do nome da tag Docker a commits Git vazios.<\/li>\n<li> A resist\u00eancia do nome da tag Docker a commits Git que alteram arquivos irrelevantes para a imagem.<\/li>\n<li> N\u00e3o resulta em problemas de sobrescrever a vers\u00e3o atual da imagem ao reiniciar builds para commits Git antigos em branches Git.<\/li>\n<\/ul>\n<p>\nAproveite! E n\u00e3o esque\u00e7a de nos visitar em <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf\">GitHub<\/a><\/noindex>, para criar uma issue ou encontrar uma j\u00e1 existente, dar um like, criar PR ou apenas acompanhar o desenvolvimento do projeto.<\/p>\n<h2>P.S.<\/h2>\n<p>\nConfira tamb\u00e9m em nosso blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/493170\/\">Lan\u00e7amento do werf 1.1: melhorias no compilador hoje e planos para o futuro.<\/a><\/noindex>\u00bb<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/481306\/\">Apresentamos o werf 1.0 est\u00e1vel: qual \u00e9 o papel do GitOps, status e planos<\/a><\/noindex>\u00bb<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460351\/\">werf \u2014 nossa ferramenta para CI\/CD no Kubernetes (vis\u00e3o geral e v\u00eddeo da apresenta\u00e7\u00e3o)<\/a><\/noindex>\u00bb;<\/li>\n<li> Ciclo de notas sobre novidades no werf:\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476646\/\">Mesclagem em 3 vias no werf: deployment no Kubernetes com Helm \"potencializado\".<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/468049\/\">Uso do werf para implanta\u00e7\u00f5es de charts Helm complexos<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Suporte a monorepo e multirepo no werf e qual a rela\u00e7\u00e3o com o Docker Registry.<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/463613\/\">Agora \u00e9 poss\u00edvel construir imagens Docker no werf tamb\u00e9m usando um Dockerfile comum<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>werf \u2014 \u043d\u0430\u0448\u0430 GitOps CLI-\u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 Kubernetes. \u0412 \u0440\u0435\u043b\u0438\u0437\u0435 v1.1 \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0435 \u043e\u0431\u0440\u0430\u0437\u043e\u0432: \u0442\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043f\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443 \u0438\u043b\u0438 content-based tagging. \u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0442\u0438\u043f\u0438\u0447\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0442\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 werf \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u0430 \u0442\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 Docker-\u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043f\u043e Git-\u0442\u0435\u0433\u0443, Git-\u0432\u0435\u0442\u043a\u0435 \u0438\u043b\u0438 Git-\u043a\u043e\u043c\u043c\u0438\u0442\u0443. \u041d\u043e \u0443 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0441\u0445\u0435\u043c \u0435\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":76770,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-76769","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\udd47Content-based tagging \u0432 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0435 werf: \u0437\u0430\u0447\u0435\u043c \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442? | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet\" \/>\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-04-04T11:42:27+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-04T11:42:27+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\udd47Tagging baseada no conte\u00fado no compilador werf: por que e como isso funciona? | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\udd47Content-based tagging \u0432 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0435 werf: \u0437\u0430\u0447\u0435\u043c \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442? | ProHoster","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/content-based-tagging-v-sborshhike-werf-zachem-i-kak-eto-rabotaet","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-04-04T11:42:27+00:00","article:modified_time":"2020-04-04T11:42:27+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"76769","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 17:30:22","updated":"2022-09-28 05:59:33","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/76769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=76769"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/76769\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/76770"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=76769"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=76769"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=76769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}