<?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: Mustafa Altunok</title>
    <description>The latest articles on DEV Community by Mustafa Altunok (@maltunok).</description>
    <link>https://dev.to/maltunok</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%2F686229%2F7fb6a3b9-9f73-4328-a893-862b79bc4082.jpeg</url>
      <title>DEV Community: Mustafa Altunok</title>
      <link>https://dev.to/maltunok</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maltunok"/>
    <language>en</language>
    <item>
      <title>Dockerfile for .Net 7 App with Non-Root User</title>
      <dc:creator>Mustafa Altunok</dc:creator>
      <pubDate>Sun, 09 Jul 2023 20:49:33 +0000</pubDate>
      <link>https://dev.to/maltunok/dockerfile-for-net-7-app-with-non-root-user-1om7</link>
      <guid>https://dev.to/maltunok/dockerfile-for-net-7-app-with-non-root-user-1om7</guid>
      <description>&lt;p&gt;Here in this post I would like to outline a dockerfile for .Net 7 app with non-root user. This is typically done to enhance security by running the application with a non-root user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine AS base
WORKDIR /app
EXPOSE 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this very first stage, first of all base image is set. It uses the image &lt;em&gt;mcr.microsoft.com/dotnet/aspnet&lt;/em&gt; with the tag 7.0-alpine. The AS base part gives a name ("base") to this stage, which can be referred to later in the Dockerfile.Then the working directory is set inside the container to /app. It means that any subsequent instructions will be executed in this directory unless explicitly changed.TLastly Docker is informed that the container will listen on port 8080 at runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENV ASPNETCORE_URLS=http://*:8080
ENV COMPlus_EnableDiagnostics=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the first line sets an environment variable named ASPNETCORE_URLS with the value http://&lt;em&gt;:8080. In ASP.NET Core applications, ASPNETCORE_URLS is an environment variable that specifies the URLs or ports on which the application will listen. In this case, it is set to http://&lt;/em&gt;:8080, which means the application will listen on all network interfaces (*) on port 8080.&lt;br&gt;
This second line sets an environment variable named COMPlus_EnableDiagnostics with the value 0. COMPlus_EnableDiagnostics is an environment variable specific to the .NET runtime. Setting it to 0 disables diagnostic features and optimizations in the .NET runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["DemoApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build DemoApp.csproj -c Release -o /app/build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the second stage; the first line sets the base image for the current stage of the build. It uses the image &lt;em&gt;mcr.microsoft.com/dotnet/sdk&lt;/em&gt; with the tag 6.0. The AS build part gives a name ("build") to this stage, which can be referred to later in the Dockerfile. &lt;br&gt;
Then the working directory is set inside the container to /src. The third line copies the DemoApp.csproj file from the local directory (the directory where the Dockerfile resides) to the current working directory (/src) inside the container.&lt;br&gt;
Fourth instruction runs the dotnet restore command inside the container. It restores the dependencies specified in the DemoApp.csproj file.&lt;br&gt;
COPY . . instruction  copies the remaining files and directories from the local directory to the current working directory (/src) inside the container. It copies all the files required for building the application.&lt;br&gt;
The last instruction runs the dotnet build command inside the container, building the application specified by DemoApp.csproj. The -c Release flag specifies the build configuration as "Release". The -o /app/build flag specifies the output directory for the build artifacts as /app/build inside the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM build AS publish
RUN dotnet publish DemoApp.csproj -c Release -o /app/publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the first line creates a new stage named publish that will inherit all the files and configurations from the build stage.&lt;br&gt;
The second instruction runs the dotnet publish command inside the container to publish the application. It targets the DemoApp.csproj project file, specifies the build configuration as Release using the -c Release flag, and sets the output directory to /app/publish using the -o /app/publish flag. The dotnet publish command packages the application along with its dependencies into a directory suitable for deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the first line creates a new stage named final that will inherit all the files and configurations from the base stage.&lt;br&gt;
The second line sets the working directory inside the container to /app. It means that any subsequent instructions will be executed in this directory unless explicitly changed.&lt;br&gt;
The third line copies the published artifacts from the publish stage into the current final stage. The --from=publish flag specifies the source stage from which to copy the files. In this case, it refers to the publish stage. The /app/publish is the source directory in the publish stage, and the . represents the destination directory in the final stage. This line effectively copies the published application files from the publish stage to the /app directory in the final stage.&lt;/p&gt;

&lt;p&gt;This stage is typically used to create the final image for deployment. It starts from the base image, sets up the working directory, and copies the published application artifacts into the image. Additional instructions can be added to configure the runtime environment or perform any necessary setup steps before running the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN addgroup -S appgroup &amp;amp;&amp;amp; adduser -S appuser -G appgroup
RUN chown -R appuser:appgroup /app &amp;amp;&amp;amp; chmod -R 755 /app
USER appuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These three lines in the Dockerfile build on the previous instructions to set ownership and permissions for the /app directory and switch to the appuser as the user for subsequent commands.&lt;br&gt;
These instructions are commonly used to ensure proper ownership and permissions for the application files and to switch to a non-root user for running the application within the container.&lt;br&gt;
The first line creates a new system group named appgroup using addgroup, and then creates a new system user named appuser and adds it to the appgroup using adduser.&lt;br&gt;
The second line changes the ownership of the /app directory and its contents recursively to the appuser:appgroup user and group using chown. The chown -R command sets ownership recursively for all files and directories within /app. Then, chmod is used to set the permissions of the /app directory and its contents to 755, which allows read, write, and execute permissions for the user (appuser) and read and execute permissions for the group (appgroup) and others.&lt;br&gt;
THe last line sets the user context to appuser, meaning that any subsequent commands will be executed with the permissions and environment of the appuser. This is typically done to enhance security by running the application with a non-root user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENTRYPOINT ["dotnet", "DemoApp.dll"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the last insstruction of our Dockerfile. This line sets the entrypoint of the container to the dotnet command, with DemoApp.dll as the argument. The dotnet command is the .NET CLI command-line tool used to execute .NET applications.&lt;br&gt;
By setting the entrypoint to dotnet, when the container starts, it will automatically execute the specified .NET application (DemoApp.dll in this case) using the dotnet command.&lt;br&gt;
The entrypoint is typically used to specify the main command or process that should be run when the container starts. In this case, it indicates that the container should run the specified .NET application as its main process.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>devops</category>
    </item>
    <item>
      <title>Azure DevOps Agents and Cleaning Up the Working Folder</title>
      <dc:creator>Mustafa Altunok</dc:creator>
      <pubDate>Wed, 05 Jul 2023 14:57:27 +0000</pubDate>
      <link>https://dev.to/maltunok/azure-devops-agents-and-directories-2h0g</link>
      <guid>https://dev.to/maltunok/azure-devops-agents-and-directories-2h0g</guid>
      <description>&lt;p&gt;In the context of Azure DevOps and Azure Pipelines, an Azure agent refers to a software component that is installed and configured on a machine or a virtual machine. These agents are responsible for executing tasks and jobs defined in your build and release pipelines.&lt;/p&gt;

&lt;p&gt;Azure agents can be categorized into two types:&lt;/p&gt;

&lt;p&gt;Self-hosted agents:&lt;/p&gt;

&lt;p&gt;Self-hosted agents are installed and configured on your own infrastructure, such as physical machines, virtual machines, or containers.&lt;br&gt;
With self-hosted agents, you have more control over the environment and can customize it to meet your specific requirements, including software dependencies, tools, and network configurations.&lt;br&gt;
Self-hosted agents are particularly useful when you have specialized hardware or specific security restrictions that prevent you from using Microsoft-hosted agents.&lt;/p&gt;

&lt;p&gt;Microsoft-hosted agents:&lt;/p&gt;

&lt;p&gt;Microsoft-hosted agents are provided by Azure DevOps as a service. These agents are maintained and managed by Microsoft.&lt;br&gt;
Microsoft-hosted agents offer a variety of preconfigured environments and tools, including Windows, Linux, and macOS platforms, with a range of software pre-installed.&lt;br&gt;
You can select the appropriate Microsoft-hosted agent pool based on your requirements, and Azure Pipelines will automatically allocate and provision an agent to execute your pipeline jobs.&lt;br&gt;
Microsoft-hosted agents are convenient to use when you don't want to manage the underlying infrastructure or when you need a specific environment readily available.&lt;br&gt;
Both self-hosted agents and Microsoft-hosted agents connect to Azure DevOps and can execute tasks and jobs defined in your pipelines. They communicate with Azure DevOps to receive instructions, download source code, execute tasks, and report back the results.&lt;/p&gt;

&lt;p&gt;Azure agents play a crucial role in enabling the automation and execution of build and release processes in Azure Pipelines, allowing you to build, test, and deploy your applications reliably and efficiently.&lt;/p&gt;

&lt;p&gt;In the context of Azure Pipelines,some of the predefined variables that represent specific directories used during the build or deployment process are as follows;&lt;/p&gt;

&lt;p&gt;$(Agent.HomeDirectory) represents the folder where the agent is installed. This folder contains the code and resources for the agent.&lt;br&gt;
Example: D:\agent&lt;/p&gt;

&lt;p&gt;$(Agent.ReleaseDirectory) represents the directory to which artifacts are downloaded during deployment of a release. The directory is cleared before every deployment if it requires artifacts to be downloaded to the agent.&lt;br&gt;
Example: D:\agent_work\r1\a&lt;/p&gt;

&lt;p&gt;$(Agent.RootDirectory) represent the working directory for this agent, where subfolders are created for every build or release.&lt;br&gt;
Example: D:\agent_work&lt;/p&gt;

&lt;p&gt;$(Agent.WorkFolder) represents the working folder for current agent, $(Agent.WorkFolder)\1 represents the working folder for current pipeline.(Normally the first pipeline will be put in $(Agent.WorkFolder)\1, and the second $(Agent.WorkFolder)\2...)&lt;/p&gt;

&lt;p&gt;So for one pipeline run, it has four folders by default: a(artifact folder), b(binaries folder), s(source folder) and TestResults(Test results folder). The s folder is where the source code files are downloaded. &lt;/p&gt;

&lt;p&gt;In order to save space we should clean up working folder. Azure retention settings is a way to manage our artifacts and working files. Another way is to define a task and make it clean up unnecessary files periodically.&lt;/p&gt;

&lt;p&gt;The task would be as follows;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

steps:
- task: DeleteFiles@1
  displayName: 'Delete files from $(Agent.WorkFolder)'
  inputs:
    SourceFolder: '$(Agent.WorkFolder)'


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

&lt;/div&gt;

&lt;p&gt;And the schedule;&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyv77e4hd0550hhpuc4s.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyv77e4hd0550hhpuc4s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
    </item>
  </channel>
</rss>
