<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Deploy Automatizado - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/deploy-automatizado/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Fri, 04 Jul 2025 20:22:35 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>Deploy Automatizado - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tutorial Completo de Cloud DevOps com Docker, CI/CD e Monitoramento &#8211; Parte 1</title>
		<link>https://mcu.tec.br/infraestrutura/tutorial-completo-de-cloud-devops-com-docker-ci-cd-e-monitoramento-parte-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tutorial-completo-de-cloud-devops-com-docker-ci-cd-e-monitoramento-parte-1</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 04 Jul 2025 19:36:11 +0000</pubDate>
				<category><![CDATA[Infraestrutura]]></category>
		<category><![CDATA[Aplicação em produção]]></category>
		<category><![CDATA[Boas práticas DevOps]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud DevOps]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Cultura DevOps]]></category>
		<category><![CDATA[Deploy Automatizado]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DevOps com Python]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Engenharia de Software]]></category>
		<category><![CDATA[Entrega Contínua]]></category>
		<category><![CDATA[Feedback Contínuo]]></category>
		<category><![CDATA[Flask com Docker]]></category>
		<category><![CDATA[GitHub Actions]]></category>
		<category><![CDATA[Grafana]]></category>
		<category><![CDATA[Infraestrutura como Código]]></category>
		<category><![CDATA[Integração Contínua]]></category>
		<category><![CDATA[Log centralizado]]></category>
		<category><![CDATA[Monitoramento]]></category>
		<category><![CDATA[Observabilidade]]></category>
		<category><![CDATA[Pipeline DevOps]]></category>
		<category><![CDATA[Prometheus]]></category>
		<category><![CDATA[Tutorial DevOps]]></category>
		<category><![CDATA[Versionamento de imagens Docker]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=560</guid>

					<description><![CDATA[<p>Aprenda passo a passo como implementar DevOps na prática com Docker, integração contínua (CI), entrega contínua (CD) e monitoramento em nuvem. Ideal para desenvolvedores e profissionais de infraestrutura que buscam automatizar e escalar aplicações com eficiência e confiabilidade.</p>
<p>The post <a href="https://mcu.tec.br/infraestrutura/tutorial-completo-de-cloud-devops-com-docker-ci-cd-e-monitoramento-parte-1/">Tutorial Completo de Cloud DevOps com Docker, CI/CD e Monitoramento – Parte 1</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Introdução ao Tutorial de Cloud DevOps</h2>



<p class="wp-block-paragraph">Este tutorial marca o início da jornada na criação de ambientes reais utilizando Docker dentro do contexto da filosofia DevOps. A proposta vai muito além de ensinar o uso de ferramentas específicas. O objetivo é apresentar uma cultura de colaboração entre desenvolvimento e operações, promovendo automação, escalabilidade e portabilidade em aplicações modernas.</p>



<p class="wp-block-paragraph">Nesta primeira etapa, o foco está em entender o papel do DevOps como facilitador da entrega contínua, da confiabilidade e da padronização de ambientes. Será demonstrado como uma aplicação desenvolvida em Python pode ser estruturada para ser executada com consistência em diferentes sistemas operacionais.</p>



<p class="wp-block-paragraph">O conteúdo explora como transformar um projeto funcional em um ambiente local em um serviço encapsulado com Docker, pronto para ser executado de forma segura e escalável, tanto localmente quanto na nuvem.</p>



<p class="wp-block-paragraph">O tutorial não se aprofunda no código da aplicação em si, mas sim em como tornar a aplicação portátil, replicável e independente do ambiente onde será executada. Essa abordagem reflete o verdadeiro papel do profissional DevOps: garantir que aplicações funcionem de forma previsível e segura em qualquer lugar.</p>



<h2 class="wp-block-heading">O que é DevOps e sua História</h2>



<p class="wp-block-paragraph">O termo <strong>DevOps</strong> é uma junção de duas palavras: <strong>Development</strong> (desenvolvimento) e <strong>Operations</strong> (operações). Trata-se de uma <strong>filosofia de trabalho</strong> e <strong>conjunto de práticas culturais e técnicas</strong> que visam integrar os times de desenvolvimento de software com os times responsáveis pela infraestrutura e operação dos sistemas. O objetivo é <strong>automatizar processos</strong>, <strong>melhorar a colaboração</strong>, <strong>aumentar a velocidade das entregas</strong> e <strong>manter a confiabilidade das aplicações</strong> em ambientes complexos e em constante mudança.</p>



<h3 class="wp-block-heading">Origens e Evolução</h3>



<p class="wp-block-paragraph">Na década de 1980, o desenvolvimento de software era centralizado e vinculado diretamente ao hardware. As equipes de desenvolvimento e operação trabalhavam de forma isolada, com pouca comunicação entre si. Essa abordagem seguiu por muito tempo, marcada por ciclos longos e sequenciais de entrega, conhecidos como <strong>modelo em cascata</strong> (Waterfall).</p>



<p class="wp-block-paragraph">Com a popularização dos computadores pessoais nos anos 1990, surgiram os primeiros servidores dedicados e aplicações cliente-servidor. Mesmo com esse avanço, as organizações ainda mantinham a separação rígida entre desenvolvimento e operações, o que gerava conflitos, atrasos e uma constante transferência de responsabilidades em caso de falhas.</p>



<p class="wp-block-paragraph">Foi apenas nos anos 2000, com a introdução do <strong>Manifesto Ágil</strong> (2001), que começou uma transformação cultural importante. As equipes passaram a trabalhar com ciclos curtos, feedback contínuo e colaboração entre áreas como desenvolvimento, testes e análise de negócios. Contudo, ainda persistia a separação das operações de TI, o que impedia uma integração plena entre todos os envolvidos no ciclo de vida da aplicação.</p>



<p class="wp-block-paragraph">A virada decisiva ocorreu em <strong>2009</strong>, quando foi apresentada publicamente uma abordagem capaz de realizar <strong>diversos deploys diários com baixo risco e alta confiabilidade</strong>, promovendo a automação de infraestrutura, controle de versão compartilhado e práticas como <strong>infraestrutura como código</strong> (IaC). Também foi criado, no mesmo ano, o evento internacional <strong>DevOpsDays</strong>, responsável por consolidar o termo “DevOps” como um movimento mundial. Foi nesse momento que se tornou evidente que <strong>mudanças pequenas, contínuas e colaborativas são mais eficazes do que grandes lançamentos esporádicos</strong>.</p>



<h3 class="wp-block-heading">Princípios e Benefícios</h3>



<p class="wp-block-paragraph">DevOps propõe que todos os envolvidos no desenvolvimento de uma aplicação — desde os requisitos até a operação em produção — atuem como <strong>um sistema integrado</strong>, com <strong>confiança mútua</strong>, <strong>respeito</strong>, <strong>aprendizado contínuo</strong>, e foco em <strong>entregar valor com qualidade e estabilidade</strong>.</p>



<p class="wp-block-paragraph">Entre os benefícios da adoção de práticas DevOps, destacam-se:</p>



<ul class="wp-block-list">
<li>Redução de riscos operacionais e falhas em produção;</li>



<li>Maior qualidade nas entregas de software;</li>



<li>Aumento da produtividade e eficiência da equipe;</li>



<li>Feedback contínuo dos usuários e dos sistemas;</li>



<li>Integração contínua (CI) e entrega contínua (CD);</li>



<li>Monitoramento proativo e correções rápidas.</li>
</ul>



<h3 class="wp-block-heading">DevOps Hoje</h3>



<p class="wp-block-paragraph">Com o avanço de tecnologias como <strong>virtualização</strong>, <strong>containers</strong>, <strong>cloud computing</strong> e <strong>orquestração com Kubernetes</strong>, DevOps se consolidou como uma abordagem essencial para empresas que desejam escalar suas operações, melhorar a resiliência dos sistemas e reduzir o tempo de resposta às mudanças do mercado.</p>



<p class="wp-block-paragraph">Essa filosofia é hoje aplicada em diversos setores, incluindo bancos, e-commerce, telecomunicações, saúde e indústria, sendo uma peça-chave na transformação digital e na inovação contínua.</p>



<h2 class="wp-block-heading">Analisando o Projeto e Criando o Ambiente Virtual com Python</h2>



<p class="wp-block-paragraph">O primeiro passo prático no tutorial é conhecer a aplicação que será utilizada como base para as atividades DevOps. Trata-se de uma aplicação desenvolvida em Python com o framework <strong>Flask</strong>, escolhida por sua leveza e simplicidade, ideal para demonstrar práticas de empacotamento, deploy e monitoramento.</p>



<p class="wp-block-paragraph">A estrutura inicial do projeto conta com arquivos básicos como <code>app.py</code>, que contém a lógica principal do servidor, e um diretório de templates com arquivos HTML que definem a interface web da aplicação. Também estão presentes arquivos auxiliares como <code>requirements.txt</code>, onde são listadas todas as dependências necessárias para executar o projeto, e o <code>.gitignore</code>, que define quais arquivos não devem ser versionados.</p>



<p class="wp-block-paragraph">Para garantir que o ambiente seja consistente em diferentes sistemas operacionais e livre de conflitos com outras bibliotecas instaladas no sistema, é criada uma <strong>virtual environment (ambiente virtual Python)</strong>. Esse ambiente isolado garante que as dependências da aplicação fiquem contidas em um único espaço, controlado e replicável.</p>



<p class="wp-block-paragraph">O processo de criação do ambiente virtual segue os seguintes passos:</p>



<ol class="wp-block-list">
<li><strong>Criação do ambiente virtual:</strong> <code>python -m venv venv</code> Isso cria uma pasta chamada <code>venv</code> contendo a estrutura necessária para o isolamento.</li>



<li><strong>Ativação do ambiente:</strong><ul><li>Em sistemas Unix/Linux/macOS: <code>source venv/bin/activate</code></li><li>Em sistemas Windows: <code>.\venv\Scripts\activate</code></li></ul>Após ativado, o terminal indicará que o ambiente virtual está ativo, geralmente com o prefixo <code>(venv)</code>.</li>



<li><strong>Instalação das dependências da aplicação:</strong> <code>pip install -r requirements.txt</code> Isso garante que todas as bibliotecas utilizadas pela aplicação estejam instaladas corretamente no ambiente isolado.</li>
</ol>



<p class="wp-block-paragraph">Com o ambiente configurado, o próximo passo será a <strong>execução local da aplicação</strong>, permitindo verificar se tudo está funcionando corretamente antes de seguir para o empacotamento com Docker.</p>



<h2 class="wp-block-heading">Executando a Aplicação Localmente e Entendendo o Ciclo de Vida DevOps</h2>



<p class="wp-block-paragraph">Com o ambiente virtual Python ativado e as dependências instaladas, o próximo passo é <strong>executar a aplicação localmente</strong>. Isso permite garantir que tudo está funcionando corretamente antes de iniciar o processo de empacotamento, automação e deploy.</p>



<p class="wp-block-paragraph">A aplicação Flask pode ser executada com o seguinte comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="python app.py
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">python</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">py</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ao rodar esse comando, o servidor local será iniciado, geralmente escutando na porta <code>5000</code>. Acesse <code>http://localhost:5000</code> no navegador para visualizar a interface da aplicação.</p>



<p class="wp-block-paragraph">Esse processo de execução local é essencial dentro do ciclo de vida DevOps, pois representa a <strong>fase de desenvolvimento e validação inicial</strong>, onde o código é testado manualmente antes de seguir para etapas mais avançadas como integração contínua, testes automatizados, entrega e monitoramento.</p>



<h3 class="wp-block-heading">O Ciclo de Vida DevOps</h3>



<p class="wp-block-paragraph">No contexto DevOps, o ciclo de vida de uma aplicação não se limita à sua construção. Ele envolve uma série de etapas que trabalham de forma contínua e colaborativa:</p>



<ol class="wp-block-list">
<li><strong>Planejamento</strong><br>Levantamento de requisitos, definição de funcionalidades e arquitetura da solução.</li>



<li><strong>Desenvolvimento</strong><br>Codificação do sistema com foco em modularidade, testes e versionamento.</li>



<li><strong>Integração e Testes</strong><br>Automatização de testes e validações a cada nova modificação no código, utilizando pipelines de integração contínua (CI).</li>



<li><strong>Entrega e Deploy</strong><br>Preparação do sistema para produção com automação de build, empacotamento (ex: containers) e publicação.</li>



<li><strong>Operação e Monitoramento</strong><br>Garantia da estabilidade da aplicação em produção com uso de ferramentas de observabilidade, logs, alertas e métricas.</li>



<li><strong>Feedback Contínuo</strong><br>Retorno constante do sistema, dos usuários e das métricas de produção para ajustes e melhorias contínuas.</li>
</ol>



<p class="wp-block-paragraph">Executar a aplicação localmente é uma etapa essencial que precede a automação. Ela garante que todos os requisitos foram corretamente instalados e que a aplicação está apta para ser <strong>empacotada</strong> — tema da próxima seção do tutorial.</p>



<h2 class="wp-block-heading">Containerizando a Aplicação com Docker</h2>



<p class="wp-block-paragraph">Agora que a aplicação está funcionando corretamente em ambiente local, o próximo passo é torná-la independente do sistema operacional onde será executada. Isso é feito através do <strong>Docker</strong>, uma tecnologia que permite empacotar a aplicação e suas dependências em uma imagem leve e portátil chamada <strong>container</strong>.</p>



<h3 class="wp-block-heading">O que é Docker?</h3>



<p class="wp-block-paragraph">Docker é uma plataforma que automatiza a criação, o empacotamento e a execução de aplicações em <strong>ambientes isolados</strong>. Com ele, é possível garantir que a aplicação funcione exatamente da mesma forma em qualquer máquina — seja localmente, em um servidor de produção ou na nuvem.</p>



<p class="wp-block-paragraph">Diferente de máquinas virtuais, containers compartilham o mesmo kernel do sistema operacional, tornando-os muito mais leves e rápidos.</p>



<h3 class="wp-block-heading">Criando o Dockerfile</h3>



<p class="wp-block-paragraph">O primeiro passo é criar um arquivo chamado <code>Dockerfile</code> na raiz do projeto. Esse arquivo define <strong>instruções passo a passo</strong> para construir a imagem da aplicação. Veja um exemplo básico:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="# Imagem base oficial do Python
FROM python:3.11

# Diretório de trabalho no container
WORKDIR /app

# Copia os arquivos do projeto para o container
COPY . .

# Instala as dependências da aplicação
RUN pip install -r requirements.txt

# Expõe a porta utilizada pelo Flask
EXPOSE 5000

# Comando para iniciar a aplicação
CMD [&quot;python&quot;, &quot;app.py&quot;]
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Imagem</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">oficial</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Python</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> python</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">3.11</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Diretório</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">trabalho</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">no</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">container</span></span>
<span class="line"><span style="color: #D8DEE9">WORKDIR</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Copia</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">os</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">arquivos</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">projeto</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">container</span></span>
<span class="line"><span style="color: #D8DEE9">COPY</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Instala</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> dependências da aplicação</span></span>
<span class="line"><span style="color: #D8DEE9">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">requirements</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">txt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Expõe</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">porta</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">utilizada</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pelo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Flask</span></span>
<span class="line"><span style="color: #D8DEE9">EXPOSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5000</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Comando</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">iniciar</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">aplicação</span></span>
<span class="line"><span style="color: #D8DEE9">CMD</span><span style="color: #D8DEE9FF"> [</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">python</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">app.py</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">]</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Cada instrução cumpre uma etapa essencial:</p>



<ul class="wp-block-list">
<li><code>FROM</code> define a base da imagem (no caso, Python 3.11).</li>



<li><code>WORKDIR</code> cria o diretório interno onde o código será executado.</li>



<li><code>COPY . .</code> transfere os arquivos da aplicação local para dentro do container.</li>



<li><code>RUN</code> executa o comando de instalação das dependências.</li>



<li><code>EXPOSE</code> informa qual porta será usada.</li>



<li><code>CMD</code> define o comando final que roda a aplicação.</li>
</ul>



<h3 class="wp-block-heading">Construindo a Imagem Docker</h3>



<p class="wp-block-paragraph">Com o <code>Dockerfile</code> criado, o próximo passo é <strong>construir a imagem</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker build -t app-devops .
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">build</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">devops</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse comando instrui o Docker a ler o <code>Dockerfile</code> e construir uma imagem chamada <code>app-devops</code>.</p>



<h3 class="wp-block-heading">Executando a Aplicação no Container</h3>



<p class="wp-block-paragraph">Uma vez criada a imagem, a aplicação pode ser executada dentro de um container com:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker run -p 5000:5000 app-devops
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5000</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">5000</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">devops</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O parâmetro <code>-p 5000:5000</code> faz o mapeamento da porta do container para a porta local, permitindo o acesso via <code>http://localhost:5000</code>.</p>



<p class="wp-block-paragraph">Agora, a aplicação está empacotada com tudo o que precisa para rodar de forma consistente, replicável e portátil. Este é o <strong>primeiro passo concreto rumo à automação e à escalabilidade</strong>, base para práticas mais avançadas de DevOps.</p>



<h2 class="wp-block-heading">Versionamento e Imagens Docker Otimizadas</h2>



<p class="wp-block-paragraph">Com a aplicação containerizada e funcionando, é hora de adotar práticas que tornam o processo mais profissional e escalável. Um dos principais aspectos nesse estágio é o <strong>versionamento das imagens</strong> e a <strong>otimização do Dockerfile</strong>, garantindo performance, segurança e controle de versões durante o ciclo de vida do projeto.</p>



<h3 class="wp-block-heading">Por que versionar as imagens?</h3>



<p class="wp-block-paragraph">Ao versionar uma imagem Docker, você evita confusões entre builds diferentes da aplicação. Isso permite, por exemplo:</p>



<ul class="wp-block-list">
<li>Identificar qual versão do container está em produção;</li>



<li>Fazer rollback em caso de falhas;</li>



<li>Executar testes A/B entre versões distintas;</li>



<li>Facilitar a integração com pipelines de CI/CD.</li>
</ul>



<p class="wp-block-paragraph">O versionamento pode ser feito no momento da construção da imagem:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker build -t app-devops:1.0.0 .
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">build</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Depois, para executar essa versão específica:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker run -p 5000:5000 app-devops:1.0.0
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5000</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">5000</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Otimizando o Dockerfile</h3>



<p class="wp-block-paragraph">A criação de imagens mais enxutas e seguras impacta diretamente no tempo de build, no espaço ocupado em disco e na segurança do ambiente. Algumas boas práticas incluem:</p>



<h4 class="wp-block-heading">1. <strong>Usar imagens menores (ex: Alpine)</strong></h4>



<p class="wp-block-paragraph">Ao invés de usar <code>python:3.11</code>, que é baseada no Debian e possui muitos pacotes desnecessários, é possível utilizar:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="FROM python:3.11-alpine
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> python</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">3.11</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">alpine</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa imagem é significativamente menor, porém requer alguns ajustes nas dependências e ferramentas, pois nem tudo está disponível por padrão.</p>



<h4 class="wp-block-heading">2. <strong>Separar camadas com mais eficiência</strong></h4>



<p class="wp-block-paragraph">Cada comando em um Dockerfile cria uma camada. Agrupar instruções reduz o número de camadas e melhora o cache:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="RUN pip install --no-cache-dir -r requirements.txt
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">no</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">cache</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">dir</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">requirements</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">txt</span></span>
<span class="line"></span></code></pre></div>



<h4 class="wp-block-heading">3. <strong>Ignorar arquivos desnecessários com <code>.dockerignore</code></strong></h4>



<p class="wp-block-paragraph">Assim como o <code>.gitignore</code>, o <code>.dockerignore</code> evita que arquivos como logs, <code>.venv/</code>, <code>__pycache__/</code>, e outros diretórios desnecessários sejam incluídos na imagem:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="__pycache__/
*.pyc
.venv/
.env
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">__pycache__</span><span style="color: #81A1C1">/</span></span>
<span class="line"><span style="color: #81A1C1">*</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">pyc</span></span>
<span class="line"><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">venv</span><span style="color: #81A1C1">/</span></span>
<span class="line"><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Verificando o tamanho e camadas da imagem</h3>



<p class="wp-block-paragraph">Use o comando abaixo para investigar o tamanho da imagem criada:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker image ls
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">image</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ls</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ou para examinar as camadas em detalhes:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker history app-devops:1.0.0
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">history</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Publicando a imagem no Docker Hub (opcional)</h3>



<p class="wp-block-paragraph">Caso deseje compartilhar sua imagem com outros membros da equipe ou utilizá-la em pipelines CI/CD, é possível enviá-la ao Docker Hub:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker tag app-devops:1.0.0 seu-usuario/app-devops:1.0.0
docker push seu-usuario/app-devops:1.0.0
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tag</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seu</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">usuario</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">push</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seu</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">usuario</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">1.0</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Para isso, é necessário ter uma conta gratuita no <a href="https://hub.docker.com/">Docker Hub</a>.</p>



<h2 class="wp-block-heading">Criando um Pipeline de Integração Contínua (CI)</h2>



<p class="wp-block-paragraph">Após a containerização da aplicação e a adoção de boas práticas com Docker, é hora de automatizar o processo de build e validação utilizando <strong>Integração Contínua (Continuous Integration &#8211; CI)</strong>. O objetivo da CI é garantir que, a cada alteração feita no código, a aplicação seja testada, empacotada e validada automaticamente, reduzindo erros e acelerando o ciclo de desenvolvimento.</p>



<h3 class="wp-block-heading">O que é Integração Contínua?</h3>



<p class="wp-block-paragraph">Integração Contínua é uma prática onde os desenvolvedores enviam mudanças frequentes ao repositório, geralmente hospedado em plataformas como GitHub, GitLab ou Bitbucket. Cada commit dispara uma série de ações automáticas:</p>



<ul class="wp-block-list">
<li><strong>Download do código atualizado</strong>;</li>



<li><strong>Execução de testes automatizados</strong>;</li>



<li><strong>Construção da imagem Docker</strong>;</li>



<li><strong>Validação do build</strong>.</li>
</ul>



<p class="wp-block-paragraph">Essas ações são definidas por meio de <strong>pipelines</strong>, descritas em arquivos YAML que informam à plataforma como automatizar as etapas desejadas.</p>



<h3 class="wp-block-heading">Exemplo com GitHub Actions</h3>



<p class="wp-block-paragraph">Para projetos hospedados no GitHub, cria-se um arquivo chamado <code>ci.yml</code> dentro do diretório <code>.github/workflows/</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="name: CI DevOps Tutorial

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Clonando o repositório
      uses: actions/checkout@v3

    - name: Instalando o Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'

    - name: Instalando dependências
      run: |
        python -m venv venv
        source venv/bin/activate
        pip install -r requirements.txt

    - name: Executando testes
      run: |
        source venv/bin/activate
        python -m unittest discover tests

    - name: Build da imagem Docker
      run: |
        docker build -t app-devops:ci .

" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CI</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DevOps</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Tutorial</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">on</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  push</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    branches</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [ </span><span style="color: #D8DEE9">main</span><span style="color: #D8DEE9FF"> ]</span></span>
<span class="line"><span style="color: #D8DEE9FF">  pull_request</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    branches</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [ </span><span style="color: #D8DEE9">main</span><span style="color: #D8DEE9FF"> ]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">jobs</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  build</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">runs</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">on</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ubuntu</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">latest</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    steps</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Clonando</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">repositório</span></span>
<span class="line"><span style="color: #D8DEE9FF">      uses</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">actions</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">checkout</span><span style="color: #D8DEE9FF">@</span><span style="color: #D8DEE9">v3</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Instalando</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Python</span></span>
<span class="line"><span style="color: #D8DEE9FF">      uses</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">actions</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">setup</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">python</span><span style="color: #D8DEE9FF">@</span><span style="color: #D8DEE9">v4</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">python</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">version</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">3.11</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Instalando</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dependências</span></span>
<span class="line"><span style="color: #D8DEE9FF">      run</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">python</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">m</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">venv</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">venv</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">source</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">venv</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">bin</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">activate</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">requirements</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">txt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Executando</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">testes</span></span>
<span class="line"><span style="color: #D8DEE9FF">      run</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">source</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">venv</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">bin</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">activate</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">python</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">m</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">unittest</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">discover</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tests</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Build</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imagem</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Docker</span></span>
<span class="line"><span style="color: #D8DEE9FF">      run</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">build</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">ci</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse pipeline define o seguinte:</p>



<ol class="wp-block-list">
<li>O processo é acionado quando há <code>push</code> ou <code>pull request</code> na branch <code>main</code>.</li>



<li>O GitHub Actions baixa o código, instala o Python 3.11 e configura o ambiente virtual.</li>



<li>Instala as dependências e executa os testes contidos no diretório <code>tests/</code>.</li>



<li>Se os testes forem bem-sucedidos, constrói a imagem Docker.</li>
</ol>



<h3 class="wp-block-heading">Vantagens do Pipeline de CI</h3>



<ul class="wp-block-list">
<li><strong>Validação automática do código</strong>;</li>



<li><strong>Redução de erros em produção</strong>;</li>



<li><strong>Feedback imediato sobre falhas</strong>;</li>



<li><strong>Base sólida para práticas de CD (entrega contínua)</strong>.</li>
</ul>



<p class="wp-block-paragraph">Este é um passo essencial para garantir que a aplicação esteja sempre pronta para ser implantada, com qualidade e consistência.</p>



<h2 class="wp-block-heading">Entrega Contínua (CD) e Automação do Deploy</h2>



<p class="wp-block-paragraph">Após configurar a Integração Contínua (CI) para testar e construir a aplicação automaticamente, o próximo passo no fluxo DevOps é implementar a <strong>Entrega Contínua (CD – Continuous Delivery)</strong>. Essa etapa garante que o sistema esteja sempre pronto para ser implantado com segurança em produção, com processos automatizados e previsíveis.</p>



<h3 class="wp-block-heading">O que é Entrega Contínua?</h3>



<p class="wp-block-paragraph">A Entrega Contínua é uma extensão natural da Integração Contínua. Ela automatiza o processo de <strong>deploy em ambientes de teste, homologação ou produção</strong>, sempre que um novo build é aprovado. Em um fluxo bem configurado, é possível que o deploy aconteça automaticamente — ou com um simples clique de aprovação.</p>



<h3 class="wp-block-heading">Como funciona na prática?</h3>



<p class="wp-block-paragraph">Para automatizar o deploy, é comum configurar etapas adicionais no pipeline, como:</p>



<ul class="wp-block-list">
<li>Publicar a imagem Docker em um registro de containers (ex: Docker Hub, GitHub Container Registry, Amazon ECR);</li>



<li>Realizar o deploy em um ambiente controlado (ex: servidor de staging, Kubernetes, máquina virtual ou instância na nuvem);</li>



<li>Executar scripts de verificação pós-deploy (ex: health check ou rollback automático).</li>
</ul>



<h3 class="wp-block-heading">Continuando o exemplo com GitHub Actions</h3>



<p class="wp-block-paragraph">Vamos expandir o pipeline para que, após o sucesso dos testes e build, a imagem seja enviada para o Docker Hub:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="    - name: Login no Docker Hub
      run: echo &quot;${{ secrets.DOCKER_PASSWORD }}&quot; | docker login -u &quot;${{ secrets.DOCKER_USERNAME }}&quot; --password-stdin

    - name: Tag e push da imagem
      run: |
        docker tag app-devops:ci ${{ secrets.DOCKER_USERNAME }}/app-devops:latest
        docker push ${{ secrets.DOCKER_USERNAME }}/app-devops:latest
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Login</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">no</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Hub</span></span>
<span class="line"><span style="color: #D8DEE9FF">      run</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">echo</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">${{ secrets.DOCKER_PASSWORD }}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">login</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">u</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">${{ secrets.DOCKER_USERNAME }}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">password</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">stdin</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Tag</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">push</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imagem</span></span>
<span class="line"><span style="color: #D8DEE9FF">      run</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tag</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">ci</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$</span><span style="color: #ECEFF4">{{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">secrets</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">DOCKER_USERNAME</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}}</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">latest</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">push</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$</span><span style="color: #ECEFF4">{{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">secrets</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">DOCKER_USERNAME</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}}</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">latest</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essas etapas:</p>



<ol class="wp-block-list">
<li><strong>Autenticam-se no Docker Hub</strong> usando segredos seguros armazenados no GitHub (<code>secrets</code>).</li>



<li><strong>Tagueiam a imagem com <code>latest</code></strong> (ou uma versão, se preferir).</li>



<li><strong>Publicam a imagem no repositório Docker</strong>, tornando-a disponível para deploy em qualquer lugar.</li>
</ol>



<h3 class="wp-block-heading">Realizando o Deploy</h3>



<p class="wp-block-paragraph">Uma vez publicada, a imagem pode ser implantada com comandos simples, como:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker pull seu-usuario/app-devops:latest
docker run -d -p 80:5000 seu-usuario/app-devops:latest
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pull</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seu</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">usuario</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">latest</span></span>
<span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">80</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">5000</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seu</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">usuario</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">devops</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">latest</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ou, em ambientes mais robustos, o deploy pode ser automatizado via:</p>



<ul class="wp-block-list">
<li><strong>Docker Compose</strong>;</li>



<li><strong>Kubernetes com Helm Charts</strong>;</li>



<li><strong>Plataformas de PaaS como Heroku, Render, ou Google Cloud Run</strong>.</li>
</ul>



<h3 class="wp-block-heading">Benefícios da Entrega Contínua</h3>



<ul class="wp-block-list">
<li><strong>Deploys mais frequentes e confiáveis</strong>;</li>



<li><strong>Menor risco de erro humano</strong>;</li>



<li><strong>Ambientes padronizados e rastreáveis</strong>;</li>



<li><strong>Maior rapidez na correção de bugs e lançamento de features</strong>.</li>
</ul>



<p class="wp-block-paragraph">A Entrega Contínua representa um marco na maturidade de equipes DevOps, sendo o elo entre o desenvolvimento ágil e a operação estável e segura.</p>



<h2 class="wp-block-heading">Monitoramento da Aplicação em Produção</h2>



<p class="wp-block-paragraph">Uma vez que a aplicação está em produção, torna-se essencial acompanhar seu comportamento em tempo real. O <strong>monitoramento contínuo</strong> permite identificar falhas rapidamente, antecipar problemas de desempenho e garantir que os usuários finais estejam tendo uma boa experiência.</p>



<p class="wp-block-paragraph">Essa prática é um dos fundamentos do DevOps moderno e deve ser implementada <strong>desde os primeiros estágios do projeto</strong>, e não apenas quando surgem erros em produção.</p>



<h3 class="wp-block-heading">O que é monitorar uma aplicação?</h3>



<p class="wp-block-paragraph">Monitorar é mais do que apenas verificar se a aplicação está “no ar”. Envolve:</p>



<ul class="wp-block-list">
<li><strong>Coleta de métricas</strong> como uso de CPU, memória, número de requisições, tempo de resposta e taxa de erro;</li>



<li><strong>Análise de logs</strong> para identificar falhas, mensagens de erro e comportamentos inesperados;</li>



<li><strong>Visualização e alertas</strong>, com dashboards e sistemas de notificação automática.</li>
</ul>



<h3 class="wp-block-heading">Ferramentas DevOps para Monitoramento</h3>



<p class="wp-block-paragraph">Algumas ferramentas populares que podem ser integradas a projetos Dockerizados e ambientes em nuvem incluem:</p>



<ul class="wp-block-list">
<li><strong>Prometheus</strong>: coleta e armazena métricas em séries temporais. Muito usado com Kubernetes.</li>



<li><strong>Grafana</strong>: cria dashboards interativos com base nos dados do Prometheus ou outras fontes.</li>



<li><strong>Loki</strong>: sistema de logs criado pelos mesmos desenvolvedores do Grafana, ideal para uso conjunto.</li>



<li><strong>ELK Stack (Elasticsearch + Logstash + Kibana)</strong>: usado para indexar e visualizar logs em larga escala.</li>
</ul>



<h3 class="wp-block-heading">Exemplo simples com Prometheus + Grafana</h3>



<p class="wp-block-paragraph">Se você está rodando a aplicação via Docker, pode usar <strong>exporters</strong> para coletar métricas. Um exemplo clássico é o <a href="https://github.com/prometheus/client_python">Prometheus Python Client</a>.</p>



<h4 class="wp-block-heading">1. Instalando o pacote no projeto</h4>



<p class="wp-block-paragraph">No <code>requirements.txt</code>, adicione:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="prometheus_client
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">prometheus_client</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">No <code>app.py</code>, adicione:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="from prometheus_client import start_http_server, Summary

REQUEST_TIME = Summary('request_processing_seconds', 'Tempo de processamento de requisições')

@app.before_first_request
def start_metrics():
    start_http_server(8000)  # Porta separada para Prometheus coletar métricas
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">prometheus_client</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">start_http_server</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Summary</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">REQUEST_TIME</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">Summary</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">request_processing_seconds</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Tempo de processamento de requisições</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">@</span><span style="color: #8FBCBB">app</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">before_first_request</span></span>
<span class="line"><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">start_metrics</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">start_http_server</span><span style="color: #D8DEE9FF">(8000)  # </span><span style="color: #8FBCBB">Porta</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">separada</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Prometheus</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">coletar</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">métricas</span></span>
<span class="line"></span></code></pre></div>



<h4 class="wp-block-heading">2. Configurando Prometheus</h4>



<p class="wp-block-paragraph">Crie um arquivo <code>prometheus.yml</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="global:
  scrape_interval: 10s

scrape_configs:
  - job_name: 'flask-app'
    static_configs:
      - targets: ['localhost:8000']
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">global</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  scrape_interval</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">s</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">scrape_configs</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> job_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">flask-app</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    static_configs</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> targets</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">localhost:8000</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">]</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Inicie o Prometheus com Docker:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker run -d -p 9090:9090 -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9090</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">9090</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">v</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$PWD</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">prometheus</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">yml</span><span style="color: #D8DEE9FF">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">etc</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">prometheus</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">prometheus</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">yml</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">prom</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">prometheus</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Acesse <code>http://localhost:9090</code> para visualizar as métricas sendo coletadas.</p>



<h4 class="wp-block-heading">3. Visualizando com Grafana</h4>



<p class="wp-block-paragraph">Com Prometheus rodando, instale o Grafana:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker run -d -p 3000:3000 grafana/grafana
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3000</span><span style="color: #D8DEE9FF">:</span><span style="color: #B48EAD">3000</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">grafana</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">grafana</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Acesse <code>http://localhost:3000</code>, conecte ao Prometheus como fonte de dados e crie dashboards para acompanhar o tempo de resposta, volume de requisições, e muito mais.</p>



<h3 class="wp-block-heading">Por que monitorar desde o início?</h3>



<ul class="wp-block-list">
<li><strong>Reduz o tempo de detecção de falhas (MTTD)</strong>;</li>



<li><strong>Facilita decisões baseadas em dados reais</strong>;</li>



<li><strong>Melhora a experiência do usuário final</strong>;</li>



<li><strong>Ajuda a provar o valor do DevOps com indicadores claros</strong>.</li>
</ul>



<h2 class="wp-block-heading">Feedback Contínuo e Melhoria Constante</h2>



<p class="wp-block-paragraph">A última etapa — e talvez a mais crítica — do ciclo DevOps é o <strong>feedback contínuo</strong>. Sem ele, todo o esforço em automação, integração, entrega e monitoramento perde seu valor estratégico. O feedback contínuo conecta as experiências reais de uso com o time de desenvolvimento e operação, possibilitando <strong>aprendizado rápido</strong>, <strong>respostas ágeis</strong> e <strong>melhorias sustentáveis</strong> ao longo do tempo.</p>



<h3 class="wp-block-heading">O que é feedback contínuo?</h3>



<p class="wp-block-paragraph">No contexto DevOps, feedback contínuo é o processo de <strong>coletar informações em tempo real</strong> sobre o comportamento do sistema em produção e compartilhar essas informações com todos os envolvidos:</p>



<ul class="wp-block-list">
<li>Desenvolvedores;</li>



<li>Engenheiros de operações;</li>



<li>Analistas de negócios;</li>



<li>Responsáveis por produto;</li>



<li>E até usuários finais (indiretamente, por meio de métricas de uso).</li>
</ul>



<h3 class="wp-block-heading">Fontes de feedback no ciclo DevOps</h3>



<p class="wp-block-paragraph">O feedback pode vir de diversas fontes:</p>



<ul class="wp-block-list">
<li><strong>Logs e métricas</strong> (via Prometheus, Grafana, Loki, etc.);</li>



<li><strong>Alertas de monitoramento</strong> (ex: erros 500, lentidão, uso excessivo de CPU);</li>



<li><strong>Feedback dos usuários</strong> via canais de suporte, UX, redes sociais;</li>



<li><strong>Relatórios de CI/CD</strong>, como testes quebrando após merge;</li>



<li><strong>Acompanhamento de deploys e rollback</strong>.</li>
</ul>



<h3 class="wp-block-heading">Como utilizar o feedback de forma eficaz</h3>



<ol class="wp-block-list">
<li><strong>Automatize a coleta e exibição</strong>: dashboards claros, alertas inteligentes e integração com canais como Slack ou e-mail ajudam a manter o time informado.</li>



<li><strong>Integre o feedback à cultura da equipe</strong>: reuniões rápidas (como daily meetings) podem incluir uma visão rápida dos indicadores e eventos recentes.</li>



<li><strong>Aja rapidamente sobre os dados recebidos</strong>: não basta coletar — o mais importante é <strong>agir</strong> com base no que se aprende. Se uma feature nova aumentou o tempo de resposta, revise. Se um bug surgiu após um deploy, resolva e documente.</li>



<li><strong>Itere com base em dados, não suposições</strong>: DevOps é sobre melhoria contínua. Métricas reais substituem achismos e ajudam a tomar decisões mais sólidas.</li>
</ol>



<h3 class="wp-block-heading">Ferramentas que auxiliam o feedback contínuo</h3>



<ul class="wp-block-list">
<li><strong>Grafana</strong>: dashboards de métricas e alertas.</li>



<li><strong>Elastic/Kibana ou Loki</strong>: visualização e análise de logs.</li>



<li><strong>Sentry</strong>: rastreamento de exceções e falhas front-end/back-end.</li>



<li><strong>Google Analytics / Matomo</strong>: comportamento de usuários.</li>



<li><strong>GitHub Issues / Jira</strong>: rastreamento de feedback de usuários e bugs.</li>
</ul>



<h2 class="wp-block-heading">Conclusão do Tutorial</h2>



<p class="wp-block-paragraph">Com este ciclo completo — planejamento, desenvolvimento, integração, entrega, operação, monitoramento e feedback — você experimentou a essência do DevOps. Mais do que uma lista de ferramentas ou práticas, DevOps é uma <strong>cultura de colaboração e melhoria contínua</strong>, que ajuda organizações a entregarem <strong>mais valor com mais velocidade e menos riscos</strong>.</p>



<p class="wp-block-paragraph">Ao longo do tutorial, você:</p>



<ul class="wp-block-list">
<li>Criou uma aplicação Python e preparou seu ambiente;</li>



<li>Empacotou a aplicação com Docker;</li>



<li>Automatizou os testes e o build com CI;</li>



<li>Realizou o deploy com práticas de CD;</li>



<li>Monitorou a aplicação em produção;</li>



<li>E finalmente, fechou o ciclo com feedback contínuo.</li>
</ul>



<p class="wp-block-paragraph">Este é apenas o começo. A partir daqui, você pode explorar temas como:</p>



<ul class="wp-block-list">
<li>Orquestração com Kubernetes;</li>



<li>Pipelines avançadas de CI/CD com GitLab ou Jenkins;</li>



<li>Segurança DevSecOps;</li>



<li>Observabilidade com OpenTelemetry;</li>



<li>e muito mais.</li>
</ul>



<ul class="wp-block-list">
<li></li>
</ul>



<h2 class="wp-block-heading">Repositórios da Alura para este Tutorial:</h2>



<ul class="wp-block-list">
<li>https://github.com/guilhermeonrails/ellis</li>



<li>https://github.com/guilhermeonrails/refactored-octo-chainsaw</li>
</ul><p>The post <a href="https://mcu.tec.br/infraestrutura/tutorial-completo-de-cloud-devops-com-docker-ci-cd-e-monitoramento-parte-1/">Tutorial Completo de Cloud DevOps com Docker, CI/CD e Monitoramento – Parte 1</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">560</post-id>	</item>
	</channel>
</rss>
