<?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>Forem: Gabriel Batista</title>
    <description>The latest articles on Forem by Gabriel Batista (@batistagabriel).</description>
    <link>https://forem.com/batistagabriel</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%2F709426%2F676fe7c1-7a3b-442a-ada8-146a2e723316.jpeg</url>
      <title>Forem: Gabriel Batista</title>
      <link>https://forem.com/batistagabriel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/batistagabriel"/>
    <language>en</language>
    <item>
      <title>Using Secure Base Images</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Wed, 12 Jun 2024 01:25:32 +0000</pubDate>
      <link>https://forem.com/batistagabriel/using-secure-base-images-5e6o</link>
      <guid>https://forem.com/batistagabriel/using-secure-base-images-5e6o</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.tenor.com%2Fm%2FDSG9ZID25nsAAAAC%2Fhello-there-general-kenobi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.tenor.com%2Fm%2FDSG9ZID25nsAAAAC%2Fhello-there-general-kenobi.gif" alt="Hello There!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote this article to share a bit of what I've learned in the &lt;a href="https://www.linuxtips.io/pick" rel="noopener noreferrer"&gt;PICK&lt;/a&gt; from &lt;a href="https://www.linuxtips.io/" rel="noopener noreferrer"&gt;LinuxTips&lt;/a&gt;. So, grab your drink and join me.&lt;/p&gt;

&lt;p&gt;It all started when, sometimes, security tools reported low/mid vulnerabilities, and when we went to assess what these vulnerabilities were, we always ended up in the mental agreement: "it's not something we did, so there's no way to fix it."&lt;/p&gt;

&lt;p&gt;During the PICK classes, I got to know Chainguard. And then the idea came up to write this article to show how to use a secure base image to build the container for my application.&lt;/p&gt;

&lt;p&gt;To demonstrate this, we will containerize a very basic console application of "hello world" in DotNet throughout this article, as the focus here is on how to build a Dockerfile for the application in a more secure way, not the application itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the application
&lt;/h2&gt;

&lt;p&gt;Assuming you already have the DotNet SDK installed and configured in your environment, let's open our terminal and start creating the project.&lt;/p&gt;

&lt;p&gt;We will create our application using the &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-new-sdk-templates#console" rel="noopener noreferrer"&gt;console template of the DotNet CLI&lt;/a&gt;. We will do this using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new console &lt;span class="nt"&gt;-o&lt;/span&gt; HelloWorldApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this is done, let's move to our favorite text editor to start manipulating the files contained in the project directory.&lt;/p&gt;

&lt;p&gt;With your text editor open, let's modify the &lt;code&gt;Program.cs&lt;/code&gt; file to have our Hello World. Edit your file to look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;HelloWorldApp&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the Dockerfile
&lt;/h2&gt;

&lt;p&gt;Perfect, now that you have created our application (which has the potential to hack NASA), it's time to create our Dockerfile to containerize our application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is worth remembering that the Dockerfile needs to be at the same level as the csproj file, in our case, inside the &lt;code&gt;HelloWorldApp&lt;/code&gt; directory.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To build our Dockerfile, in addition to using secure base images, we will use an organization and performance concept called &lt;a href="https://docs.docker.com/build/building/multi-stage/" rel="noopener noreferrer"&gt;multi-stage builds&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  First stage
&lt;/h3&gt;

&lt;p&gt;Without further ado, let's move to the first line of our Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The base image we are using has a reduced scope so that there are only dependencies that satisfy the use of the DotNet SDK.&lt;/p&gt;

&lt;p&gt;Therefore, compared to the scope of a base alpine image, for example, the chances of our container having vulnerabilities that do not pertain only to the DotNet SDK dependencies are much smaller. And this is the great advantage of using Chainguard's base images.&lt;/p&gt;

&lt;p&gt;Still, regarding the first line, note that we used an alias to identify the stage that will be executed. In this case, we called the current stage &lt;code&gt;build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Moving on, so that we can execute our command that will compile our application and generate our dll (&lt;code&gt;dotnet publish&lt;/code&gt;), we need to first declare that our files belong to a non-root user so they can be compiled. We will do this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nonroot:nonroot &lt;span class="nb"&gt;.&lt;/span&gt; /source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are using the &lt;code&gt;COPY&lt;/code&gt; command to copy all the files from the current directory where the Dockerfile is located, under the permissions of a non-root user, to a directory inside the container called &lt;code&gt;source&lt;/code&gt; which will be used later.&lt;/p&gt;

&lt;p&gt;Since it is a secure base image, some operations (such as publish in our case) require a little more attention to permission levels, since letting things be compiled at a high level would undermine the security of the image.&lt;/p&gt;

&lt;p&gt;At the end of this stage, we will define our default working directory and carry out the process of creating our dll, which will be directed to a directory called &lt;code&gt;Release&lt;/code&gt;. This will be done in the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;WORKDIR /source
RUN dotnet publish &lt;span class="nt"&gt;--use-current-runtime&lt;/span&gt; &lt;span class="nt"&gt;--self-contained&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final stage
&lt;/h3&gt;

&lt;p&gt;Now, in this stage, we no longer need dependencies related to the SDK; we now need resources related to the DotNet runtime to run our dll. For this, we will use the following base image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, we will proceed to define our default working directory and now use the great advantage of using multi-stage. As in the &lt;code&gt;build&lt;/code&gt; stage, we have already generated our dll; we can now copy our dll to the current stage to use it. We will do this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;WORKDIR /
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build /source &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in the &lt;code&gt;COPY&lt;/code&gt; command we are stating that we want what was generated in the &lt;code&gt;/source&lt;/code&gt; directory of the &lt;code&gt;build&lt;/code&gt; stage to be copied to the root context &lt;code&gt;.&lt;/code&gt;. And this is where we gain organization and performance in our Dockerfile, segmenting the creation and reuse of artifacts.&lt;/p&gt;

&lt;p&gt;Finally, we will define our main command that will be executed when our container starts, that is, we will indicate that we use DotNet to run our dll. We do this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dotnet"&lt;/span&gt;, &lt;span class="s2"&gt;"Release/HelloWorldApp.dll"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complete Dockerfile
&lt;/h3&gt;

&lt;p&gt;With all this done, our final Dockerfile should look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nonroot:nonroot &lt;span class="nb"&gt;.&lt;/span&gt; /source
WORKDIR /source

RUN dotnet publish &lt;span class="nt"&gt;--use-current-runtime&lt;/span&gt; &lt;span class="nt"&gt;--self-contained&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; Release

FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
WORKDIR /
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build /source &lt;span class="nb"&gt;.&lt;/span&gt;

ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dotnet"&lt;/span&gt;, &lt;span class="s2"&gt;"Release/HelloWorldApp.dll"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building and Running the Image
&lt;/h2&gt;

&lt;p&gt;With our Dockerfile created, it is time to build our image and see if everything works as expected (this is usually where everything catches fire). To do this, being in the same directory where our Dockerfile is, we will run the following command:&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; helloworldapp &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the build is complete, let's move to the most awaited moment: running a container that will have our dll being executed. To do this, use the command:&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;--rm&lt;/span&gt; helloworldapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's All, Folks
&lt;/h2&gt;

&lt;p&gt;This concludes our journey with the use of secure base images and multi-stage Dockerfiles. Clearly, you can venture further, for example, by creating GitHub workflows that scan the code or container with each push/pull request using tools like Snyk or Trivy.&lt;/p&gt;

&lt;p&gt;Now it's up to you: abuse and use what we've covered here! Explore other base images, try to understand more how they work, try refactoring Dockerfiles to use multi-stage. Go beyond!&lt;/p&gt;

&lt;p&gt;Remember: may the force be with you, live long and prosper, and don't panic! Allons-y!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
    </item>
    <item>
      <title>Usando Imagens Base Seguras</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Wed, 12 Jun 2024 01:25:28 +0000</pubDate>
      <link>https://forem.com/batistagabriel/usando-imagens-base-seguras-2dc7</link>
      <guid>https://forem.com/batistagabriel/usando-imagens-base-seguras-2dc7</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.tenor.com%2Fm%2FDSG9ZID25nsAAAAC%2Fhello-there-general-kenobi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.tenor.com%2Fm%2FDSG9ZID25nsAAAAC%2Fhello-there-general-kenobi.gif" alt="Hello There!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Escrevi este artigo para compartilhar um pouco do que já aprendi no &lt;a href="https://www.linuxtips.io/pick" rel="noopener noreferrer"&gt;PICK&lt;/a&gt; da &lt;a href="https://www.linuxtips.io/" rel="noopener noreferrer"&gt;LinuxTips&lt;/a&gt;. Então, pegue sua bebida e me acompanhe.&lt;/p&gt;

&lt;p&gt;Tudo começou quando, por vezes, as ferramentas de segurança reportavam vulnerabilidades low/mid e, quando íamos avaliar o que era essa vulnerabilidade, nós sempre acabávamos no grande acordo mental: "não é algo que a gente fez, então não tem como resolver".&lt;/p&gt;

&lt;p&gt;Durante as aulas do PICK, conheci a Chainguard. E aí surgiu a ideia de montar este artigo para mostrar como utilizar uma imagem base segura para construir o container da minha aplicação.&lt;/p&gt;

&lt;p&gt;Para mostrar isso, vamos containerizar uma aplicação de console bem básica de "hello world" em DotNet ao longo deste artigo, visto que o foco aqui é como montar um Dockerfile para a aplicação de forma mais segura e não a aplicação em si.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a aplicação
&lt;/h2&gt;

&lt;p&gt;Assumindo que você já tenha o SDK do DotNet instalado e configurado em seu ambiente, vamos abrir nosso terminal e começar a criação do projeto. &lt;/p&gt;

&lt;p&gt;Vamos criar nossa aplicação usando o &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-new-sdk-templates#console" rel="noopener noreferrer"&gt;template &lt;code&gt;console&lt;/code&gt; da CLI do DotNet&lt;/a&gt;. Faremos isso utilizando o comando a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new console &lt;span class="nt"&gt;-o&lt;/span&gt; HelloWorldApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feito isto, vamos para nosso editor de texto preferido para começar a manipular os arquivos contidos no diretório do projeto.&lt;/p&gt;

&lt;p&gt;Com seu editor de texto aberto, vamos alterar o arquivo &lt;code&gt;Program.cs&lt;/code&gt; para que ele tenha nosso "Hello World". Edite seu arquivo para que ele se pareça com o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;HelloWorldApp&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Criando o Dockerfile
&lt;/h2&gt;

&lt;p&gt;Perfeito, agora que você criou nossa aplicação (que tem potencial para hackear a NASA), é hora de criarmos nosso Dockerfile para containerizar nossa aplicação. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vale lembrar que o Dockerfile precisa ficar no mesmo nível do arquivo csproj, no nosso caso, dentro do diretório &lt;code&gt;HelloWorldApp&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Para construir nosso Dockerfile, além de utilizar imagens base seguras, vamos utilizar um conceito de organização e performance chamado &lt;a href="https://docs.docker.com/build/building/multi-stage/" rel="noopener noreferrer"&gt;multi-stage builds&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Primeira etapa
&lt;/h3&gt;

&lt;p&gt;Sem mais delongas, vamos para a primeira linha do nosso Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A imagem base que estamos utilizando possui um escopo reduzido para que apenas haja dependências que satisfaçam o uso do SDK do DotNet. &lt;/p&gt;

&lt;p&gt;Portanto, se comparado com o escopo de uma imagem base alpine, por exemplo, as chances de nosso container ter vulnerabilidades que não dizem respeito apenas às dependências do SDK do DotNet são bem menores. E este é o grande diferencial de utilizar as imagens base da Chainguard.&lt;/p&gt;

&lt;p&gt;Ainda sobre a primeira linha, perceba que utilizamos um alias para identificar a etapa que será executada. Neste caso, chamamos a etapa atual de &lt;code&gt;build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Seguindo em frente, para que nós possamos executar nosso comando que irá compilar nossa aplicação e gerar nossa dll (&lt;code&gt;dotnet publish&lt;/code&gt;), precisaremos antes declarar que nossos arquivos pertencem a um usuário não root para poderem ser compilados. Faremos isto da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nonroot:nonroot &lt;span class="nb"&gt;.&lt;/span&gt; /source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos utilizando o comando &lt;code&gt;COPY&lt;/code&gt; para copiarmos todos os arquivos do diretório atual onde está o Dockerfile, sob as permissões de um usuário que não é root, para um diretório dentro do container chamado &lt;code&gt;source&lt;/code&gt; que será utilizado posteriormente.&lt;/p&gt;

&lt;p&gt;Por se tratar de uma imagem base segura, algumas operações (como o publish no nosso caso) requerem um pouco mais de atenção a níveis de permissão, visto que deixar coisas serem compiladas a um nível elevado levaria por água abaixo toda a segurança da imagem.&lt;/p&gt;

&lt;p&gt;Ao final desta etapa, vamos definir nosso diretório de trabalho padrão e realizar o processo de criação da nossa dll que será direcionada para um diretório chamado &lt;code&gt;Release&lt;/code&gt;. Isto será feito nas linhas a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;WORKDIR /source
RUN dotnet publish &lt;span class="nt"&gt;--use-current-runtime&lt;/span&gt; &lt;span class="nt"&gt;--self-contained&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Etapa final
&lt;/h3&gt;

&lt;p&gt;Agora, nesta etapa, não precisamos mais que haja dependências relacionadas ao SDK; precisamos agora ter recursos referentes ao runtime do DotNet para executar nossa dll. Para isso, vamos utilizar a seguinte imagem base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após isso, vamos então partir para a definição do nosso diretório de trabalho padrão e vamos agora utilizar a grande vantagem de se utilizar o multi-stage. Como na etapa de &lt;code&gt;build&lt;/code&gt; nós já geramos a nossa dll, podemos então copiar nossa dll para a etapa atual para podermos utilizá-la. Vamos fazer isso da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;WORKDIR /
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build /source &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que no comando &lt;code&gt;COPY&lt;/code&gt; estamos informando que queremos que seja copiado para o contexto raiz &lt;code&gt;.&lt;/code&gt; o que foi gerado no diretório &lt;code&gt;/source&lt;/code&gt; da etapa &lt;code&gt;build&lt;/code&gt;. E é aí que ganhamos organização e performance em nosso Dockerfile, segmentando a criação e reutilização de artefatos.&lt;/p&gt;

&lt;p&gt;Por fim, vamos definir qual será nosso comando principal que será executado quando nosso container for iniciado, ou seja, vamos indicar que usemos o DotNet para executar nossa dll. Fazemos isso da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dotnet"&lt;/span&gt;, &lt;span class="s2"&gt;"Release/HelloWorldApp.dll"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dockerfile Completo
&lt;/h3&gt;

&lt;p&gt;Com tudo isso feito, nosso Dockerfile final deve se parecer com o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM cgr.dev/chainguard/dotnet-sdk:latest AS build
COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nonroot:nonroot &lt;span class="nb"&gt;.&lt;/span&gt; /source
WORKDIR /source

RUN dotnet publish &lt;span class="nt"&gt;--use-current-runtime&lt;/span&gt; &lt;span class="nt"&gt;--self-contained&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; Release

FROM cgr.dev/chainguard/dotnet-runtime:latest AS final
WORKDIR /
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build /source &lt;span class="nb"&gt;.&lt;/span&gt;

ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dotnet"&lt;/span&gt;, &lt;span class="s2"&gt;"Release/HelloWorldApp.dll"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build e Execução da Imagem
&lt;/h2&gt;

&lt;p&gt;Com nosso Dockerfile criado, é hora de fazer o build da nossa imagem e ver se tudo funciona como o esperado (geralmente é aqui que tudo pega fogo). Para fazer isso, estando no mesmo diretório onde nosso Dockerfile está, vamos executar o seguinte comando:&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; helloworldapp &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após o build concluído, vamos para o momento mais aguardado: a execução de um container que possuirá nossa dll sendo executada. Para isso, utilize o comando:&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;--rm&lt;/span&gt; helloworldapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Isso É Tudo, Pessoal
&lt;/h2&gt;

&lt;p&gt;Isto conclui nossa jornada com o uso de imagens base seguras e multi-stage em Dockerfiles. Claramente, você pode se aventurar indo além, por exemplo, criando workflows no GitHub que fazem o scan do código ou do container a cada push/pull request usando ferramentas como o Snyk ou o Trivy.&lt;/p&gt;

&lt;p&gt;Agora é com você: abuse e use o que passamos por aqui! Explore outras imagens base, tente entender mais como funcionam, tente refatorar Dockerfiles para utilizar multi-stage. Vá além!&lt;/p&gt;

&lt;p&gt;Lembre-se: que a força esteja com você, tenha uma vida longa e próspera e não entre em pânico! Allons-y!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
    </item>
  </channel>
</rss>
