<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matheus Fernandes Rodrigues</title>
    <description>The latest articles on DEV Community by Matheus Fernandes Rodrigues (@fernandeess).</description>
    <link>https://dev.to/fernandeess</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2603413%2F7d474078-f639-40ea-ad2e-c8f5fcfa6c51.jpeg</url>
      <title>DEV Community: Matheus Fernandes Rodrigues</title>
      <link>https://dev.to/fernandeess</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernandeess"/>
    <language>en</language>
    <item>
      <title>Guia de sobrevivencia ao Docker</title>
      <dc:creator>Matheus Fernandes Rodrigues</dc:creator>
      <pubDate>Thu, 02 Apr 2026 18:21:02 +0000</pubDate>
      <link>https://dev.to/fernandeess/guia-de-sobrevivencia-ao-docker-2m60</link>
      <guid>https://dev.to/fernandeess/guia-de-sobrevivencia-ao-docker-2m60</guid>
      <description>&lt;p&gt;\Um guia prático e direto com os comandos essenciais do Docker para facilitar o seu dia a dia no desenvolvimento.&lt;/p&gt;




&lt;h2&gt;
  
  
  Guia de Sobrevivência Docker
&lt;/h2&gt;

&lt;p&gt;Se você já falou…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"na minha máquina funciona"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então você já sentiu o problema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker resolve isso.  
&lt;/h2&gt;

&lt;p&gt;Esse guia é simples:&lt;br&gt;&lt;br&gt;
Só o que importa.&lt;br&gt;&lt;br&gt;
Só o que você realmente usa.&lt;/p&gt;

&lt;p&gt;Seu bote salva-vidas no caos do Docker.&lt;/p&gt;


&lt;h2&gt;
  
  
  📦 1. O Coração: Imagens
&lt;/h2&gt;

&lt;p&gt;Imagem é o molde.&lt;br&gt;&lt;br&gt;
É de onde tudo nasce.&lt;br&gt;&lt;br&gt;
Sem imagem… não existe container.&lt;/p&gt;
&lt;h3&gt;
  
  
  O que você precisa saber:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Baixa uma imagem pronta&lt;/span&gt;
docker pull &amp;lt;imagem&amp;gt;

&lt;span class="c"&gt;# Lista o que você já tem&lt;/span&gt;
docker images

&lt;span class="c"&gt;# Remove imagem (libera espaço)&lt;/span&gt;
docker rmi &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# Cria sua própria imagem&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; meu-app:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Se você entendeu isso…&lt;br&gt;&lt;br&gt;
já saiu na frente de muita gente.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 2. O Motor: Containers
&lt;/h2&gt;

&lt;p&gt;Container é a imagem rodando.&lt;br&gt;&lt;br&gt;
É onde sua aplicação vive.&lt;/p&gt;
&lt;h3&gt;
  
  
  Rodando o básico
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Abre um terminal dentro do container&lt;/span&gt;
docker run &lt;span class="nt"&gt;-it&lt;/span&gt; ubuntu /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Isso aqui é pra testar, explorar, aprender.&lt;/p&gt;
&lt;h3&gt;
  
  
  O que você vai usar de verdade
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Roda em segundo plano + mapeia porta&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; meu-servidor nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Tradução:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seu PC → porta 8080&lt;/li&gt;
&lt;li&gt;Container → porta 80&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Gestão do dia a dia
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Containers rodando&lt;/span&gt;
docker ps

&lt;span class="c"&gt;# Todos (inclusive parados)&lt;/span&gt;
docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;

&lt;span class="c"&gt;# Para um container&lt;/span&gt;
docker stop &amp;lt;nome&amp;gt;

&lt;span class="c"&gt;# Remove&lt;/span&gt;
docker &lt;span class="nb"&gt;rm&lt;/span&gt; &amp;lt;nome&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Simples.&lt;br&gt;&lt;br&gt;
Sem segredo.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ 3. Debugging (modo detetive)
&lt;/h2&gt;

&lt;p&gt;Deu problema?&lt;br&gt;&lt;br&gt;
Agora você investiga.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Logs em tempo real&lt;/span&gt;
docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;nome&amp;gt;

&lt;span class="c"&gt;# Entra no container&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;nome&amp;gt; sh

&lt;span class="c"&gt;# Detalhes completos&lt;/span&gt;
docker inspect &amp;lt;nome&amp;gt;

&lt;span class="c"&gt;# Consumo de recursos&lt;/span&gt;
docker stats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você dominar isso…&lt;br&gt;&lt;br&gt;
você para de “achar” e começa a entender.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 4. Faxina de Emergência
&lt;/h2&gt;

&lt;p&gt;Docker suja sua máquina.&lt;br&gt;&lt;br&gt;
E rápido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limpeza padrão
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker system prune
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;containers parados&lt;/li&gt;
&lt;li&gt;redes inúteis&lt;/li&gt;
&lt;li&gt;cache&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limpeza pesada
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker system prune &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--volumes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso aqui é sem dó.&lt;br&gt;&lt;br&gt;
Use com consciência.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devops</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Como realizar o Deploy de Projetos Web em uma VPS</title>
      <dc:creator>Matheus Fernandes Rodrigues</dc:creator>
      <pubDate>Mon, 06 Jan 2025 22:28:54 +0000</pubDate>
      <link>https://dev.to/fernandeess/como-realizar-o-deploy-de-projetos-web-em-uma-vps-2jhm</link>
      <guid>https://dev.to/fernandeess/como-realizar-o-deploy-de-projetos-web-em-uma-vps-2jhm</guid>
      <description>&lt;p&gt;Escolhi utilizar uma VPS para o deploy do meu portfólio pelo excelente custo-benefício e controle de gastos. Essa solução permite testar configurações em um ambiente controlado, simulando cenários reais de forma prática e sem surpresas financeiras. Baseei-me no vídeo do canal &lt;a href="https://youtu.be/F-9KWQByeU0?feature=shared" rel="noopener noreferrer"&gt;Dreams of Code&lt;/a&gt;, que explica de forma clara como configurar uma VPS.&lt;/p&gt;

&lt;p&gt;A seguir, descrevo o passo a passo que segui para configurar minha VPS e que você também poderá seguir para subir o seu projeto&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yncjif13zcrkwa11e3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1yncjif13zcrkwa11e3.png" alt="cloud-architecture" width="671" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Contrate um serviço de VPS para adquirir seu servidor dedicado.
&lt;/h2&gt;

&lt;p&gt;Existem várias opções disponíveis, mas no meu caso, optei pelo serviço da Contabo por apenas 5 dólares mensais, oferecendo 4 núcleos  de CPU, 6 GB de RAM, 400 GB de armazenamento SSD, 200 Mbit/s de velocidade de rede e 32 TB de tráfego mensal (com entrada ilimitada), &lt;br&gt;
rodando o Ubuntu Server 22.04.5 LTS&lt;/p&gt;

&lt;p&gt;Realize o primeiro acesso ao servidor utilizando o protocolo SSH com o seguinte comando no terminal, utilizando o IP da máquina contratada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;ssh root@&amp;lt;IP-do-servidor&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encontre o IP da sua máquina para configurar o DNS utilizando o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;ip addr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure o DNS no serviço onde o domínio foi adquirido. Consulte a documentação oficial do provedor para orientações detalhadas sobre como realizar essa configuração.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Atualize os pacotes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Criando um Novo Usuário
&lt;/h2&gt;

&lt;p&gt;Trabalhar diretamente com o usuário root pode expor seu servidor a riscos desnecessários, a melhor pratica e criar um novo usurário com  privilégios limitados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Concedendo permissões de sudo
&lt;/h2&gt;

&lt;p&gt;Após a criação do usuário devemos adiciona-lo ao sudo group para que ele possa realizar comandos que exigem privilégios de nível elevado, sem a necessidade de utilizar diretamente o usuário root&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos  trocar para o novo usuário para darmos inicio a configuração do sistema&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Removendo autenticação por senha do SSH
&lt;/h2&gt;

&lt;p&gt;Para aumentar a segurança da conexão SSH, é recomendável desativar a autenticação por senha, isso elimina o risco de ataques de brute force baseado em senha. &lt;/p&gt;

&lt;p&gt;Antes de desativarmos a autenticação de senha para o SSH, devemos criar um par de chaves SSH para garantir que ainda poderemos acessar o servidor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"useremail@email.com"&lt;/span&gt;
&lt;span class="c"&gt;## -t ed25519: Especifica o tipo da chave a ser gerada. &lt;/span&gt;
&lt;span class="c"&gt;## -C "seuemail@exemplo.com: Adiciona um comentário à chave Durante a execução do comando, você deverá escolher o local onde deseja salvar a chave ou optar pelo local padrão: `~/.ssh/chave`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a criação da chave devemos adicionar a chave SSH ao servidor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/sshkey.pub newuser@serverip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;indica o caminho onde a sua chave esta localizado localmente -i ~/.ssh/sshkey.pub&lt;/li&gt;
&lt;li&gt;Esse comando copia a chave pública SSH para o arquivo &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; no servidor remoto, permitindo o acesso para o usuário com a chave criada&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora tente acessar o servidor utilizado a chave SSH privada localizada no mesmo diretório da chave publica&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-p&lt;/span&gt; 22 &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/sshkey newuser@serverip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;-p especifica a porta SSH definida no servidor&lt;/li&gt;
&lt;li&gt;-i ~/.ssh/sshkey especifica o caminho da chave privada&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se acesso utilizando a chave SSH der certo podemos remover a autenticação por senha do SSH.&lt;/p&gt;

&lt;p&gt;Primeiro abra o arquivo de configuração SSH&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Localize e altere as seguintes linhas no arquivo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## HARDENING SSH CONECTION&lt;/span&gt;
PermitRootLogin no &lt;span class="c"&gt;## BLOQUEIA O LOGIN DIRETO COM ROOT&lt;/span&gt;
PasswordAuthentication no &lt;span class="c"&gt;## DESATIVA CONEXÃO POR SENHA&lt;/span&gt;
UsePAM no &lt;span class="c"&gt;## DESATIVA O USO DE PAM NO SSH &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;após alterar essas linhas salve e feche o arquivo de configuração e reinicie o serviço de SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;para validar se as alterações estão funcionando tente se conectar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@serverip &lt;span class="c"&gt;# a resposta deve ser essa root@serverip Permission denied (publickey).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conecte-se ao novo usuário utilizando o SSH.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Instale o docker e docker-compose
&lt;/h2&gt;

&lt;p&gt;Para configurar o ambiente, prossiga com a instalação do Docker e do Docker Compose seguindo a documentação oficial:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/ubuntu/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/install/linux/" rel="noopener noreferrer"&gt;https://docs.docker.com/compose/install/linux/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após instalar o Docker, execute esta imagem para verificar se ele está funcionando corretamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;-d&lt;/span&gt; nginxdemos/hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1ub9z9ptc1pozom625x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1ub9z9ptc1pozom625x.png" alt="Image description" width="800" height="403"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;docker 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adiciona o serviço docker à lista de serviços que são iniciados automaticamente na inicialização do sistema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adiciona o usuário newuser ao grupo docker, concedendo permissões para que ele possa executar comandos com o Docker sem a necessidade de utilizar sudo&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Configurar Firewall
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bloqueia todas as conexões de entrada por padrão para maior segurança&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permite todas as conexões de saída por padrão para permitir o tráfego de saída.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permite conexões SSH (porta 22) para acesso remoto seguro ao servidor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permite conexões HTTP (porta 80) para acesso web não criptografado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permite conexões HTTPS (porta 443) para acesso web seguro e criptografado.&lt;/p&gt;

&lt;p&gt;Para que o Docker respeite as regras do UFW, edite o arquivo de configuração do Docker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/docker/daemon.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"iptables"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reinicie o docker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Configuração do Docker file para o Projeto
&lt;/h2&gt;

&lt;p&gt;Crie o arquivo &lt;strong&gt;Dockerfile&lt;/strong&gt; na raiz do seu projeto para a criação da imagem docker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stage 1: Construção da aplicação usando Node.js&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# Define o diretório de trabalho dentro do container para organizar os arquivos&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copia os arquivos de configuração do Node.js (package.json e package-lock.json) para o container&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# Instala as dependências do projeto&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Copia o restante dos arquivos do projeto para o container&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Executa o comando para construir a aplicação (adapte este comando conforme o projeto)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="c"&gt;# Stage 2: Configuração do servidor Nginx para servir a aplicação&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;

&lt;span class="c"&gt;# Define o diretório de trabalho do Nginx onde os arquivos estáticos serão armazenados&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/share/nginx/html&lt;/span&gt;

&lt;span class="c"&gt;# Copia os arquivos da build gerada no estágio anterior para o diretório do Nginx&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/dist/codebyfernandes/browser .&lt;/span&gt;

&lt;span class="c"&gt;# Copia o arquivo de configuração personalizado do Nginx (opcional, se necessário)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; default.conf /etc/nginx/conf.d/default.conf&lt;/span&gt;

&lt;span class="c"&gt;# Expõe a porta 80 para o servidor&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 80&lt;/span&gt;

&lt;span class="c"&gt;# Define o comando padrão para iniciar o Nginx&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["nginx", "-g", "daemon off;"]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crie o arquivo default.conf na raiz do projeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
    listen 80&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Porta onde o servidor vai escutar&lt;/span&gt;
    server_name localhost&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Nome do servidor (pode ser substituído pelo domínio)&lt;/span&gt;
    root /usr/share/nginx/html&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Diretório onde estão os arquivos da aplicação&lt;/span&gt;
    index index.html&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Arquivo principal da aplicação&lt;/span&gt;

    &lt;span class="c"&gt;# Rota principal para servir o Angular&lt;/span&gt;
    location / &lt;span class="o"&gt;{&lt;/span&gt;
        try_files &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;/ /index.html&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Redireciona todas as rotas para o index.html&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;# Configuração de cache para arquivos estáticos&lt;/span&gt;
    location ~&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|webmanifest&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
        expires 6M&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Define o tempo de expiração para 6 meses&lt;/span&gt;
        access_log off&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Desativa logs para esses arquivos&lt;/span&gt;
        add_header Cache-Control &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Permite cache público&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    error_page 404 /index.html&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Redireciona erros 404 para o index.html&lt;/span&gt;

    &lt;span class="c"&gt;# Logs personalizados&lt;/span&gt;
    error_log /var/log/nginx/angular-error.log&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Registro de erros&lt;/span&gt;
    access_log /var/log/nginx/angular-access.log&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# Registro de acessos&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora crie a imagem localmente e rode ela em seguida&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; meu-app:1.0 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;-d&lt;/span&gt; meu-app:1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;d&lt;/code&gt;&lt;/strong&gt; : Executa o container em segundo plano.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;p 80:80&lt;/code&gt;&lt;/strong&gt;: Mapeia a porta 80 do container para a porta 80 do host.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se tudo estiver configurado corretamente, você poderá acessar seu projeto em: &lt;a href="http://localhost/" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora envie sua imagem para o Docker Hub: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/get-started/introduction/build-and-push-first-image/" rel="noopener noreferrer"&gt;Docker Hub: Build and Push First Image&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Configuração do docker compose
&lt;/h2&gt;

&lt;p&gt;Crie o arquivo compose.yaml na raiz do seu projeto.&lt;/p&gt;

&lt;p&gt;Primeiro vamos adicionar a imagem do seu web app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Define os serviços do projeto&lt;/span&gt;
  &lt;span class="na"&gt;webapp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="c1"&gt;# Nome do serviço&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fernandeeess/portfolio-app:prod&lt;/span&gt;
    &lt;span class="c1"&gt;# Imagem do contêiner usada para o serviço (versão de produção)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos configurar o reverse proxy para o seu projeto utilizando o &lt;strong&gt;Traefik&lt;/strong&gt;, que simplifica a gestão ao configurar automaticamente o certificado SSL e ajustar o load balancer de acordo com os serviços criados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;reverse-proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Define o serviço do reverse proxy&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traefik:v3.1&lt;/span&gt;
    &lt;span class="c1"&gt;# Especifica a imagem do Traefik que será usada&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Ativa o provedor Docker&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--providers.docker"&lt;/span&gt;
      &lt;span class="c1"&gt;# Desativa a exposição automática de serviços no Traefik&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--providers.docker.exposedbydefault=false"&lt;/span&gt;
      &lt;span class="c1"&gt;# Configura a porta para HTTPS (websecure)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entryPoints.websecure.address=:443"&lt;/span&gt;
      &lt;span class="c1"&gt;# Configura o desafio TLS para emissão do certificado SSL&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.tlschallenge=true"&lt;/span&gt;
      &lt;span class="c1"&gt;# Define o e-mail para registrar os certificados SSL&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.email=youremail"&lt;/span&gt;
      &lt;span class="c1"&gt;# Define o local para armazenar os certificados SSL&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"&lt;/span&gt;
      &lt;span class="c1"&gt;# Configura a porta para HTTP (web)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.address=:80"&lt;/span&gt;
      &lt;span class="c1"&gt;# Redireciona HTTP para HTTPS&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.http.redirections.entrypoint.to=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.http.redirections.entrypoint.scheme=https"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Mapeia as portas do host para o contêiner (HTTP e HTTPS)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Volume para armazenar certificados SSL&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;letsencrypt:/letsencrypt&lt;/span&gt;
      &lt;span class="c1"&gt;# Permite que o Traefik se comunique com o Docker para detectar serviços&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;

  &lt;span class="na"&gt;webapp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Define o serviço da aplicação web&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fernandeeess/portfolio-app:prod&lt;/span&gt;
    &lt;span class="c1"&gt;# Especifica a imagem do contêiner da aplicação&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;letsencrypt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Volume para armazenar os dados do Let's Encrypt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicione as labels ao web app service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;webapp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Define o serviço da aplicação web&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fernandeeess/portfolio-app:prod&lt;/span&gt;
    &lt;span class="c1"&gt;# Especifica a imagem do contêiner que será usada para o serviço&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Habilita o Traefik para este serviço&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.enable=true"&lt;/span&gt;
      &lt;span class="c1"&gt;# Define a regra de roteamento baseada no domínio&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.rule=Host(`yourdomain.com`)"&lt;/span&gt;
      &lt;span class="c1"&gt;# Define o entrypoint como HTTPS (websecure)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.entrypoints=websecure"&lt;/span&gt;
      &lt;span class="c1"&gt;# Configura o resolver de certificado SSL a ser usado&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.tls.certresolver=myresolver"&lt;/span&gt;
      &lt;span class="c1"&gt;# Define a porta interna do contêiner que será usada pelo load balancer&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.webapp.loadbalancer.server.port=80"&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Configuração de implantação do serviço&lt;/span&gt;
      &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replicated&lt;/span&gt;
      &lt;span class="c1"&gt;# Define o número de réplicas (instâncias) do serviço&lt;/span&gt;
      &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure o serviço do Watchtower para monitorar a imagem Docker com a tag &lt;code&gt;prod&lt;/code&gt;. Sempre que houver uma atualização, o Watchtower irá puxar as alterações e reiniciar os serviços automaticamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# Continuous Delivery/Deployment&lt;/span&gt;
&lt;span class="na"&gt;watchtower&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containrrr/watchtower&lt;/span&gt;  &lt;span class="c1"&gt;# Imagem do Watchtower.&lt;/span&gt;
  &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--label-enable"&lt;/span&gt;        &lt;span class="c1"&gt;# Monitora apenas serviços com labels específicas.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--interval"&lt;/span&gt;            &lt;span class="c1"&gt;# Define o intervalo de verificação.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30"&lt;/span&gt;                    &lt;span class="c1"&gt;# Verifica atualizações a cada 30 segundos.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--rolling-restart"&lt;/span&gt;     &lt;span class="c1"&gt;# Reinicia os serviços de forma gradual.&lt;/span&gt;
  &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;  &lt;span class="c1"&gt;# Permite ao Watchtower gerenciar containers.&lt;/span&gt;

&lt;span class="c1"&gt;# Adicione esta label ao serviço "webapp" para que o Watchtower o monitore:&lt;/span&gt;
&lt;span class="c1"&gt;# - "com.centurylinklabs.watchtower.enable=true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O arquivo final deve ficar assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;watchtower&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containrrr/watchtower&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--label-enable"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--interval"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--rolling-restart"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
  &lt;span class="na"&gt;reverse-proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traefik:v3.1&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--providers.docker"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--providers.docker.exposedbydefault=false"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entryPoints.websecure.address=:443"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.tlschallenge=true"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.email=email@email.com"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.address=:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.http.redirections.entrypoint.to=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--entrypoints.web.http.redirections.entrypoint.scheme=https"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;letsencrypt:/letsencrypt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;

  &lt;span class="na"&gt;webapp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fernandeeess/portfolio-app:prod&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.enable=true"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.rule=Host(`yourdomain.com`)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.entrypoints=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.webapp.tls.certresolver=myresolver"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.webapp.loadbalancer.server.port=80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;com.centurylinklabs.watchtower.enable=true"&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;replicated&lt;/span&gt;
      &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;letsencrypt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tudo estiver configurado corretamente, você poderá acessar seu projeto no seu domínio configurado&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Configure o CI utilizando o GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Automatize o processo de construção da imagem Docker e envio ao Docker Hub. Siga o tutorial disponível no link abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ken_mwaura1/automate-docker-image-builds-and-push-to-docker-hub-using-github-actions-32g5"&gt;Automate Docker Image Builds and Push to Docker Hub Using GitHub Actions&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Lembre-se de que a imagem deve estar com a tag "prod" para que o Watchtower possa puxar as alterações e reiniciar os serviços.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Portfolio

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Fernandeess/codebyfernandes" rel="noopener noreferrer"&gt;https://github.com/Fernandeess/codebyfernandes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codebyfernandes.tech/" rel="noopener noreferrer"&gt;https://codebyfernandes.tech/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Instalação e Configuração do Docker&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Como instalar o Docker no Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/install/linux/" rel="noopener noreferrer"&gt;Como instalar o Docker Compose no Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Documentação e Conceitos do Docker&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/reference/compose-file/" rel="noopener noreferrer"&gt;Documentação Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/build/concepts/dockerfile/" rel="noopener noreferrer"&gt;Documentação do Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Recursos Adicionais e Ferramentas Relacionadas&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://doc.traefik.io/traefik/" rel="noopener noreferrer"&gt;Documentação oficial do Traefik&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-started/introduction/build-and-push-first-image/" rel="noopener noreferrer"&gt;Introdução ao Docker: Construir e Publicar uma Imagem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ken_mwaura1/automate-docker-image-builds-and-push-to-docker-hub-using-github-actions-32g5"&gt;Automatize a Construção e Publicação de Imagens Docker no Docker Hub com GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://containrrr.dev/watchtower/" rel="noopener noreferrer"&gt;Watchtower - Atualização Automática de Contêineres&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Firewall e Práticas de Segurança&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.hostinger.com.br/tutoriais/firewall-ubuntu-ufw" rel="noopener noreferrer"&gt;Como configurar o Firewall UFW no Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/30383845/what-is-the-best-practice-of-docker-ufw-under-ubuntu" rel="noopener noreferrer"&gt;Como Corrigir o Docker Ignorando Configurações do UFW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>cloud</category>
      <category>vps</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
