<?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>devops Archives - Leonardo Nascimento | Engenheiro de Software</title>
	<atom:link href="https://leonardonascimento.dev/tag/devops/feed/" rel="self" type="application/rss+xml" />
	<link>https://leonardonascimento.dev/tag/devops/</link>
	<description>Especializado em backend, APIs e sistemas escaláveis. Experiência em arquitetura de sistemas, integrações, mensageria, performance e aplicações de alta disponibilidade.</description>
	<lastBuildDate>Thu, 22 Jan 2026 16:05:49 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://leonardonascimento.dev/wp-content/uploads/2021/05/cropped-programming-32x32.png</url>
	<title>devops Archives - Leonardo Nascimento | Engenheiro de Software</title>
	<link>https://leonardonascimento.dev/tag/devops/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Como instalar Docker, Portainer e Evolution API</title>
		<link>https://leonardonascimento.dev/blog/como-instalar-docker-portainer-e-evolution-api/</link>
					<comments>https://leonardonascimento.dev/blog/como-instalar-docker-portainer-e-evolution-api/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 20:15:00 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Infra]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[evolution api]]></category>
		<category><![CDATA[portainer]]></category>
		<category><![CDATA[traefik]]></category>
		<category><![CDATA[vps]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2304</guid>

					<description><![CDATA[<p>Este guia mostra como subir um ambiente completo com Docker, Portainer e Evolution API, utilizando o Orion Design (interface padrão da Evolution), de forma organizada e fácil de manter. A ideia é ter: Pré-requisitos que evitam dor de cabeça Passo a passo: instalar Docker + Traefik + Portainer + Evolution API via SetupOrion 1) Prepare [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/como-instalar-docker-portainer-e-evolution-api/">Como instalar Docker, Portainer e Evolution API</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Este guia mostra como subir um ambiente completo com <strong>Docker</strong>, <strong>Portainer</strong> e <strong>Evolution API</strong>, utilizando o <strong>Orion Design</strong> (interface padrão da Evolution), de forma organizada e fácil de manter.</p>



<p>A ideia é ter:</p>



<ul class="wp-block-list">
<li>containers gerenciáveis via Portainer</li>



<li>stack versionável via Docker Compose</li>



<li>Evolution API pronta para uso em produção</li>
</ul>



<h2 class="wp-block-heading" id="h-pre-requisitos-que-evitam-dor-de-cabeca">Pré-requisitos que evitam dor de cabeça</h2>



<ol class="wp-block-list">
<li><strong>Servidor limpo (zerado)</strong><br>O SetupOrion verifica se já existe painel/stack instalada e vai falhar se o servidor não estiver “limpo”.</li>



<li><strong>Domínio e DNS</strong><br>A recomendação do guia é criar um subdomínio base (ex.: <code>vps.seudominio.com</code>) apontando para o IP do servidor e, a partir dele, criar CNAMEs para as apps (portainer, api etc.).</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-passo-a-passo-instalar-docker-traefik-portainer-evolution-api-via-setuporion">Passo a passo: instalar Docker + Traefik + Portainer + Evolution API via SetupOrion</h2>



<h3 class="wp-block-heading" id="h-1-prepare-o-dns-antes-de-rodar-o-instalador">1) Prepare o DNS (antes de rodar o instalador)</h3>



<p>Crie o registro base:</p>



<ul class="wp-block-list">
<li><strong>A</strong>: <code>vps.seudominio.com</code> → IP do seu servidor (proxy desligado, se usar Cloudflare)</li>
</ul>



<p>Depois, crie os CNAMEs que você vai usar:</p>



<ul class="wp-block-list">
<li><strong>CNAME</strong>: <code>portainer</code> → <code>vps.seudominio.com</code> (proxy desligado)</li>



<li><strong>CNAME</strong>: <code>api</code> → <code>vps.seudominio.com</code> (proxy desligado)</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Se você não quiser usar <code>vps.seudominio.com</code>, pode apontar o CNAME direto para o IP, mas o modelo do “vps base” facilita troca de IP depois.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-2-conecte-via-ssh">2) Conecte via SSH</h3>



<p>Exemplo:</p>



<pre class="wp-block-code"><code>ssh root@SEU-IP
</code></pre>



<p>(ou <code>ssh root@vps.seudominio.com</code>)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-3-rode-o-setuporion-um-comando">3) Rode o SetupOrion (um comando)</h3>



<pre class="wp-block-code"><code>bash &lt;(curl -sSL setup.oriondesign.art.br)
</code></pre>



<p>Isso abre o menu do SetupOrion.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-4-instale-traefik-portainer-primeiro">4) Instale Traefik + Portainer (primeiro)</h3>



<p>No menu, a recomendação é começar pela opção de base <strong>Traefik + Portainer</strong> (no guia aparece como a “primeira instalação obrigatória”).</p>



<p>Durante o processo ele vai pedir:</p>



<ul class="wp-block-list">
<li>hostname do Portainer (ex.: <code>portainer.seudominio.com</code>)</li>



<li>usuário e senha (o guia menciona evitar caracteres problemáticos e usar credenciais seguras)</li>



<li>e-mail (usado para SSL/certificados)</li>
</ul>



<p>Ao final, você acessa o Portainer em:</p>



<ul class="wp-block-list">
<li><code>https://portainer.seudominio.com</code></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-5-instale-a-evolution-api-pelo-proprio-menu-do-setuporion">5) Instale a Evolution API pelo próprio menu do SetupOrion</h3>



<p>Com o SetupOrion aberto, selecione a Evolution API.</p>



<ul class="wp-block-list">
<li><strong>“03 – Evolution API”</strong> → digite <code>03</code></li>
</ul>



<p>Depois ele vai pedir o domínio da Evolution API:</p>



<ul class="wp-block-list">
<li>informe: <code>api.seudominio.com</code> (garanta que o CNAME <code>api</code> já existe)</li>
</ul>



<p>Ao final ele exibe algo como:</p>



<ul class="wp-block-list">
<li><code>Server URL: https://api.seudominio.com</code></li>



<li><code>Global API Key: ...</code> (salve isso)</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-6-acesse-o-manager-da-evolution-api-orion-gerenciador">6) Acesse o “manager” da Evolution API (Orion/gerenciador)</h3>



<p>A URL indicada no guia:</p>



<ul class="wp-block-list">
<li><code>https://api.seudominio.com/manager</code></li>
</ul>



<p>Você entra com:</p>



<ul class="wp-block-list">
<li><strong>Server URL</strong> = <code>https://api.seudominio.com</code></li>



<li><strong>Global API Key</strong> = a chave exibida ao final da instalação</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="h-7-verifique-no-portainer-se-esta-tudo-rodando">7) Verifique no Portainer se está tudo rodando</h3>



<p>No Portainer:</p>



<ul class="wp-block-list">
<li><strong>Stacks</strong> → encontre a stack da Evolution API → status “Running”</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-o-que-esse-metodo-te-entrega-sem-gambiarra">O que esse método te entrega (sem gambiarra)</h2>



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



<li>Traefik pronto (rotas + SSL)</li>



<li>Portainer pronto (gestão)</li>



<li>Evolution API instalada e acessível por domínio<br>Tudo via menu, no padrão do SetupOrion.</li>
</ul>
<p>The post <a href="https://leonardonascimento.dev/blog/como-instalar-docker-portainer-e-evolution-api/">Como instalar Docker, Portainer e Evolution API</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/como-instalar-docker-portainer-e-evolution-api/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</title>
		<link>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/</link>
					<comments>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 15:26:32 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[Produção]]></category>
		<category><![CDATA[ci/cd]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[produção]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2295</guid>

					<description><![CDATA[<p>Deploy manual funciona até o dia em que deixa de funcionar. Enquanto o projeto é pequeno e o time é reduzido, subir código via SSH, rodar alguns comandos e torcer para dar certo parece aceitável. Em projetos reais, com mais gente mexendo, deploy frequente e produção rodando 24/7, isso vira risco operacional. CI/CD não é [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/">Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Deploy manual funciona até o dia em que deixa de funcionar. Enquanto o projeto é pequeno e o time é reduzido, subir código via SSH, rodar alguns comandos e torcer para dar certo parece aceitável. Em projetos reais, com mais gente mexendo, deploy frequente e produção rodando 24/7, isso vira risco operacional.</p>



<p>CI/CD não é sobre velocidade. É sobre <strong>previsibilidade, repetibilidade e segurança</strong> no processo de entrega.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-o-que-ci-cd-realmente-resolve-em-projetos-laravel">O que CI/CD realmente resolve em projetos Laravel</h2>



<p>Em aplicações Laravel, o pipeline de deploy resolve três problemas clássicos:</p>



<ol class="wp-block-list">
<li><strong>Ambiente inconsistente</strong><br>O código roda local, mas quebra em produção porque algo foi esquecido ou executado fora de ordem.</li>



<li><strong>Deploys inseguros</strong><br>Código sobe sem testes, sem validação, sem rollback fácil.</li>



<li><strong>Processo dependente de pessoas</strong><br>“Só fulano sabe fazer deploy”. Quando ele não está, ninguém sobe nada.</li>
</ol>



<p>CI/CD elimina esses pontos ao transformar deploy em <strong>processo automatizado</strong>, não em ritual manual.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-conceito-basico-do-pipeline-independente-da-ferramenta">Conceito básico do pipeline (independente da ferramenta)</h2>



<p>Antes de falar de GitHub Actions ou GitLab CI, é importante entender o fluxo lógico. Um pipeline de Laravel bem definido costuma ter estas etapas:</p>



<ol class="wp-block-list">
<li><strong>Checkout do código</strong></li>



<li><strong>Instalação de dependências</strong></li>



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



<li><strong>Build (quando aplicável)</strong></li>



<li><strong>Deploy</strong></li>



<li><strong>Pós-deploy (migrations, cache, filas)</strong></li>
</ol>



<p>Se qualquer etapa falhar, o deploy <strong>não acontece</strong>. Isso é uma proteção, não um obstáculo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-estrutura-minima-de-um-deploy-laravel-saudavel">Estrutura mínima de um deploy Laravel saudável</h2>



<p>Independente de cloud ou CI, alguns princípios não mudam:</p>



<ul class="wp-block-list">
<li><code>composer install</code> sempre em modo produção</li>



<li><code>.env</code> nunca versionado</li>



<li><code>APP_ENV</code> e <code>APP_DEBUG</code> corretos</li>



<li>migrations rodando de forma controlada</li>



<li>cache/config/views limpos e recompilados</li>



<li>workers reiniciados corretamente</li>
</ul>



<p>Se isso não estiver automatizado, o risco é constante.</p>



<h2 class="wp-block-heading">Exemplo de pipeline com GitHub Actions</h2>



<p>Um pipeline simples, mas funcional, usando GitHub Actions:</p>



<pre class="wp-block-preformatted">name: Deploy Laravel<br><br>on:<br>  push:<br>    branches:<br>      - main<br><br>jobs:<br>  deploy:<br>    runs-on: ubuntu-latest<br><br>    steps:<br>      - name: Checkout<br>        uses: actions/checkout@v4<br><br>      - name: Setup PHP<br>        uses: shivammathur/setup-php@v2<br>        with:<br>          php-version: '8.2'<br>          extensions: mbstring, pdo, pdo_mysql<br><br>      - name: Install dependencies<br>        run: composer install --no-dev --optimize-autoloader<br><br>      - name: Run tests<br>        run: php artisan test<br><br>      - name: Deploy via SSH<br>        uses: appleboy/ssh-action@v1<br>        with:<br>          host: ${{ secrets.SERVER_HOST }}<br>          username: ${{ secrets.SERVER_USER }}<br>          key: ${{ secrets.SERVER_SSH_KEY }}<br>          script: |<br>            cd /var/www/app<br>            git pull origin main<br>            composer install --no-dev --optimize-autoloader<br>            php artisan migrate --force<br>            php artisan optimize<br>            php artisan queue:restart</pre>



<h2 class="wp-block-heading">Onde muita gente erra no deploy de Laravel</h2>



<h3 class="wp-block-heading">Rodar migration sem pensar em impacto</h3>



<p>Migration em produção pode travar tabela, gerar lentidão ou indisponibilidade. CI/CD não elimina isso. Ele apenas automatiza. Migration precisa ser escrita com consciência de produção.</p>



<h3 class="wp-block-heading">Cache mal tratado</h3>



<p>Não limpar/recriar cache de config e routes gera bugs difíceis de explicar. Cache antigo em produção é clássico.</p>



<h3 class="wp-block-heading">Workers esquecidos</h3>



<p>Deploy sobe código novo, mas workers continuam rodando código antigo. Resultado: comportamento inconsistente.</p>



<h3 class="wp-block-heading">Falta de rollback</h3>



<p>CI/CD sem rollback é metade da solução. Mesmo que seja manual, precisa existir um caminho claro para voltar.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Estratégia simples de rollback</h2>



<p>Mesmo sem blue/green ou canary, dá para ter rollback básico:</p>



<ul class="wp-block-list">
<li>manter tags ou releases</li>



<li>usar <code>git checkout</code> para versão anterior</li>



<li>rodar <code>php artisan migrate:rollback</code> quando aplicável</li>



<li>reiniciar workers</li>
</ul>



<p>O importante é <strong>ter plano</strong>. Não improvisar sob pressão.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">CI/CD não substitui observabilidade</h2>



<p>Deploy automatizado reduz erro humano, mas não impede bugs. Por isso, CI/CD precisa andar junto com:</p>



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



<li>alertas pós-deploy</li>



<li>logs estruturados</li>



<li>métricas de saúde</li>
</ul>



<p>Deploy sem visibilidade é só um erro mais rápido.</p>



<p>CI/CD em projetos Laravel não é luxo nem modinha. É uma camada básica de segurança operacional. Ele garante que o código passe sempre pelo mesmo caminho, reduz risco humano e cria previsibilidade no processo de entrega.</p>



<p>Quando o deploy deixa de ser um evento tenso e vira algo rotineiro, o time ganha confiança para evoluir o sistema. E isso, no fim, é o que permite crescer sem quebrar tudo a cada release.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/">Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
