<?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: Lucas Gabriel </title>
    <description>The latest articles on DEV Community by Lucas Gabriel  (@lucasgabriel).</description>
    <link>https://dev.to/lucasgabriel</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%2F861626%2F1aa6c529-de9f-4520-b89c-8be8bc619aba.jpeg</url>
      <title>DEV Community: Lucas Gabriel </title>
      <link>https://dev.to/lucasgabriel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucasgabriel"/>
    <language>en</language>
    <item>
      <title>Funções em JavaScript: Array.filter()</title>
      <dc:creator>Lucas Gabriel </dc:creator>
      <pubDate>Sun, 07 Jan 2024 17:46:17 +0000</pubDate>
      <link>https://dev.to/lucasgabriel/funcoes-em-javascript-arrayfilter-24p8</link>
      <guid>https://dev.to/lucasgabriel/funcoes-em-javascript-arrayfilter-24p8</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Listas são estruturas de dados que estão presentes no dia a dia de programadores. Cada linguagem de programação possui suas especificidades na implementação dessas estruturas, oferecendo diferentes métodos para se trabalhar com os dados nela armazenados.&lt;/p&gt;

&lt;p&gt;O JavaScript oferece algumas funções especiais para manipular &lt;em&gt;listas/arrays&lt;/em&gt;: as &lt;em&gt;HOF's (High Order Functions)&lt;/em&gt;. Estas, basicamente, são funções que podem receber como parâmetro outras funções e também podem retornar uma função como resultado do seu processamento 🤯. Leia mais sobre &lt;a href="https://www.alura.com.br/artigos/high-order-functions"&gt;HOF's aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hoje vamos aprender sobre uma HOF que muito útil para quem precisa filtrar dados em uma lista: &lt;em&gt;filter()&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problematização
&lt;/h2&gt;

&lt;p&gt;Vamos considerar o seguinte cenário: nos foi dada uma lista de clientes cadastrados em um site. Esta lista, inclui clientes com cadastros ativos e inativos, e precisamos filtrar a partir dela somente os cliente com cadastro ativo.&lt;br&gt;
Segue abaixo nossa lista:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lucas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maria&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mateus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Renan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Julya&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jéssica&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para filtrarmos esta lista, a solução mais intuitiva talvez seja estruturar um laço de repetição &lt;code&gt;for&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientesAtivos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ativo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;clientesAtivos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientesAtivos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/* Saída:
[
  { nome: 'Lucas', ativo: true },
  { nome: 'Mateus', ativo: true },
  { nome: 'Jéssica', ativo: true }
]
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criamos uma laço de repetição &lt;code&gt;for&lt;/code&gt; cuja variável de controle &lt;code&gt;i&lt;/code&gt; começa em zero, porque vamos utilizá-la para acessar as posições do array, que como sabemos começa em 0. Essa variável será incrementada em +1 até que ela atinja a quantidade de elementos do array - 1, ou seja, a última posição do array, que é o seu número de elementos - 1.&lt;br&gt;
Acessamos a chave &lt;code&gt;ativo&lt;/code&gt; do objeto usando o ´&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Property_accessors"&gt;bracket notation`(notação de colchetes)&lt;/a&gt;. Como ela guarda um valor booleano, no bloco &lt;code&gt;if&lt;/code&gt;, se for o valor for &lt;code&gt;true&lt;/code&gt; o objeto será adiciona ao &lt;em&gt;array clientesAtivos&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A solução acima funciona perfeitamente. Obteremos o resultado desejado. Porém, como programadores precisamos sempre pensar na melhor solução para um problema. Em muitos casos, haverão várias alternativas para solucionar o mesmo problema. E nestes casos, nosso trabalho é escolher a melhor alternativa para aquele problema, naquele contexto específico.&lt;/p&gt;

&lt;p&gt;É possível resolver esse problema da filtragem da lista com código menor e maior legibilidade, diminuindo nossa chance erro e facilitando a vida de quem eventualmente venha a trabalhar no nosso código posteriormente.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;filter()&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"&gt;&lt;em&gt;filter()&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; é uma HOF do JavaScript, cujo objetivo é filtrar dados de um &lt;em&gt;array&lt;/em&gt; e armazenar o resultado em um novo &lt;em&gt;array&lt;/em&gt;. Note que o &lt;em&gt;filter()&lt;/em&gt; não faz alterações no array em que ele é usado, ele cria um novo array e armazena nele os valores que atendem ao critério do filtro aplicado.&lt;/p&gt;

&lt;p&gt;A sintaxe do filter é a seguinte:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;js&lt;br&gt;
array.filter(function callback(valorAtual, indice, &lt;br&gt;
arrayOriginal) {});&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;callback&lt;/em&gt;: função que é aplicada em todos os elementos do array;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;valorAtual&lt;/em&gt;: parâmetro obrigatório e é referente ao elemento que está sendo acessado no momento;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;indice&lt;/em&gt;: parâmetro opcional. Representa a posição do &lt;em&gt;valorAtual&lt;/em&gt; no &lt;em&gt;array&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;arrayOriginal&lt;/em&gt;: parâmetro opcional. &lt;em&gt;Array&lt;/em&gt; original em que o &lt;em&gt;valorAtual&lt;/em&gt; está armazenado;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Podemos observar que o filter recebe obrigatoriamente uma função como parâmetro. Essa função é uma &lt;em&gt;callback&lt;/em&gt; (&lt;a href="https://www.freecodecamp.org/portuguese/news/funcoes-de-callback-em-javascript-o-que-sao-e-como-usa-las/"&gt;aprenda sobre &lt;em&gt;callbacks&lt;/em&gt; aqui&lt;/a&gt;) que aplica um teste em cada elemento do array. Os valores que passam no teste são adicionados no novo &lt;em&gt;array&lt;/em&gt; que é retornado pelo &lt;em&gt;filter&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos aplicar o &lt;em&gt;filter&lt;/em&gt; para solucionar nosso problema de filtrar clientes ativos:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
const clientesAtivosFilter = clientes.filter(cliente =&amp;gt; &lt;br&gt;
cliente['ativo']);&lt;/p&gt;

&lt;p&gt;console.log(clientesAtivosFilter);&lt;/p&gt;

&lt;p&gt;/**&lt;br&gt;
Saída:&lt;br&gt;
[&lt;br&gt;
  { nome: 'Lucas', ativo: true },&lt;br&gt;
  { nome: 'Mateus', ativo: true },&lt;br&gt;
  { nome: 'Jéssica', ativo: true }&lt;br&gt;
]&lt;br&gt;
*/&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
Sim, resolvemos o mesmo problema com uma única linha de código. Esse é o poder do JavaScript!&lt;br&gt;
Vamos entender como tudo isso está funcionando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;chamamos o filter e passamos para ele uma &lt;em&gt;callback&lt;/em&gt; usando uma sintaxe mais curta, conhecida como &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/Arrow_functions"&gt;&lt;em&gt;arrow function&lt;/em&gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;no parâmetro da &lt;em&gt;callback&lt;/em&gt;, acessamos o elemento do &lt;em&gt;array&lt;/em&gt;, que no caso é um objeto com as chaves &lt;code&gt;nome&lt;/code&gt; e &lt;code&gt;ativo&lt;/code&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;acessamos a chave &lt;code&gt;ativo&lt;/code&gt;, e sendo ela &lt;code&gt;true&lt;/code&gt; o objeto será adicionado ao &lt;em&gt;array&lt;/em&gt; criado e retornado pelo &lt;em&gt;filter&lt;/em&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos para um exemplo um pouco mais complexo. Considere a seguinte lista:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;js&lt;br&gt;
const produtos = [&lt;br&gt;
  {id: 1, descricao: "Smartphone", categoria: "Eletrônico", preco: 1000},&lt;br&gt;
  {id: 2, descricao: "Notebook", categoria: "Eletrônico", preco: 3000},&lt;br&gt;
  {id: 3, descricao: "Geladeira", categoria: "Eletrodoméstico", preco: 1800},&lt;br&gt;
  {id: 4, descricao: "Liquidificador", categoria: "Eletrodoméstico", preco: 150},&lt;br&gt;
  {id: 5, descricao: "Fogão", categoria: "Eletrodoméstico", preco: 500},&lt;br&gt;
  {id: 6, descricao: "AirFryer", categoria: "Eletrodoméstico", preco: 600},&lt;br&gt;
  {id: 7, descricao: "PS5", categoria: "Eletrônico", preco: 4500},&lt;br&gt;
  {id: 8, descricao: "Smart TV 50 4k", categoria: "Eletrônico", preco: 3200},&lt;br&gt;
  {id: 9, descricao: "Monitor Gamer", categoria: "Eletrônico", preco: 1800},&lt;br&gt;
  {id: 10, descricao: "Máquina de Lavar", categoria: "Eletrodoméstico", preco: 1600}&lt;br&gt;
];&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
O desafio agora é filtrar esses produtos pela categoria(Eletrônico) e preço(a partir de &lt;em&gt;2000R$&lt;/em&gt;). A solução com filter ficaria assim:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`js&lt;br&gt;
onst eletronicosCaros = produtos.filter(produto =&amp;gt; produto.categoria === 'Eletrônico' &amp;amp;&amp;amp; produto.preco &amp;gt;= 2000)&lt;/p&gt;

&lt;p&gt;console.log(eletronicosCaros)&lt;/p&gt;

&lt;p&gt;/**&lt;br&gt;
Saída:&lt;br&gt;
[&lt;br&gt;
  {&lt;br&gt;
    id: 2,&lt;br&gt;
    descricao: 'Notebook',&lt;br&gt;
    categoria: 'Eletrônico',&lt;br&gt;
    preco: 3000&lt;br&gt;
  },&lt;br&gt;
  { id: 7, descricao: 'PS5', categoria: 'Eletrônico', preco: 4500 },&lt;br&gt;
  {&lt;br&gt;
    id: 8,&lt;br&gt;
    descricao: 'Smart TV 50 4k',&lt;br&gt;
    categoria: 'Eletrônico',&lt;br&gt;
    preco: 3200&lt;br&gt;
  }&lt;br&gt;
]&lt;br&gt;
*/&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;filter&lt;/em&gt; é um recurso poderoso que dispomos no JavaScript para trabalharmos com listas. Existem várias outras HOF's no JavaScript e você pode conferir algumas &lt;a href="https://medium.com/orangejuicefc/higher-order-functions-no-javascript-cce3b9aab426"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disponibilizei esses códigos que usei como exemplo em um &lt;a href="https://github.com/Lucas-GSS/dio/tree/main/artigos/javascript-filter"&gt;repositório no meu GitHub&lt;/a&gt;. Fique a vontade para clonar, criar fork's e praticar.&lt;br&gt;
Sugestões e feedbacks são sempre bem-vindos. Você pode me contactar no &lt;a href="https://www.linkedin.com/in/lucas-gabriel7/"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
Espero que este conteúdo tenha sido útil de alguma forma. Até mais!&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Docker: Conceitos Básicos e Comandos Iniciais (+ um jogo no final)</title>
      <dc:creator>Lucas Gabriel </dc:creator>
      <pubDate>Thu, 25 May 2023 01:13:08 +0000</pubDate>
      <link>https://dev.to/lucasgabriel/docker-conceitos-basicos-e-comandos-iniciais-um-jogo-no-final-3a55</link>
      <guid>https://dev.to/lucasgabriel/docker-conceitos-basicos-e-comandos-iniciais-um-jogo-no-final-3a55</guid>
      <description>&lt;p&gt;Escrevo este artigo na intenção de que seja uma introdução ao Docker e a alguns conceitos relacionados a ele. Espero que ele seja útil para te apresentar a uma ferramenta tão importante.&lt;/p&gt;

&lt;p&gt;Agora, imagine-se em uma equipe de desenvolvimento. Você desenvolve parte da aplicação em uma distro Linux, e os demais integrantes da equipe possuem diferentes sistemas operacionais do seu, como Windows ou MacOS. Como garantir que a aplicação vai rodar em cada Sistema Operacional? Como garantir que ela funcionará no ambiente de testes e em produção? Como evitar o cansativo trabalho de instalar todas as bibliotecas e dependências necessárias, além das configurações, toda vez que o ambiente mudar?&lt;/p&gt;

&lt;p&gt;A resposta é relativamente simples: &lt;strong&gt;containers.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O que são containers?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Um container é um processo ou conjunto de processos que são organizados de forma isolada no SO hospedeiro. São processos que o kernel do sistema operacional coloca em uma ‘caixa’, assim eles são isolados dos demais processos que estão sendo executados. Ele não possui acesso ao sistema de arquivos, à rede ou a outros containers. O kernel simula todo um ambiente que possui um sistema de arquivos próprio, além disso controla o quanto de recurso os processos do container podem consumir. Mas como isso é feito?&lt;/p&gt;

&lt;p&gt;Por meio de cgroups e namespaces. Control Groups ou cgroups são ferramentas do kernel do Linux que controlam o quanto de recurso um processo pode consumir, por exemplo, a quantidade de RAM, CPU, disco, realizar operações de I/O, etc… Afinal, se um processo pode consumir recurso indefinidamente, isso pode vir a atrapalhar o funcionamento do SO, tornando todas as operações muito lentas ou derrubando o sistema inteiro. Namespaces são responsáveis por segregar os processos. Lembra do filme Matrix, em que os humanos vivem uma realidade simulada por máquinas? Namespaces fazem o mesmo, simulam todo um ambiente alternativo para os processos, assim tudo que os processos executam não afetam o sistema principal, o que torna os containers seguros. Para se aprofundar mais nesses conceitos, recomento &lt;a href="https://etcd.dev/2021/09/20/containers-o-que-sao-namespaces-e-cgroups/"&gt;este artigo do etcd&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;É comum confundir containers com máquinas virtuais, porém existem diferenças fundamentais entre as duas tecnologias. Um container usa o mesmo kernel do SO em que foi criado e é isso que torna o container leve e eficiente, ele é simplesmente um processo sendo executado dentro do SO hospedeiro. Tanto que containers de sistema Linux x64 só rodam em sistemas Linux x64, conatiners Windows x86 somente em sistemas Windows x86.&lt;/p&gt;

&lt;p&gt;Máquinas virtuais servem para rodar outro sistema operacional, como MacOS, usando o mesmo hardware do SO hospedeiro. Para isso é necessário o hypervisor, um software que abstrai parte do hardware para a máquina virtual funcionar. Sendo assim, com uma máquina virtual você tem outro kernel, tem um SO inteiro para trabalhar, porém isso é muito mais custoso e difícil de escalar. &lt;/p&gt;

&lt;p&gt;Máquinas virtuais e containers são soluções para problemas diferentes. Enquanto containers são mais úteis para empacotar e executar aplicações, máquinas virtuais são úteis em casos que é necessário um SO inteiro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DmGwsOIP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://caiodelgado.dev/content/images/2020/04/containervm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DmGwsOIP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://caiodelgado.dev/content/images/2020/04/containervm.png" alt="Diferença entre VM’s e Containers" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diferença entre VM’s e Containers&lt;/p&gt;

&lt;p&gt;Para se aprofundar mais nestes conceitos e diferenças, recomendo este &lt;a href="https://www.youtube.com/watch?v=85k8se4Zo70"&gt;vídeo do Fabio Akita sobre containers e VM's&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Docker?
&lt;/h2&gt;

&lt;p&gt;Docker é um software que visa simplificar a criação e o gerenciamento de containers. Ele foi desenvolvido por Solomon Hykes e apresentado na PyCon de 2013 e foi um divisor de águas na manipulação de containers e imagens. Com ele é possível empacotar aplicações e todas suas dependências em imagens e executá-las em containers.&lt;/p&gt;

&lt;p&gt;Empacotamos nossas aplicações em imagens, que são como scripts que contém tudo o que é necessário para a execução do container, como por exemplo: o código-fonte, bibliotecas, dependências, etc… Imagem é a matéria prima do container.&lt;/p&gt;

&lt;p&gt;O Docker possui um hub de imagens, o &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;, que é um repositório onde estão imagens oficiais das mais diferentes tecnologias como banco de dados, runtimes, So’s, etc… Nesse repositório podemos baixar imagens e após criar uma conta subir as nossas próprias. &lt;/p&gt;

&lt;p&gt;Docker ficou muito popular e muito útil pois simplificou e tornou eficiente a manipulação de containers e imagens. Docker não inventou essas tecnologias, elas já existiam no kernel do Linux. Seu grande mérito está em tornar o uso dessas tecnologias amigável e produtivo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação do Docker e Comandos Básicos
&lt;/h2&gt;

&lt;p&gt;Caso não tenha o Docker instalado: &lt;a href="https://docs.docker.com/get-docker/"&gt;Guia Instalação Oficial - Docker&lt;/a&gt;. Escolha a opção do seu SO e siga o passo a passo da instalação.&lt;/p&gt;

&lt;p&gt;Vamos agora botar a mão na massa e desbravar o Docker. Para criar o seu primeiro container, digite o comando abaixo no terminal 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;docker container run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mX42F4s1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osqj9wy9f25irl2uztie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mX42F4s1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osqj9wy9f25irl2uztie.png" alt="output docker-cli" width="659" height="505"&gt;&lt;/a&gt;&lt;br&gt;
O que acabamos de fazer é baixar a imagem hello-world e executá-la em um container. Porém há informações nesse output que vale a pena analisarmos para entendermos um pouco mais sobre o funcionamento do Docker.&lt;/p&gt;

&lt;p&gt;Temos um descrição do procecedimento que o Docker seguiu após a execução do comando &lt;code&gt;run&lt;/code&gt;. Primeiro o comando digitado no CLI foi enviado para Docker Daemon, que, por sua vez verificou se a imagem “hello-world” estava disponível localmente. Como não estava a imagem foi baixado do &lt;strong&gt;&lt;em&gt;hub&lt;/em&gt;&lt;/strong&gt; do Docker num processo semelhante ao ***&lt;strong&gt;&lt;em&gt;git pull.&lt;/em&gt;&lt;/strong&gt;*** Após baixar a imagem, o daemon criou um novo container, cujo o output é o que obtivemos no terminal.&lt;/p&gt;

&lt;p&gt;Você pode verificar quais imagens você tem localmente com o comando abaixo:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dQl1kLHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4u4vapx6pppsd2vnkt5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dQl1kLHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4u4vapx6pppsd2vnkt5z.png" alt="output docker-cli" width="511" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para verificar quais containers estão em execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YMBCTrlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zrvyq34i0hshusg6ich.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YMBCTrlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zrvyq34i0hshusg6ich.png" alt="output docker-cli" width="580" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas se foi criado um container a partir da imagem ***********&lt;strong&gt;&lt;em&gt;hello-world,&lt;/em&gt;&lt;/strong&gt;*********** por que ele não aparece na saída do comando acima? Isso é porque o container foi criado, executado e finalizado. Para listar containers que já foram finalizados, utilizamos o parâmetro &lt;code&gt;-a&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3d4rNEGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scz36596jm17jdf0ee8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3d4rNEGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scz36596jm17jdf0ee8u.png" alt="output docker-cli" width="800" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora sim podemos ver todos os containers, tanto os que estão em execução como os que já foram finalizados. Aqui também há alguns detalhes que valem a pena serem observados.&lt;/p&gt;

&lt;p&gt;Primeiro podemos ver que o container criado possui um ID, que é importante caso seja necessário realizar uma operação em um container específico. Podemos observar também o nome da imagem, além do comando que é executado no container logo quando é iniciado. Podemos ver quando o container foi criado e o seu status atual, a porta que ele está disponibilizando e por fim um nome, que é aleatório dado pelo Docker.&lt;/p&gt;

&lt;p&gt;No output do comando &lt;code&gt;docker container run hello-world&lt;/code&gt; há uma sugestão de um comando mais ambicioso. Vamos exexutá-lo? Além disso, vamos também nomear esse nosso novo container? 🤩&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; meu-container ubuntu bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MfFBmvB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcf9xtz7xxp3fca1hcf7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MfFBmvB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcf9xtz7xxp3fca1hcf7.png" alt="output docker-cli" width="720" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Automagicamente temos um novo terminal diante de nós! Agora vamos entender o que fizemos: por meio do comando &lt;code&gt;run&lt;/code&gt; pedimos a criação de um novo container, o parâmetro &lt;code&gt;-it&lt;/code&gt; indica que queremos interagir com o container, já o &lt;code&gt;--name&lt;/code&gt; nos permite passar um nome para o container (************&lt;strong&gt;&lt;em&gt;meu-container),&lt;/em&gt;&lt;/strong&gt;************ depois especificamos a imagem que queremos (***********&lt;strong&gt;&lt;em&gt;ubuntu) e&lt;/em&gt;&lt;/strong&gt;*********** por fim damos o comando &lt;code&gt;bash&lt;/code&gt; para entrarmos no terminal do container. E sim, agora estamos em um terminal do Ubuntu. Incrível, né!?&lt;/p&gt;

&lt;p&gt;Execute o comando abaixo e veja por si mesmo que é de fato um Ubuntu:&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;cat&lt;/span&gt; /etc/os-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0i8H97gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iglz7mblabvpvou37vgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0i8H97gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iglz7mblabvpvou37vgg.png" alt="output docker-cli" width="721" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos criar um arquivo e escrever nele:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4cxiutba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xasxoswfl1hdgrl8z8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4cxiutba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xasxoswfl1hdgrl8z8f.png" alt="print file content" width="726" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porém, quando finalizarmos esse container esse arquivo e qualquer outro que foi criado não persistirá no disco. Isso ocorre porque, como aprendemos no início desse artigo, esses containers são isolados do SO hospedeiro e esse isolamento inclui o sistema de arquivos.&lt;/p&gt;

&lt;p&gt;Contudo, é possível permitir que o container tenha acesso ao sistema de arquivos, à rede, à outros containers… mas, isso é assunto para um próximo artigo, em que podemos aprender sobre mapeamento de portas, de volume, comunicação entre containers, entre outros assuntos. Até lá, para se aprofundar mais recomendo &lt;a href="https://docs.docker.com/get-started/overview/"&gt;Documentação Oficial do Docker&lt;/a&gt; e também &lt;a href="https://www.youtube.com/watch?v=EEvJsgiZprM&amp;amp;t=2736s"&gt;este vídeo do canal Full Cycle&lt;/a&gt;, que é excelente e possui vários outros conteúdos. Vale a pena conferir.&lt;/p&gt;

&lt;p&gt;Por fim, vamos sair do terminal do nosso container digitando &lt;code&gt;exit&lt;/code&gt;  e apertando **&lt;strong&gt;&lt;em&gt;Enter&lt;/em&gt;&lt;/strong&gt;**, e agora vamos listar nossos containers com &lt;code&gt;docker ps -a&lt;/code&gt; (um comando mais curto para listar os containers):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6iNvAR35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5yicy9dkneiq145egwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6iNvAR35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5yicy9dkneiq145egwb.png" alt="output docker-cli" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos aprender a remover containers e a apagar imagens. Isso é útil pois, ainda que containers sejam leves eles consomem recursos de CPU e memória, muitos containers podem vir a afetar o desempenho da sua máquina. As imagens também são leves, porém o acúmulo de imagens desnecessárias ocupam armazenameto. Para remover um container específico, você pode usar o nome ou o ID do container. Vamos usar o nome que demos ao nosso&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm &lt;/span&gt;meu-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Da mesma forma você pode remover imagens específicas por meio do ID ou nome, o que muda é que o comando é o &lt;code&gt;rmi&lt;/code&gt; (remove image). Porém aqui vou ensinar um truque. Como possuímos mais de uma imagem vamos apagá-las numa tacada só:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker rmi &lt;span class="si"&gt;$(&lt;/span&gt;docker images &lt;span class="nt"&gt;-aq&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$()&lt;/code&gt; indica uma variável no shell. Neste caso o valor dessa variável é o retorno do comando &lt;code&gt;docker images -aq&lt;/code&gt; que lista todas as imagens locais do Docker, o &lt;code&gt;rmi&lt;/code&gt; será aplicado nessas imagens. O mesmo pode ser feito nos containers porém substituindo por &lt;code&gt;docker ps -aq&lt;/code&gt; . O parâmetro &lt;code&gt;-f&lt;/code&gt; pode ser usado após &lt;code&gt;rm&lt;/code&gt; ou &lt;code&gt;rmi&lt;/code&gt; para forçar a remoção dos containers em execução ou imagens que estejam servindo de base para containers em execução.&lt;/p&gt;

&lt;p&gt;E chegamos ao fim desse artigo introdutório sobre Docker. Espero que tenha sido útil de algum jeito. Dúvidas, sugestões e feedbacks são muito bem-vindos 😄. Ah, e antes de ir quero deixar aqui uma dica divertida: execute o comando &lt;code&gt;docker run -it andrius/ascii-patrol&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
