<?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: Sitota Alemu</title>
    <description>The latest articles on Forem by Sitota Alemu (@uwancha).</description>
    <link>https://forem.com/uwancha</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%2F1133489%2F242703ff-9b06-42ce-a6a4-c2c460018798.jpeg</url>
      <title>Forem: Sitota Alemu</title>
      <link>https://forem.com/uwancha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/uwancha"/>
    <language>en</language>
    <item>
      <title>Using dev-notify-bridge to Get Desktop Notifications from Docker or Remote Environments</title>
      <dc:creator>Sitota Alemu</dc:creator>
      <pubDate>Mon, 13 Oct 2025 12:08:57 +0000</pubDate>
      <link>https://forem.com/uwancha/using-dev-notify-bridge-to-get-desktop-notifications-from-docker-or-remote-environments-a3a</link>
      <guid>https://forem.com/uwancha/using-dev-notify-bridge-to-get-desktop-notifications-from-docker-or-remote-environments-a3a</guid>
      <description>&lt;p&gt;Using dev-notify-bridge to Get Desktop Notifications from Docker, WSL, or Remote Environments&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instantly see OTPs, build results, and app notifications — even from inside Docker or WSL.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When running Node.js apps in Docker, WSL, or remote environments, desktop notifications simply don’t work. Your app can’t access the host system’s notification center — meaning no popups for build completions, test results, or verification codes.&lt;/p&gt;

&lt;p&gt;This is especially frustrating during &lt;strong&gt;local authentication testing&lt;/strong&gt;, when you need to check &lt;strong&gt;OTPs or verification codes&lt;/strong&gt; sent by their app. Instead of instantly seeing the code, you often switch between tools like Mailtrap or database viewers — an unnecessary delay that breaks development flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/dev-notify-bridge?activeTab=readme#docker-integration-examples" rel="noopener noreferrer"&gt;dev-notify-bridge&lt;/a&gt;&lt;/strong&gt; solves this problem by acting as a local HTTP listener on your host machine. Any containerized or remote app can send a POST request to it, and the bridge instantly triggers a &lt;strong&gt;native desktop notification&lt;/strong&gt; on your computer.&lt;/p&gt;

&lt;p&gt;It’s lightweight, cross-platform, and designed purely for &lt;strong&gt;local development&lt;/strong&gt;, making it perfect for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OTP and verification code previews&lt;/li&gt;
&lt;li&gt;Build complete or test result notifications&lt;/li&gt;
&lt;li&gt;Background job or deployment status updates&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Install globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; dev-notify-bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or just run it on the fly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx dev-notify-bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, it listens on port &lt;code&gt;6789&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Run the bridge
&lt;/h2&gt;

&lt;p&gt;Start the bridge on your host machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx dev-notify-bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To change the port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx dev-notify-bridge &lt;span class="nt"&gt;--port&lt;/span&gt; 5454
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see a message like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [ dev-notify-bridge ] running at http://localhost:5454
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means it’s ready to receive notification requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sending notifications from a container or remote app
&lt;/h2&gt;

&lt;p&gt;Once the bridge is running locally, your Docker container or remote service can send a POST request to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  When using a &lt;strong&gt;single container&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re running your app using &lt;code&gt;docker run&lt;/code&gt;, add the following flag so your container can reach the host machine:&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="nt"&gt;--add-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host.docker.internal:host-gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then send a POST request from inside your container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://host.docker.internal:5454/notify &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"title": "Build Complete", "message": "Your backend is ready", "sound": true}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should instantly see a desktop notification pop up.&lt;/p&gt;




&lt;h3&gt;
  
  
  When using &lt;strong&gt;Docker Compose&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re running multiple services through &lt;code&gt;docker-compose&lt;/code&gt;, make sure each service that needs to send notifications includes an &lt;code&gt;extra_hosts&lt;/code&gt; entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;extra_hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host.docker.internal:host-gateway"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the container can resolve &lt;code&gt;host.docker.internal&lt;/code&gt; correctly, especially on &lt;strong&gt;Linux&lt;/strong&gt; systems.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;macOS&lt;/strong&gt; and &lt;strong&gt;Windows&lt;/strong&gt;, Docker Desktop already provides &lt;code&gt;host.docker.internal&lt;/code&gt; by default,&lt;br&gt;
but keeping this config ensures your setup stays portable across all platforms.&lt;/p&gt;

&lt;p&gt;So whether your team is using Linux, macOS, or Windows — notifications will just work.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example with JavaScript
&lt;/h2&gt;

&lt;p&gt;Here’s how you can trigger a notification from your app code:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://host.docker.internal:5454/notify&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server Started&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API is running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sound&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common issues
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No notification appears&lt;/strong&gt;&lt;br&gt;
Check that notifications are enabled on your system and that you’re not in “Do Not Disturb” mode.&lt;br&gt;
On Linux, make sure the &lt;code&gt;notify-send&lt;/code&gt; utility is installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS not resolving (Linux users)&lt;/strong&gt;&lt;br&gt;
If you get &lt;code&gt;ENOTFOUND host.docker.internal&lt;/code&gt;, add the flag&lt;br&gt;
&lt;code&gt;--add-host=host.docker.internal:host-gateway&lt;/code&gt; (for single containers)&lt;br&gt;
or use the &lt;code&gt;extra_hosts&lt;/code&gt; section (for Docker Compose).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port already in use&lt;/strong&gt;&lt;br&gt;
You can change the port using &lt;code&gt;--port&lt;/code&gt;, e.g. &lt;code&gt;npx dev-notify-bridge --port 6000&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why use it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/dev-notify-bridge?activeTab=readme#docker-integration-examples" rel="noopener noreferrer"&gt;dev-notify-bridge&lt;/a&gt; exists to make your development flow smoother.&lt;br&gt;
No need to tail logs or wait for builds — get instant, native desktop notifications from apps running anywhere, even in isolated environments.&lt;/p&gt;

&lt;p&gt;It’s tiny, fast, cross-platform, and takes just one command to start.&lt;/p&gt;


&lt;h2&gt;
  
  
  Quick Docker Setup Examples
&lt;/h2&gt;

&lt;p&gt;Below are minimal examples to get you started, whether you’re using a single container or a multi-service setup.&lt;/p&gt;
&lt;h3&gt;
  
  
  Single Container (e.g. development API)
&lt;/h3&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;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--add-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host.docker.internal:host-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;development &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="se"&gt;\&lt;/span&gt;
  my-api-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, inside your app:&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://host.docker.internal:5454/notify&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Build Complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API container is up&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Multi-Service (docker-compose.yml)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.9'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/usr/src/app&lt;/span&gt;
    &lt;span class="na"&gt;extra_hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host.docker.internal:host-gateway"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;development&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your services are running, any container can send notifications to the bridge running on your host system.&lt;/p&gt;




&lt;p&gt;That’s all it takes.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;dev-notify-bridge&lt;/code&gt; once on your host machine, and your Docker or remote apps can instantly trigger native desktop notifications — no extra setup, no manual checking.&lt;/p&gt;

&lt;p&gt;No more switching to Mailtrap or database tools just to read an OTP.&lt;br&gt;
No more tailing logs to see if a build finished.&lt;br&gt;
Just instant feedback, right where you need it — on your desktop.&lt;/p&gt;

&lt;p&gt;It’s small, fast, and made to keep developers in flow, even when code runs in isolated environments.&lt;/p&gt;




</description>
      <category>tooling</category>
      <category>node</category>
      <category>productivity</category>
      <category>docker</category>
    </item>
    <item>
      <title>The Right Way to Handle 404s in Angular SPAs with Nginx</title>
      <dc:creator>Sitota Alemu</dc:creator>
      <pubDate>Thu, 09 Oct 2025 19:39:46 +0000</pubDate>
      <link>https://forem.com/uwancha/the-right-way-to-handle-404s-in-angular-spas-with-nginx-10cd</link>
      <guid>https://forem.com/uwancha/the-right-way-to-handle-404s-in-angular-spas-with-nginx-10cd</guid>
      <description>&lt;p&gt;Modern Angular and other single-page applications (SPAs) often break one of the web’s oldest conventions — returning the correct HTTP status code.&lt;/p&gt;

&lt;p&gt;When every route, valid or not, serves index.html, even a nonexistent page returns 200 OK.&lt;/p&gt;

&lt;p&gt;This confuses search engines and creates “soft 404” issues that hurt your site’s SEO.&lt;/p&gt;

&lt;p&gt;This article walks through how to correctly configure &lt;strong&gt;Nginx&lt;/strong&gt; to serve Angular SPAs with real &lt;strong&gt;404 responses&lt;/strong&gt;, without breaking client-side routing.&lt;/p&gt;

&lt;p&gt;You’ll learn how to map valid routes, handle unknown paths gracefully, and still show Angular’s 404 component — all while keeping accurate HTTP responses for crawlers and analytics tools.&lt;/p&gt;

&lt;p&gt;By the end, you’ll have a clean, production-ready setup where &lt;code&gt;/nonexistent&lt;/code&gt; returns a true &lt;strong&gt;404 Not Found&lt;/strong&gt;, and Angular displays its own custom 404 view.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;By default, SPAs rely on client-side routing.&lt;br&gt;
That means the web server always serves &lt;code&gt;index.html&lt;/code&gt;, regardless of the URL.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; → Home page ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/about&lt;/code&gt; → About page ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/random-nonexistent-page&lt;/code&gt; → Angular’s 404 component ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works fine for users, but there’s a hidden issue — &lt;strong&gt;the HTTP response is always 200 OK&lt;/strong&gt;, even for routes that don’t exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /random-nonexistent-page
&lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search engines interpret this as a &lt;strong&gt;soft 404&lt;/strong&gt;, meaning the page doesn’t exist but the server claims it does.&lt;br&gt;
This can confuse crawlers, waste crawl budget, and reduce your site’s ranking quality.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;We want Nginx to handle SPAs correctly by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serving Angular normally for valid routes with &lt;strong&gt;HTTP 200&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Returning &lt;strong&gt;HTTP 404&lt;/strong&gt; for invalid routes, while still showing Angular’s 404 component.&lt;/li&gt;
&lt;li&gt;Keeping static assets and caching behavior unchanged.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Step 1: Define Valid Routes in Nginx
&lt;/h2&gt;

&lt;p&gt;We can define which routes are valid using Nginx’s &lt;code&gt;map&lt;/code&gt; directive.&lt;br&gt;
This creates a variable that indicates whether a request path is known or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;map&lt;/span&gt; &lt;span class="nv"&gt;$request_uri&lt;/span&gt; &lt;span class="nv"&gt;$is_valid_route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;default&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;/products&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;/profile&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;~^/orders/[0-9]+&lt;/span&gt;$ &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Dynamic route&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; → valid route (serve SPA and return 200)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; → invalid route (return 404)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time you add a new route to Angular, update this list to match.&lt;br&gt;
For dynamic routes, you can use regular expressions.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 2: Use &lt;code&gt;$is_valid_route&lt;/code&gt; in the Main Location Block
&lt;/h2&gt;

&lt;p&gt;Next, we use that variable to control how requests are handled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$is_valid_route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.html&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;This tells Nginx:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the route isn’t valid, return 404 immediately.&lt;/li&gt;
&lt;li&gt;Otherwise, serve the requested file or fall back to &lt;code&gt;index.html&lt;/code&gt; for Angular routing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that only valid routes return &lt;code&gt;200 OK&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Serve Angular’s 404 Component with a Real 404 Status
&lt;/h2&gt;

&lt;p&gt;The challenge is that we don’t want to show Nginx’s default “Not Found” page.&lt;br&gt;
We still want Angular’s 404 component to appear — but &lt;strong&gt;the HTTP response must stay 404&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To do this, use the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;error_page&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="n"&gt;/index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/index.html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/usr/share/nginx/html/customer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;expires&lt;/span&gt; &lt;span class="s"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Pragma&lt;/span&gt; &lt;span class="s"&gt;"no-cache"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Cache-Control&lt;/span&gt; &lt;span class="s"&gt;"no-store,&lt;/span&gt; &lt;span class="s"&gt;no-cache,&lt;/span&gt; &lt;span class="s"&gt;must-revalidate"&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;Here’s what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When Nginx encounters a 404, it internally rewrites the request to &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Angular bootstraps as usual and uses the current URL to decide which route to show.&lt;/li&gt;
&lt;li&gt;The server response remains &lt;strong&gt;HTTP 404&lt;/strong&gt;, not 200. This is the key: Angular still renders the 404 page, but Nginx reports the truth.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This way, users see your app’s 404 view, and crawlers see the correct status code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: The Final Result
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;HTTP Status&lt;/th&gt;
&lt;th&gt;Angular View&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Home&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/products&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Products&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/orders/123&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Order details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/nonexistent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Angular 404 page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The routing experience remains seamless for users, and your SEO health stays intact.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Practical Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always update the Nginx route map when you introduce new Angular routes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use regex for dynamic paths (e.g., &lt;code&gt;/orders/:id&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test responses locally before deploying:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost/nonexistent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  HTTP/1.1 404 Not Found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Confirm that your app’s 404 component is configured for Angular’s wildcard route (&lt;code&gt;path: '**'&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This setup provides a clean balance between &lt;strong&gt;user experience and technical correctness&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accurate HTTP responses for crawlers and analytics&lt;/li&gt;
&lt;li&gt;Consistent routing behavior for users&lt;/li&gt;
&lt;li&gt;Full control over caching and assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With $is_valid_route and error_page 404 /index.html, your Angular SPA stays SEO-friendly, predictable, and production-ready — all without the complexity of SSR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have you handled SPA 404s differently?
&lt;/h2&gt;

&lt;p&gt;Share your setup or tweaks in the comments — I’d love to compare notes!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>nginx</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Understanding Asynchronous I/O Operations in Node.js</title>
      <dc:creator>Sitota Alemu</dc:creator>
      <pubDate>Mon, 27 Jan 2025 11:22:52 +0000</pubDate>
      <link>https://forem.com/uwancha/understanding-asynchronous-io-operations-in-nodejs-15p4</link>
      <guid>https://forem.com/uwancha/understanding-asynchronous-io-operations-in-nodejs-15p4</guid>
      <description>&lt;p&gt;Understanding how Node.js handles asynchronous I/O operations is vital for anyone interested in building applications with Node.js. Often, this concept is raised in interviews. So, in this post, I’ll be sharing an overview of how Node.js handles asynchronous tasks.&lt;br&gt;
Before reading this post, it’s assumed that you have a basic understanding of event loops and other fundamental Node.js concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview of Asynchronous I/O Process&lt;/strong&gt;&lt;br&gt;
      &lt;em&gt;Asynchronous Function ➔ Call Stack ➔ Delegating I/O to &lt;br&gt;
       System APIs ➔ Callback Queue ➔ Event Loop ➔ Call Stack&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When asynchronous code is encountered (e.g., fetching data from a database, reading files, etc.), the call stack, event loop, and Node.js’s underlying APIs (like &lt;a href="https://libuv.org/" rel="noopener noreferrer"&gt;Libuv&lt;/a&gt; ) work together to handle it. The process involves delegating the asynchronous task to the appropriate background thread or system API. Let’s explore this in detail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's a Breakdown&lt;/strong&gt;&lt;br&gt;
    &lt;strong&gt;1. Asynchronous Function Call&lt;/strong&gt; When an asynchronous function (e.g., a database query) is called, it is pushed onto the call stack like any other function.&lt;br&gt;
    &lt;strong&gt;2. Delegation to Background APIs&lt;/strong&gt; If the function involves I/O (e.g., querying a database, reading a file, or making a network request), Node.js delegates this task to the appropriate system-level API or thread in the background (e.g., Libuv thread pool or database driver). The function is immediately popped off the call stack once the task is delegated, allowing the stack to continue processing other code.&lt;br&gt;
    &lt;strong&gt;3. Background Processing&lt;/strong&gt; The actual I/O operation (e.g., querying the database) happens in the background. This is managed outside the JavaScript runtime by the underlying Libuv library, which handles threads and system resources.&lt;br&gt;
    &lt;strong&gt;4. Callback Queuing&lt;/strong&gt; Once the asynchronous task completes (e.g., the database query finishes), the result is passed to the callback associated with the operation. The callback is placed into an appropriate queue (e.g., the I/O callback queue) for the event loop to process.&lt;br&gt;
    &lt;strong&gt;5. Event Loop Execution&lt;/strong&gt; The event loop continuously checks if the call stack is empty. If it is, it takes the next task from the queue (i.e., the callback) and pushes it onto the call stack for execution.&lt;/p&gt;

&lt;p&gt;In a nutshell, an asynchronous I/O operation can be summarized in the following steps:&lt;br&gt;
    &lt;strong&gt;1.&lt;/strong&gt; Asynchronous Function Call:&lt;br&gt;
        ◦ When an asynchronous function (e.g., a database query) is called, it is pushed onto the call stack like any other function.&lt;br&gt;
    &lt;strong&gt;2.&lt;/strong&gt; Delegation to Background APIs:&lt;br&gt;
        ◦ Since the function involves I/O (e.g., querying a database, reading a file, or making a network request), Node.js delegates this task to the appropriate system-level API or thread in the background (e.g., Libuv thread pool or database driver).&lt;br&gt;
        ◦ The function is immediately popped off the call stack once the task is delegated, allowing the stack to continue processing other code.&lt;br&gt;
    &lt;strong&gt;3.&lt;/strong&gt; Background Processing:&lt;br&gt;
        ◦ The actual I/O operation happens in the background, managed by Libuv or other underlying libraries.&lt;br&gt;
    &lt;strong&gt;4.&lt;/strong&gt; Callback Queuing:&lt;br&gt;
        ◦ Once the asynchronous task completes, the callback is placed into the appropriate queue for the event loop to process.&lt;br&gt;
    &lt;strong&gt;5.&lt;/strong&gt; Event Loop Execution:&lt;br&gt;
        ◦ The event loop checks if the call stack is empty. If it is, it picks the next callback from the queue and pushes it onto the call stack for execution.&lt;/p&gt;

&lt;p&gt;Thanks for reading! I’ll be writing about the event loop and its phases in an upcoming post. If you have any thoughts, questions, or feedback, don’t hesitate to leave them in the comments. I’d love to hear from you!&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>eventloops</category>
      <category>asynchronous</category>
    </item>
    <item>
      <title>What the Heck is Docker?</title>
      <dc:creator>Sitota Alemu</dc:creator>
      <pubDate>Mon, 02 Dec 2024 08:26:12 +0000</pubDate>
      <link>https://forem.com/uwancha/what-the-heck-is-docker-4b2l</link>
      <guid>https://forem.com/uwancha/what-the-heck-is-docker-4b2l</guid>
      <description>&lt;p&gt;"What's Docker? What's a container? What's an image? Bla bla bla..." These are the questions my colleagues always ask me when they start learning Docker. And, to be honest, I asked the same questions when I was first introduced to it.&lt;/p&gt;

&lt;p&gt;But you know what? Answers like, "Docker is a platform where..." didn’t really satisfy me. Sure, those answers are correct, but they didn't help me &lt;strong&gt;understand&lt;/strong&gt; Docker. I had deeper questions like:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why should I use Docker?
&lt;/li&gt;
&lt;li&gt;What’s containerization exactly?
&lt;/li&gt;
&lt;li&gt;How is it different from virtualization?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re like me, these are the questions that matter. So, let’s break it down together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is "What’s Docker?" the Right Question?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, it’s a valid question. But here’s the catch: the answer to "What’s Docker?" is just the tip of the iceberg. If you ask someone this, they’ll probably say:&lt;br&gt;&lt;br&gt;
  "Docker is a platform for developing, shipping, and running applications in containers."  &lt;/p&gt;

&lt;p&gt;Cool, but... what does that even mean?&lt;br&gt;&lt;br&gt;
To really understand Docker, you need to ask a better question: &lt;em&gt;&lt;strong&gt;"What is containerization?"&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s Containerization?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Here’s a textbook definition:&lt;br&gt;&lt;br&gt;
  "Containerization is the process of packaging an application, along with its dependencies (libraries, configuration files, and binaries), into a lightweight, portable, and consistent unit called a container." &lt;/p&gt;

&lt;p&gt;Sounds fancy, right? But does it really help you &lt;em&gt;visualize&lt;/em&gt; what containerization is? Probably not. Let’s dig deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concepts You Need to Know to Understand Containerization&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Before approaching containerization, you need to understand some core concepts. Without these, Docker and containers might feel like magic. Here’s what you should explore first:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Software Deployment Process&lt;/strong&gt;
Think about how applications are traditionally deployed. In the "pre-container" world:

&lt;ul&gt;
&lt;li&gt;You write code on your local machine.
&lt;/li&gt;
&lt;li&gt;Then, you configure it to work on a server.
&lt;/li&gt;
&lt;li&gt;But wait! The server needs specific versions of libraries, dependencies, and tools to run your app.
&lt;/li&gt;
&lt;li&gt;Uh-oh, it works on your local machine but crashes in production because the environments aren’t identical.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the classic "It works on my machine!" problem. Containerization solves this by ensuring that your application &lt;em&gt;and&lt;/em&gt; its dependencies are bundled into a single, portable unit (the container) that can run anywhere.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Virtualization&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To understand containers, you need to understand how virtualization works:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Machines (VMs)&lt;/strong&gt;: These are like mini-computers running inside your actual computer. They emulate an entire operating system (OS) and are great for isolating applications.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers&lt;/strong&gt;: Unlike VMs, containers don’t emulate an entire OS. Instead, they share the host OS's kernel while isolating your application and its dependencies. This makes containers much lighter and faster than VMs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Containerization&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Now that you understand virtualization( of course just a tip of it, dig deep into it for more understanding), you can appreciate what containerization does:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It isolates your application, just like a VM.
&lt;/li&gt;
&lt;li&gt;It’s lightweight and portable, unlike a VM.
&lt;/li&gt;
&lt;li&gt;It ensures consistency across development, staging, and production environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How Docker Fits Into the Picture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker is the tool that makes containerization easy. It provides:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A way to &lt;strong&gt;create containers&lt;/strong&gt; (using Docker images).
&lt;/li&gt;
&lt;li&gt;A way to &lt;strong&gt;share containers&lt;/strong&gt; (via Docker Hub or private registries).
&lt;/li&gt;
&lt;li&gt;A way to &lt;strong&gt;run containers&lt;/strong&gt; (on your local machine, servers, or even in the cloud).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in simple terms: Docker makes containerization accessible to everyone.&lt;/p&gt;

&lt;p&gt;If you want to understand Docker, start by understanding containerization. And if you want to understand containerization, take some time to learn about software deployment and virtualization first. Once you’ve got the basics down, Docker (and all its buzzwords like "containers" and "images") will start to make sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources that helped me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I couldn't remember all the resources that helped me, but here are some of them(None of the links are affiliated):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A course on Edx: &lt;a href="https://www.edx.org/learn/kubernetes/ibm-introduction-to-containers-kubernetes-and-openshift?index=product&amp;amp;queryID=677efdb67e58c70ba4833ffbdcb24236&amp;amp;position=2&amp;amp;results_level=first-level-results&amp;amp;term=docker&amp;amp;objectID=course-45e714ff-881f-4f74-85c3-b2e63e2df20b&amp;amp;campaign=Introduction+to+Containers%2C+Kubernetes+and+OpenShift&amp;amp;source=edX&amp;amp;product_category=course&amp;amp;placement_url=https%3A%2F%2Fwww.edx.org%2Fsearch" rel="noopener noreferrer"&gt;Introduction to containers, Kubernets and OpenShift&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fireship (YouTube) - &lt;a href="https://youtu.be/rIrNIzy6U_g?si=_KkQPgQ2CgqKFg7N" rel="noopener noreferrer"&gt;Docker 101&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
      <category>containerapps</category>
    </item>
    <item>
      <title>Next.js with Docker setup error fixed</title>
      <dc:creator>Sitota Alemu</dc:creator>
      <pubDate>Mon, 07 Oct 2024 06:34:01 +0000</pubDate>
      <link>https://forem.com/uwancha/nextjs-with-docker-setup-error-fixed-2b3j</link>
      <guid>https://forem.com/uwancha/nextjs-with-docker-setup-error-fixed-2b3j</guid>
      <description>&lt;h2&gt;
  
  
  What I faced
&lt;/h2&gt;

&lt;p&gt;Hey guys, I was Setting up Next.js with Docker and I had faced several issues. One of the errors was docker couldn't able to load ld-linux-x86-64.so.2.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;⚠ Attempted to load @next/swc-linux-x64-gnu, but an error occurred: &lt;br&gt;
Error loading shared library ld-linux-x86-64.so.2: No such file or directory &lt;br&gt;
(needed by /src/node_modules/@next/swc-linux-x64-gnu/next-swc.linux-x64-gnu.node)&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;The missing file ld-linux-x86-64.so.2 is part of glibc and some base images like alpine based one's doesn't include. This is a simplest error which is related to the docker image I was using. So I switched to Debian based Image and it worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;The following youtube video helped me in the process of setting up.&lt;br&gt;
&lt;a href="https://youtu.be/rJ62a7YNZ4Q?si=kCYojokNsSXK75vg" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it, thank you guys. Since I am in a hurry, I haven't articulated it well, might edit later.&lt;/p&gt;

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