<?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: Maykol Alfaro</title>
    <description>The latest articles on DEV Community by Maykol Alfaro (@maykol_alfaro).</description>
    <link>https://dev.to/maykol_alfaro</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%2F3810669%2F77bc8302-4680-4489-bf31-ce897ae4c3ef.jpg</url>
      <title>DEV Community: Maykol Alfaro</title>
      <link>https://dev.to/maykol_alfaro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maykol_alfaro"/>
    <language>en</language>
    <item>
      <title>Beyond the Query: Mastering AI and Vector Search in SQL Server 2025</title>
      <dc:creator>Maykol Alfaro</dc:creator>
      <pubDate>Tue, 31 Mar 2026 21:28:47 +0000</pubDate>
      <link>https://dev.to/maykol_alfaro/beyond-the-query-mastering-ai-and-vector-search-in-sql-server-2025-4k6j</link>
      <guid>https://dev.to/maykol_alfaro/beyond-the-query-mastering-ai-and-vector-search-in-sql-server-2025-4k6j</guid>
      <description>&lt;p&gt;The new &lt;strong&gt;Microsoft DP-800 SQL AI Developer Associate certification&lt;/strong&gt; is showing a major move: SQL Server is no longer just a relational database, it’s becoming a new tool for &lt;strong&gt;AI-driven applications&lt;/strong&gt; and &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are preparing for the exam or modernizing your stack, here are the three AI pillars you need to take into consideration.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Vector Embeddings
&lt;/h3&gt;

&lt;p&gt;Vector embeddings represent data as coordinates in a multi-dimensional space. This allows SQL Server to perform a &lt;strong&gt;Semantic Search&lt;/strong&gt;, finding data based on meaning rather than just exact keyword matches.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vector Search:&lt;/strong&gt; &lt;code&gt;VECTOR_DISTANCE&lt;/code&gt; compares how similar two items are (e.g., finding a "lightweight backpack" when a user searches for "travel bags").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt; In SQL Server 2025, vectors are stored using the &lt;code&gt;VECTOR&lt;/code&gt; data type, which can handle thousands of dimensions (like the standard 1,536 dimensions used by OpenAI).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Indexing:&lt;/strong&gt; For large datasets (millions of rows), use &lt;strong&gt;DiskANN&lt;/strong&gt; indexes to enable fast, approximate nearest neighbor (ANN) searches without scanning every row.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. External Models
&lt;/h3&gt;

&lt;p&gt;You no longer need to move your data to a separate environment to run an LLM. SQL Server now acts as a kind of orchestrator that can call AI models directly via T-SQL.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CREATE EXTERNAL MODEL&lt;/strong&gt;: This command allows you to define a reusable connection to an AI endpoint (like Azure OpenAI).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI_GENERATE_EMBEDDINGS&lt;/strong&gt;: function to convert text stored in columns into vectors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: Uses &lt;strong&gt;Database Scoped Credentials&lt;/strong&gt; to securely authenticate without hardcoding any credentials in your scripts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Retrieval-Augmented Generation (RAG)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RAG&lt;/strong&gt;  solves the lack of the specific knowledge of LLMs about your private business data by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Retrieving&lt;/strong&gt; relevant chunks of your private data using vector search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Augmenting&lt;/strong&gt; the AI's prompt with this real-world context.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generating&lt;/strong&gt; a response that is grounded in your actual database.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; To keep costs down and performance high, always &lt;strong&gt;chunk&lt;/strong&gt; your data into smaller segments (e.g., 500 characters) before generating embeddings. This ensures you don't hit model token limits and keeps your search results focused.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts for DP-800 Candidates
&lt;/h3&gt;

&lt;p&gt;As you study for this certification exam, focus on these three pillars, where I think this certification will be mainly focused. If you follow Microsoft's documentation's path, &lt;strong&gt;Milestone 3&lt;/strong&gt; is where this magic occurs.&lt;/p&gt;

</description>
      <category>sqlserver</category>
      <category>dp800</category>
      <category>ai</category>
      <category>azure</category>
    </item>
    <item>
      <title>The DLL Hell of Windows Containers: Debugging "Silent" Failures</title>
      <dc:creator>Maykol Alfaro</dc:creator>
      <pubDate>Tue, 24 Mar 2026 23:11:38 +0000</pubDate>
      <link>https://dev.to/maykol_alfaro/the-dll-hell-of-windows-containers-debugging-silent-failures-nnm</link>
      <guid>https://dev.to/maykol_alfaro/the-dll-hell-of-windows-containers-debugging-silent-failures-nnm</guid>
      <description>&lt;p&gt;In our previous posts, we talked about some techniques to dramatically lower your final image size, the experience working with &lt;strong&gt;Windows Containers&lt;/strong&gt;, and why it was the most viable bridge to the cloud when trying to modernize your applications &lt;strong&gt;(.NET Framework)&lt;/strong&gt;. Today, we're moving from the theory of &lt;strong&gt;"Lift and Shift"&lt;/strong&gt; and diving into how to solve the &lt;strong&gt;"it works on my machine"&lt;/strong&gt; nightmare.&lt;/p&gt;

&lt;p&gt;If you've spent any time with &lt;strong&gt;Windows Containers&lt;/strong&gt;, you know how it feels when you run &lt;code&gt;docker build&lt;/code&gt;, it finishes successfully, then you run &lt;code&gt;docker run&lt;/code&gt;, and... nothing. The container exits immediately. No stack trace, no event log, just a &lt;strong&gt;Exit Code 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Debugging these type of errors require moving from the basic &lt;strong&gt;Docker&lt;/strong&gt; commands and diving into the internals of the Windows kernel and subsystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Entrypoint Trap
&lt;/h2&gt;

&lt;p&gt;When a &lt;strong&gt;Windows Container&lt;/strong&gt; crashes on startup, the logs are often lost because the container object is destroyed before the buffer flushes. To fix this, you must hijack the entrypoint.&lt;/p&gt;

&lt;p&gt;Instead of letting your &lt;strong&gt;Dockerfile&lt;/strong&gt; run its &lt;code&gt;ENTRYPOINT&lt;/code&gt;, run it manually:&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;-it&lt;/span&gt; &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; powershell your-image-name:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once inside the &lt;strong&gt;PowerShell&lt;/strong&gt; prompt:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your app directory (e.g., C:\inetpub\wwwroot or C:\app).&lt;/li&gt;
&lt;li&gt;Manually execute your .exe or start the IIS service.&lt;/li&gt;
&lt;li&gt;Monitor the console. Here is where you'll likely see a &lt;strong&gt;"missing DLL"&lt;/strong&gt; or &lt;strong&gt;"access denied"&lt;/strong&gt; error that the &lt;strong&gt;Docker&lt;/strong&gt; daemon was hiding.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Hunting the "Ghost" DLLs and Exceptions
&lt;/h2&gt;

&lt;p&gt;Windows Server Core for example is a "refactored" OS. To keep the size down, Microsoft stripped out UI components, fonts, and specific legacy APIs. If your app or one of its third-party dependencies calls one of these missing APIs, it will crash with a &lt;strong&gt;DllNotFoundException&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Trying to find these types of errors might be overwhelming, but there are some tools you can download and use directly in your &lt;strong&gt;Windows Containers&lt;/strong&gt;. When the &lt;code&gt;docker logs&lt;/code&gt; command is not enough, you can use something like  &lt;a href="https://github.com/microsoft/windows-container-tools/tree/master/LogMonitor" rel="noopener noreferrer"&gt;&lt;strong&gt;Log Monitor&lt;/strong&gt;&lt;/a&gt;, a Microsoft-supported opensource tool that bridges Windows application logs to STDOUT/STDERR. And it's configured via a config file.&lt;/p&gt;

&lt;p&gt;As the Microsoft's documentation says, &lt;strong&gt;Log Monitor&lt;/strong&gt; can either be used in a SHELL usage pattern:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHELL ["C:\\LogMonitor\\LogMonitor.exe", "cmd", "/S", "/C"]
CMD c:\windows\system32\ping.exe -n 20 localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or an ENTRYPOINT usage pattern:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENTRYPOINT C:\LogMonitor\LogMonitor.exe c:\windows\system32\ping.exe -n 20 localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;One tool that also helped me find hidden application specific exceptions was &lt;a href="https://learn.microsoft.com/es-es/sysinternals/downloads/procdump" rel="noopener noreferrer"&gt;&lt;strong&gt;ProcDump&lt;/strong&gt;&lt;/a&gt;. This is a command-line utility from Microsoft Sysinternals designed to monitor applications for CPU spikes, memory spikes, or unhandled exceptions and automatically generate crash dumps &lt;strong&gt;(DMP files)&lt;/strong&gt;.  Later, you can analyze this generated files with other tools such as &lt;a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/windbg-overview" rel="noopener noreferrer"&gt;&lt;strong&gt;WinDbg&lt;/strong&gt;&lt;/a&gt; which offers more modern visuals to see where your application/container is failing.&lt;/p&gt;

&lt;p&gt;There are many other tools that you can use to generate these types of logs and try to find &lt;strong&gt;"Ghost"&lt;/strong&gt; DLLs or exceptions that might be causing your containers failure, but at least these are the tools that helped me troubleshoot these scenarios. And at least all these 3 tools are from Microsoft, in case your company worries about using third-party tools that don't align with their security policies.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Kernel Mismatch (Isolation Modes)
&lt;/h2&gt;

&lt;p&gt;In Linux, the container shares the host kernel. In Windows, the "Kernel" is much more rigid. If your host is Windows 11 and your container is built on &lt;code&gt;ltsc2019&lt;/code&gt;, they speak a slightly different "language."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Symptom:&lt;/strong&gt; You get an error like "The container operating system does not match the host operating system."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix: Strategic Isolation&lt;/strong&gt;&lt;br&gt;
As an engineer, you need to understand the two isolation levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Process Isolation:&lt;/strong&gt; The container shares the host kernel directly. It’s fast and has low overhead, but the versions must match (e.g., Host 2022 -&amp;gt; Container 2022).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyper-V Isolation:&lt;/strong&gt; The container runs inside a tiny, optimized VM. It’s slower to start but allows you to run older containers on newer hosts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Command Tip:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For local development try to force Hyper-V isolation, that way you can test your &lt;strong&gt;Windows Containers&lt;/strong&gt; on different OS versions and don't worry about these kernel mismatches.&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;--isolation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hyperv your-image-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The "Invisible Text" Mystery
&lt;/h2&gt;

&lt;p&gt;One of the most common issues you'll get after a "successful" deployment is:  &lt;em&gt;"The app runs, the PDF generates, but all the text is missing or replaced by weird squares (▯▯▯)."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This happens because in Windows Server Core Microsoft removed nearly every font you take for granted to reduce its size. If your &lt;strong&gt;.NET Framework&lt;/strong&gt; code asks for "Arial" and it's not there, GDI+ won't always tell you, it will just fail silently or fall back to a font that doesn't support your character set.&lt;/p&gt;

&lt;p&gt;On a desktop, you just drag a &lt;code&gt;.ttf&lt;/code&gt; into &lt;code&gt;C:\Windows\Fonts&lt;/code&gt;. In a container, that does &lt;strong&gt;nothing&lt;/strong&gt;. You can't just &lt;code&gt;COPY&lt;/code&gt; the files; you have to &lt;strong&gt;register&lt;/strong&gt; them in the Windows Registry so the GDI+ engine knows they exist.&lt;/p&gt;

&lt;p&gt;To solve this, we had to modify our &lt;strong&gt;Dockerfile&lt;/strong&gt; to copy the missing fonts and register them in the Windows Registry.&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;# Step 1: Copy your fonts into a temporary folder&lt;/span&gt;
 COPY ./my-fonts/ /fonts/  
 # Step 2: Register each font in the registry
 RUN powershell -Command \  
    $fontPath  =  'C:\fonts'; \
    $registryPath  =  'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts'; \ 
    Get-ChildItem -Path  $fontPath  -Filter *.ttf | ForEach-Object { \  
        $fontName  =  $_.BaseName; \ 
        Copy-Item  $_.FullName -Destination  'C:\Windows\Fonts'; \ 
        New-ItemProperty -Path  $registryPath  -Name  $fontName  -Value  $_.Name -PropertyType String -Force \
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Nobody told us dealing with &lt;strong&gt;Windows Containers&lt;/strong&gt; was going to be a bit frustrating sometimes, but not imposible. At that point we didn't know what else we could do to monitor/debug our containers trying to find these errors. Just to finally see a &lt;strong&gt;"missing DLL"&lt;/strong&gt; or just a &lt;strong&gt;"missing font"&lt;/strong&gt; error. And &lt;strong&gt;"tutorials"&lt;/strong&gt; or these guides on the internet to help you start with &lt;strong&gt;Windows Containers&lt;/strong&gt; don't talk about these nuances, that's why I decided to start writing this series and help some people out there dealing with these types of issues and if you're starting, at least let you know what you will/can encounter during your containerization process.&lt;/p&gt;

</description>
      <category>containers</category>
      <category>docker</category>
      <category>microservices</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>The Size Paradox: 4 Techniques to Slim Down Windows Container Images</title>
      <dc:creator>Maykol Alfaro</dc:creator>
      <pubDate>Wed, 18 Mar 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/maykol_alfaro/the-size-paradox-4-techniques-to-slim-down-windows-container-images-4p10</link>
      <guid>https://dev.to/maykol_alfaro/the-size-paradox-4-techniques-to-slim-down-windows-container-images-4p10</guid>
      <description>&lt;p&gt;In our previous post, we discussed  my experience working with Windows Containers, and why it was the most viable bridge to the cloud when trying to modernize your applications &lt;strong&gt;(.NET Framework)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sometimes, in a world where Linux images are measured in megabytes, seeing a Windows build log report a 5GB image can be a bit shocking. For us, as software engineers, image size isn't just about disk space, it’s about &lt;strong&gt;deployment velocity&lt;/strong&gt;. A 5GB image means slower cold starts in Kubernetes, longer &lt;strong&gt;CI/CD&lt;/strong&gt; wait times, and higher egress costs. Here is how we managed to lower those numbers down by modifying our &lt;strong&gt;Dockerfiles&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Base Image
&lt;/h2&gt;

&lt;p&gt;One of the most important decisions is made in the very first line of the &lt;strong&gt;Dockerfile&lt;/strong&gt;. Microsoft provides four primary images, and choosing the wrong one can cost you up to 4GB before you even add your code &lt;strong&gt;(Yes, that's true)&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Base Image&lt;/th&gt;
&lt;th&gt;Typical Size&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nano Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~100MB&lt;/td&gt;
&lt;td&gt;The "Alpine" equivalent of Windows. Built for the newest .NET versions (.NET 6+). No PowerShell, no WMI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Server Core&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~1.5GB - 2GB&lt;/td&gt;
&lt;td&gt;This is the best suite for .NET Framework 4.8. No GUI, but supports the full .NET stack and PowerShell.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5GB+&lt;/td&gt;
&lt;td&gt;This is the largest image and has full Windows API support for workloads.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3GB+&lt;/td&gt;
&lt;td&gt;It also provides the full Windows API support and allows you to use more server features. Use only if you have a strong dependency on any Windows specific feature such as GDI+ or specialized fonts.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;Always pin your version to the host OS LTSC (Long-Term Servicing Channel). For example, if your production nodes run Windows Server 2025, your &lt;code&gt;FROM&lt;/code&gt; should be &lt;code&gt;ltsc2025&lt;/code&gt;. Also, if your application for some reason has a strong dependency on a specific cumulative update you can also specify this in your &lt;code&gt;FROM&lt;/code&gt; statement, so it should be like &lt;code&gt;ltsc2025-KB5075899&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-Stage Builds
&lt;/h2&gt;

&lt;p&gt;If you are building a &lt;strong&gt;.NET Framework&lt;/strong&gt; app, the SDK image (which includes MSBuild, NuGet, and compilers) is massive, often over 5GB. You must separate your build environment from your runtime environment. This can dramatically reduce the final image size.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# STAGE 1: The Builder
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS builder
WORKDIR /src
COPY . .
RUN nuget restore
RUN msbuild /p:Configuration=Release /p:OutputPath=/app/out

# STAGE 2: The Runtime
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2025
WORKDIR /inetpub/wwwroot

# We only take the binaries. Everything else (SDK, caches, source) is discarded.
COPY --from=builder /app/out/_PublishedWebsites/MyLegacyApp .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Layer "Squashing" and Atomic Commands
&lt;/h2&gt;

&lt;p&gt;When you add a &lt;code&gt;RUN&lt;/code&gt; command in your &lt;strong&gt;Dockerfile&lt;/strong&gt;, it creates a new filesystem layer. In Windows, these layers are significantly heavier than in Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The common mistake:&lt;/strong&gt; Let's say you're running &lt;code&gt;RUN powershell Expand-Archive app.zip&lt;/code&gt; and then &lt;code&gt;RUN powershell Remove-Item app.zip&lt;/code&gt;. The ZIP file is still taking up space from the previous layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Use atomic commands. Download, unzip, install, and cleanup in one single layer. That way you're freeing some space and you won't end up with a huge image at the end of the process.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Optimized Layering
RUN powershell -Command \
    $ProgressPreference = 'SilentlyContinue'; \
    Invoke-WebRequest -Uri https://example.com/installer.msi -OutFile installer.msi; \
    Start-Process msiexec.exe -ArgumentList '/i', 'installer.msi', '/quiet', '/norestart' -NoNewWindow -Wait; \
    Remove-Item installer.msi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Mastering the .dockerignore
&lt;/h2&gt;

&lt;p&gt;These &lt;strong&gt;.NET Framework&lt;/strong&gt; projects are known for their "hidden" folders. Visual Studio creates &lt;strong&gt;bin/&lt;/strong&gt;, &lt;strong&gt;obj/&lt;/strong&gt;, &lt;strong&gt;.vs/&lt;/strong&gt;, and &lt;strong&gt;packages/&lt;/strong&gt; folders that can easily add several hundred MBs to your build context.&lt;/p&gt;

&lt;p&gt;If your build context is huge, your docker build command will hang for minutes just "Sending build context to Docker daemon." &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to solve this:&lt;/strong&gt; Create a &lt;strong&gt;.dockerignore&lt;/strong&gt; file and exclude everything except your source code. This is similar to how a &lt;strong&gt;.gitignore&lt;/strong&gt; file works.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .dockerignore
**/.git
**/.vs
**/bin
**/obj
**/packages
*.user
*.suo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I know there might be more ways to optimize your &lt;strong&gt;Dockerfiles&lt;/strong&gt; or your docker builds. In this section I just provided the most common use cases I faced during my "Lift-and-Shift" strategy working with this decade-old &lt;strong&gt;.NET Framework&lt;/strong&gt; application, and how we approached them to successfully become the bridge we needed to get into the cloud.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Optimizing Windows images isn't just a nice-to-have feature, it’s what separates a hobbyist project from a production-ready enterprise system. By mastering multi-stage builds and atomic layer cleanup, we can turn a 10GB legacy monolithic application into a 2GB container that scales efficiently.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>dotnet</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Windows Containers: Navigating the Path from Monolith to Cloud-Native</title>
      <dc:creator>Maykol Alfaro</dc:creator>
      <pubDate>Wed, 11 Mar 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/maykol_alfaro/windows-containers-navigating-the-path-from-monolith-to-cloud-native-15fk</link>
      <guid>https://dev.to/maykol_alfaro/windows-containers-navigating-the-path-from-monolith-to-cloud-native-15fk</guid>
      <description>&lt;p&gt;A couple of years ago, I was assigned to a project where I was in charge of containerizing a decade-old web application developed on &lt;strong&gt;.NET Framework 4.8&lt;/strong&gt;. At first, this might seem like a good candidate for migration to a newer version such as &lt;strong&gt;.NET 8&lt;/strong&gt; (the latest version at that moment). But if you've ever been tasked with modernizing this type of application, you've likely hit the &lt;strong&gt;"Rewrite vs. Lift-and-Shift"&lt;/strong&gt; crossroads. &lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Windows Containers&lt;/strong&gt; come in. I know they aren't the coolest choice, but they are often the most viable bridge to the cloud when you're trying to modernize your applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The "Why": Pragmatism Over Purity&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I've been a &lt;strong&gt;software engineer&lt;/strong&gt; for over 8 years, and something I've learned is that a full rewrite to a newer version isn't always feasible. Business requirements, tight deadlines, and complex dependencies often make a &lt;strong&gt;“Lift and Shift”&lt;/strong&gt; strategy the only viable path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows Containers&lt;/strong&gt; allow you to wrap that &lt;strong&gt;.NET Framework 4.8&lt;/strong&gt; monolith in a portable, versioned environment, with minimal changes to the legacy code. You get the benefits of &lt;strong&gt;CI/CD&lt;/strong&gt; and orchestration (like Azure Kubernetes Service) while keeping the application logic exactly as it is.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Reality Check: This Isn't Linux&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before you run &lt;code&gt;docker build&lt;/code&gt;, you need to get away from the Linux mindset. Here is what I’ve learned:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Size Paradox&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Linux, a large image is 500MB. In Windows, a small &lt;strong&gt;Server Core&lt;/strong&gt; image starts at &lt;strong&gt;2GB to 5GB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here, you have to prioritize &lt;strong&gt;layer caching&lt;/strong&gt;. If you don't structure your &lt;strong&gt;Dockerfile&lt;/strong&gt; correctly, your &lt;strong&gt;CI/CD&lt;/strong&gt; pipeline will spend 20 minutes just pulling base layers (Don't worry, I've also been there before).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Isolation Modes: Your New Best Friend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows Containers&lt;/strong&gt; run in two modes: &lt;strong&gt;Process Isolation and Hyper-V Isolation.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Process Isolation&lt;/strong&gt; shares the host kernel (blazing fast, but the host and container OS versions must match exactly).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hyper-V Isolation&lt;/strong&gt; runs the container in a highly optimized VM (slower, but allows you to run an older container on a newer host).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The "Silent" Failures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows Containers&lt;/strong&gt; often fail without clear errors if a specific Windows Feature (like GDI+ or specialized fonts) is missing from the base image. Debugging usually requires you to open a &lt;strong&gt;PowerShell&lt;/strong&gt; session just to realize a DLL is missing from your container.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Strategy: How to Approach Your First Build&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When you start writing your &lt;strong&gt;Dockerfile&lt;/strong&gt;, don't just aim for "it works." Aim for maintainability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Multi-Stage Builds:&lt;/strong&gt; Compile your code in a "heavy" SDK image, then copy only the binaries into a "slim" runtime image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Master the .dockerignore:&lt;/strong&gt; Windows projects are notorious for bloated bin and obj folders. Don't let them sneak into your image layers, or you'll pay for it in larger image layers and slower builds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Forward Slashes are King:&lt;/strong&gt; Even though you’re in a Windows environment, use "/" in your &lt;strong&gt;Dockerfiles&lt;/strong&gt;. It’s cleaner, easier to read, and avoids the "escape character" mess of backslashes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't worry, I know this is just a general overview of my personal experience with &lt;strong&gt;Windows Containers&lt;/strong&gt;, and it doesn't dive into deep specifics. But in the next posts of this series we will discuss how to take advantage of &lt;strong&gt;Windows Containers&lt;/strong&gt; and their ecosystem to architect successful applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Windows Containers&lt;/strong&gt; are a bridge to modern cloud applications, but they shouldn't be the final destination. They are a great tool for engineers who need to solve real-world business problems today while preparing for the microservices of tomorrow. They come with challenges and a significant learning curve, but once you master how the isolation modes work and how to manage image layering, you’ve unlocked a massive advantage for your organization and your professional experience.&lt;/p&gt;

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