{"id":52071,"date":"2020-02-18T05:34:24","date_gmt":"2020-02-18T02:34:24","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy"},"modified":"2020-02-18T05:34:24","modified_gmt":"2020-02-18T02:34:24","slug":"horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy","title":{"rendered":"Pense bem antes de usar Docker-in-Docker para CI ou ambiente de testes.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Pense bem antes de usar Docker-in-Docker para CI ou ambiente de testes.\" src=\"\/wp-content\/uploads\/2020\/02\/50b03664f1984b36e1703717dfaa7ecc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDocker-in-Docker \u00e9 um ambiente virtualizado do daemon do Docker, executado dentro do pr\u00f3prio cont\u00eainer para a constru\u00e7\u00e3o de imagens de cont\u00eainer. O objetivo principal de criar o Docker-in-Docker foi ajudar no desenvolvimento do pr\u00f3prio Docker. Muitas pessoas o utilizam para executar o Jenkins CI. A princ\u00edpio, isso parece normal, mas surgem problemas que podem ser evitados ao instalar o Docker dentro do cont\u00eainer do Jenkins CI. Este artigo explica como fazer isso. Se voc\u00ea est\u00e1 interessado na solu\u00e7\u00e3o final sem detalhes, basta ler a \u00faltima se\u00e7\u00e3o do artigo \"Solu\u00e7\u00e3o para o problema\".<\/p>\n<p><img decoding=\"async\" alt=\"Pense bem antes de usar Docker-in-Docker para CI ou ambiente de testes.\" src=\"\/wp-content\/uploads\/2020\/02\/0fdafa0c0a1768170cff52333e733314.png\" style=\"display:block;margin: 0 auto;\" \/><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Docker-in-Docker: \"Bom\"<\/h3>\n<p>\nMais de dois anos atr\u00e1s, eu inseri no Docker <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/moby\/moby\/commit\/280901e5fbd0c2dabd14d7a9b69a073f6e8f87e4\">--all<\/a><\/noindex> --privileged e escrevi <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jpetazzo\/dind\/commit\/bfbe19c0eec634f66c9f8bac53c6b7c7e0fdb063\">a primeira vers\u00e3o do dind.<\/a><\/noindex>O objetivo era ajudar a equipe principal a desenvolver o Docker mais rapidamente. Antes do Docker-in-Docker, o ciclo t\u00edpico de desenvolvimento era assim:<\/p>\n<ul>\n<li>hackity hack;<\/li>\n<li>constru\u00e7\u00e3o (build);<\/li>\n<li>parar o daemon do Docker em execu\u00e7\u00e3o;<\/li>\n<li>iniciar um novo daemon do Docker;<\/li>\n<li>testar;<\/li>\n<li>repetir o ciclo.<\/li>\n<\/ul>\n<p>\nSe voc\u00ea quisesse fazer uma constru\u00e7\u00e3o limpa e reproduz\u00edvel (ou seja, dentro de um cont\u00eainer), ela se tornava mais complicada:<\/p>\n<ul>\n<li>hackity hack;<\/li>\n<li>certificar-se de que uma vers\u00e3o funcional do Docker estava em execu\u00e7\u00e3o;<\/li>\n<li>construir um novo Docker com um Docker antigo;<\/li>\n<li>parar o daemon do Docker;<\/li>\n<li>iniciar um novo daemon do Docker;<\/li>\n<li>testar;<\/li>\n<li>parar o novo daemon do Docker;<\/li>\n<li>repetir.<\/li>\n<\/ul>\n<p>\nCom a chegada do Docker-in-Docker, o processo se simplificou:<\/p>\n<ul>\n<li>hackity hack;<\/li>\n<li>constru\u00e7\u00e3o + execu\u00e7\u00e3o em uma \u00fanica etapa;<\/li>\n<li>repetir o ciclo.<\/li>\n<\/ul>\n<p>\nN\u00e3o \u00e9 melhor assim?<\/p>\n<p><img decoding=\"async\" alt=\"Pense bem antes de usar Docker-in-Docker para CI ou ambiente de testes.\" src=\"\/wp-content\/uploads\/2020\/02\/b4870536068c660a8d996ec53f079504.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Docker-in-Docker: \"Ruim\"<\/h3>\n<p>\nNo entanto, ao contr\u00e1rio da cren\u00e7a popular, o Docker-in-Docker n\u00e3o \u00e9 composto 100% de estrelas, unic\u00f3rnios e p\u00f4neis. Quero dizer que existem alguns problemas que o desenvolvedor precisa estar ciente.<\/p>\n<p>Um deles diz respeito ao LSM (m\u00f3dulos de seguran\u00e7a do Linux), como o AppArmor e o SELinux: ao iniciar um cont\u00eainer, o \"Docker interno\" pode tentar aplicar perfis de seguran\u00e7a que entrar\u00e3o em conflito ou complicar\u00e3o o \"Docker externo\". Este \u00e9 o problema mais complexo que foi necess\u00e1rio resolver ao tentar combinar a implementa\u00e7\u00e3o original da op\u00e7\u00e3o \u2013privileged. Minhas altera\u00e7\u00f5es funcionaram, e todos os testes tamb\u00e9m passariam na minha m\u00e1quina Debian e nas m\u00e1quinas virtuais de teste Ubuntu, mas falhariam e queimariam na m\u00e1quina do Michael Crosby (se n\u00e3o me engano, ele tinha Fedora). N\u00e3o consigo lembrar a causa exata do problema, mas \u00e9 poss\u00edvel que tenha surgido porque o Mike \u00e9 um homem s\u00e1bio que trabalha com SELINUX=enforce (eu usei AppArmor), e minhas altera\u00e7\u00f5es n\u00e3o consideraram os perfis do SELinux.<\/p>\n<h3>Docker-in-Docker: \"Maligno\"<\/h3>\n<p>\nO segundo problema est\u00e1 relacionado aos drivers de armazenamento do Docker. Quando voc\u00ea executa Docker-in-Docker, o Docker externo opera sobre um sistema de arquivos normal (EXT4, BTRFS ou qualquer outro que voc\u00ea tenha dispon\u00edvel), enquanto o Docker interno opera sobre um sistema de copy-on-write (AUFS, BTRFS, Device Mapper, etc., dependendo do que o Docker externo est\u00e1 configurado para usar). Isso resulta em v\u00e1rias combina\u00e7\u00f5es que n\u00e3o funcionar\u00e3o. Por exemplo, voc\u00ea n\u00e3o poder\u00e1 executar AUFS sobre AUFS. <\/p>\n<p>Se voc\u00ea executar BTRFS sobre BTRFS, inicialmente isso deve funcionar, mas assim que houver subvolumes aninhados, n\u00e3o ser\u00e1 poss\u00edvel excluir o subvolume pai. O m\u00f3dulo Device Mapper n\u00e3o tem namespace, ent\u00e3o, se v\u00e1rias inst\u00e2ncias do Docker o utilizarem em uma mesma m\u00e1quina, todas poder\u00e3o ver (e impactar) as imagens umas das outras e os dispositivos de backup dos cont\u00eaineres. Isso \u00e9 ruim.<\/p>\n<p>Existem solu\u00e7\u00f5es alternativas para muitos desses problemas. Por exemplo, se voc\u00ea quiser usar AUFS no Docker interno, basta transformar a pasta \/var\/lib\/docker em um volume, e tudo ficar\u00e1 bem. O Docker adicionou alguns namespaces b\u00e1sicos aos alvos do Device Mapper, portanto, se v\u00e1rias chamadas do Docker forem feitas em uma \u00fanica m\u00e1quina, elas n\u00e3o se \"atropelar\u00e3o\".<\/p>\n<p>No entanto, essa configura\u00e7\u00e3o n\u00e3o \u00e9 nada simples, como pode ser visto nestes <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jpetazzo\/dind\/issues\/78\">de artigos<\/a><\/noindex> no reposit\u00f3rio dind no GitHub.<\/p>\n<h3>Docker-in-Docker: fica ainda pior<\/h3>\n<p>\nE quanto ao cache de build? Isso tamb\u00e9m pode ser bastante complicado. As pessoas costumam me perguntar: \u201cse estou executando Docker-in-Docker, como posso usar as imagens localizadas no meu host, em vez de ter que puxar tudo novamente no meu Docker interno\u201d?<\/p>\n<p>Algumas pessoas empreendedoras tentaram montar \/var\/lib\/docker do host no cont\u00eainer Docker-in-Docker. \u00c0s vezes, eles compartilham \/var\/lib\/docker entre v\u00e1rios cont\u00eaineres.<\/p>\n<p><img decoding=\"async\" alt=\"Pense bem antes de usar Docker-in-Docker para CI ou ambiente de testes.\" src=\"\/wp-content\/uploads\/2020\/02\/192c9d26798d32078272aab1864bbccb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Quer corromper dados? Porque isso \u00e9 exatamente o que corromper\u00e1 seus dados!<\/i><\/p>\n<p>O daemon do Docker foi claramente projetado para ter acesso exclusivo ao \/var\/lib\/docker. Nada mais deve 'tocar, cutucar ou mexer' em qualquer arquivo Docker que esteja nessa pasta.<\/p>\n<p>Por que isso \u00e9 t\u00e3o importante? Porque \u00e9 o resultado de uma das li\u00e7\u00f5es mais dif\u00edceis aprendidas durante o desenvolvimento do dotCloud. O motor de cont\u00eaineres do dotCloud funcionava com v\u00e1rios processos acessando \/var\/lib\/dotcloud simultaneamente. Truques engenhosos, como substitui\u00e7\u00e3o at\u00f4mica de arquivos (em vez de edi\u00e7\u00e3o no local), 'bloqueio' de c\u00f3digo com recomenda\u00e7\u00f5es e bloqueios obrigat\u00f3rios e outros experimentos com sistemas seguros, como SQLite e BDB, nem sempre funcionavam. Quando reestruturamos nosso motor de cont\u00eaineres, que eventualmente se tornou o Docker, uma das principais decis\u00f5es de design foi centralizar todas as opera\u00e7\u00f5es de cont\u00eainer em um \u00fanico daemon para acabar com essa confus\u00e3o de acesso simult\u00e2neo.<\/p>\n<p>N\u00e3o me entenda mal: \u00e9 completamente poss\u00edvel criar algo bom, confi\u00e1vel e r\u00e1pido, que inclua v\u00e1rios processos e gerenciamento paralelo moderno. Mas acreditamos que \u00e9 mais simples e f\u00e1cil escrever e manter o c\u00f3digo usando o Docker como o \u00fanico jogador.<\/p>\n<p>Isso significa que se voc\u00ea compartilhar o diret\u00f3rio \/var\/lib\/docker entre v\u00e1rias inst\u00e2ncias do Docker, voc\u00ea ter\u00e1 problemas. Claro, isso pode funcionar, especialmente nos est\u00e1gios iniciais de testes. 'Ei, m\u00e3e, consigo rodar o ubuntu com docker!' Mas tente fazer algo mais complicado, como puxar a mesma imagem de duas inst\u00e2ncias diferentes, e voc\u00ea ver\u00e1 o mundo pegar fogo.<\/p>\n<p>Isso significa que, se o seu sistema CI realiza builds e rebuilds, a cada rein\u00edcio do cont\u00eainer Docker-in-Docker voc\u00ea corre o risco de derrubar uma bomba de n\u00facleo no seu cache. Isso n\u00e3o \u00e9 nada legal!<\/p>\n<h3>Solu\u00e7\u00e3o do problema<\/h3>\n<p>\nVamos dar um passo atr\u00e1s. Voc\u00ea realmente precisa do Docker-in-Docker ou apenas quer a capacidade de executar o Docker, ou seja, construir e executar cont\u00eaineres e imagens do seu sistema CI enquanto esse pr\u00f3prio sistema CI est\u00e1 em um cont\u00eainer?<\/p>\n<p>Aposto que a maioria das pessoas quer a \u00faltima op\u00e7\u00e3o, ou seja, elas querem que um sistema CI, como Jenkins, possa executar cont\u00eaineres. A maneira mais simples de fazer isso \u00e9 simplesmente inserir o socket do Docker no seu cont\u00eainer CI, vinculando-o com a flag -v.<\/p>\n<p>Em termos simples, ao executar seu cont\u00eainer CI (Jenkins ou outro), em vez de quebrar a cabe\u00e7a com Docker-in-Docker, inicie-o a partir da linha:<\/p>\n<pre><code class=\"plaintext\">docker run -v \/var\/run\/docker.sock:\/var\/run\/docker.sock ...<\/code><\/pre>\n<p>\nAgora este cont\u00eainer ter\u00e1 acesso ao socket do Docker e, portanto, poder\u00e1 executar cont\u00eaineres. Exceto que, em vez de executar cont\u00eaineres \"filhos\", ele executar\u00e1 cont\u00eaineres \"parentes\".<\/p>\n<p>Experimente isso, usando a imagem oficial do docker (que cont\u00e9m o bin\u00e1rio do Docker):<\/p>\n<pre><code class=\"plaintext\">docker run -v \/var\/run\/docker.sock:\/var\/run\/docker.sock \n           -ti docker<\/code><\/pre>\n<p>\nIsso se parece e funciona como Docker-in-Docker, mas n\u00e3o \u00e9 Docker-in-Docker: quando este cont\u00eainer criar cont\u00eaineres adicionais, eles ser\u00e3o criados no Docker de n\u00edvel superior. Voc\u00ea n\u00e3o experimentar\u00e1 os efeitos colaterais da aninhagem, e o cache de constru\u00e7\u00e3o ser\u00e1 compartilhado para v\u00e1rias chamadas.<\/p>\n<p>Nota: vers\u00f5es anteriores deste artigo recomendavam vincular o bin\u00e1rio do Docker do host ao cont\u00eainer. Isso agora \u00e9 considerado pouco confi\u00e1vel, uma vez que o mecanismo Docker n\u00e3o se aplica mais a bibliotecas est\u00e1ticas ou quase est\u00e1ticas.<\/p>\n<p>Assim, se voc\u00ea deseja usar o Docker a partir do Jenkins CI, voc\u00ea tem 2 op\u00e7\u00f5es:<br \/>\ninstalar a CLI do Docker usando o sistema b\u00e1sico de empacotamento de imagem (ou seja, se sua imagem for baseada em Debian, use pacotes .deb), usar a API do Docker.<\/p>\n<h3>Um pouco de publicidade \ud83d\ude42<\/h3>\n<p>\nObrigado por permanecer conosco. Voc\u00ea gosta dos nossos artigos? Quer ver mais materiais interessantes? Apoie-nos fazendo um pedido ou recomendando para conhecidos. <noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/cloudvps\/nl\">VPS em nuvem para desenvolvedores a partir de $4.99<\/a><\/noindex>, <b>uma alternativa \u00fanica aos servidores entry-level, que criamos para voc\u00ea:<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/347386\/\">Toda a verdade sobre VPS (KVM) E5-2697 v3 (6 N\u00facleos) 10GB DDR4 480GB SSD 1Gbps a partir de $19 ou como dividir um servidor corretamente?<\/a><\/noindex> (dispon\u00edveis op\u00e7\u00f5es com RAID1 e RAID10, at\u00e9 24 n\u00facleos e at\u00e9 40GB DDR4).<\/p>\n<p><b>Dell R730xd por 2 vezes mais barato no datacenter Equinix Tier IV em Amsterd\u00e3?<\/b> Somente conosco <b><noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/serversnl\">2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100TB a partir de $199<\/a><\/noindex> na Holanda! <b>Dell R420 \u2014 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB \u2014 a partir de $99!<\/b><\/b> Leia sobre <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/329618\/\">Como construir uma infraestrutura de classe corporativa utilizando servidores Dell R730xd E5-2650 v4 com custo de 9000 euros por centavos?<\/a><\/noindex><br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ua-hosting\/blog\/488536\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Docker-in-Docker \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 Docker-\u0434\u0435\u043c\u043e\u043d, \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u0443\u044e \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0435\u043b\u044c\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f Docker-in-Docker \u0431\u044b\u043b\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0430\u043c\u043e\u0433\u043e Docker. \u041c\u043d\u043e\u0433\u0438\u0435 \u043b\u044e\u0434\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0435\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Jenkins CI. \u041f\u043e\u043d\u0430\u0447\u0430\u043b\u0443 \u044d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u043c, \u043d\u043e \u0437\u0430\u0442\u0435\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 Docker \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 Jenkins CI. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u044d\u0442\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":52072,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-52071","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\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\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy\" \/>\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\udd47\u0425\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker-in-Docker \u0434\u043b\u044f CI \u0438\u043b\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0440\u0435\u0434\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy\" \/>\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-18T02:34:24+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T02:34:24+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\udd47Pense bem antes de usar Docker-in-Docker para CI ou ambiente de teste | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy","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\udd47\u0425\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker-in-Docker \u0434\u043b\u044f CI \u0438\u043b\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0440\u0435\u0434\u044b | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/pt\/blog\/horosho-podumajte-prezhde-chem-ispolzovat-docker-in-docker-dlya-ci-ili-testovoj-sredy","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-18T02:34:24+00:00","article:modified_time":"2020-02-18T02:34:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52071","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 20:50:23","updated":"2022-09-27 17:46:30","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\/52071","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=52071"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/52071\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/52072"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=52071"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=52071"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=52071"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}