<?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: Basit Jamil</title>
    <description>The latest articles on Forem by Basit Jamil (@chbasitgill).</description>
    <link>https://forem.com/chbasitgill</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%2F347695%2F0883cd79-cada-4653-b32b-7db298946057.jpeg</url>
      <title>Forem: Basit Jamil</title>
      <link>https://forem.com/chbasitgill</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chbasitgill"/>
    <language>en</language>
    <item>
      <title>Build an Angular app once, Deploy Anywhere with Docker &amp; Nginx</title>
      <dc:creator>Basit Jamil</dc:creator>
      <pubDate>Sat, 02 May 2026 05:42:58 +0000</pubDate>
      <link>https://forem.com/chbasitgill/build-an-angular-app-once-deploy-anywhere-with-docker-nginx-2gbl</link>
      <guid>https://forem.com/chbasitgill/build-an-angular-app-once-deploy-anywhere-with-docker-nginx-2gbl</guid>
      <description>&lt;p&gt;Standard Angular builds bake environment variables into the code at build time. This means if you have &lt;strong&gt;Dev&lt;/strong&gt;, &lt;strong&gt;Staging&lt;/strong&gt;, and &lt;strong&gt;Prod&lt;/strong&gt; environments, you have to build the app three times. &lt;/p&gt;

&lt;p&gt;That's a waste of time. Instead, we should build a single Docker image and swap configurations at runtime. Here is how to do it.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Strategy
&lt;/h2&gt;

&lt;p&gt;We will store environment-specific configurations in JSON files and use an &lt;strong&gt;Entrypoint script&lt;/strong&gt; in Docker to swap them based on an environment variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create Config Files
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;src/config&lt;/code&gt; folder, create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;app-config.dev.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app-config.prod.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In your &lt;code&gt;src/&lt;/code&gt; folder, create a default &lt;code&gt;app-config.json&lt;/code&gt; for local development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Update angular.json
&lt;/h3&gt;

&lt;p&gt;Ensure these files are included in your build assets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"assets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"src/favicon.ico"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"src/assets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"src/app-config.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"src/config"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. The Angular Logic
&lt;/h2&gt;

&lt;p&gt;We need to load the JSON file &lt;strong&gt;before&lt;/strong&gt; the app starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Config Service
&lt;/h3&gt;

&lt;p&gt;Create a service to fetch the JSON file using &lt;code&gt;HttpClient&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConfigService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;loadConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;firstValueFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app-config.json&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&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;h3&gt;
  
  
  The App Initializer
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;APP_INITIALIZER&lt;/code&gt; in your &lt;code&gt;app.config.ts&lt;/code&gt; (Standalone) or &lt;code&gt;AppModule&lt;/code&gt; to block the bootstrap process until the config is loaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In providers:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;APP_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;initApp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;multi&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;
  
  
  3. The Docker Magic
&lt;/h2&gt;

&lt;p&gt;Now, we create a Docker image that can adapt to its environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  entrypoint.sh
&lt;/h3&gt;

&lt;p&gt;This script runs when the container starts. It checks the &lt;code&gt;$ENVIRONMENT&lt;/code&gt; variable and overwrites the main config file.&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="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$ENVIRONMENT&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Prod"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /usr/share/nginx/html/config/app-config.prod.json /usr/share/nginx/html/app-config.json
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /usr/share/nginx/html/config/app-config.dev.json /usr/share/nginx/html/app-config.json
&lt;span class="k"&gt;fi

&lt;/span&gt;nginx &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'daemon off;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Use a multi-stage build to compile the app and serve it with Nginx.&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;# Build Stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:lts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

&lt;span class="c"&gt;# Run Stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:latest&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/dist/your-app-name/browser /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./entrypoint.sh /entrypoint.sh&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /entrypoint.sh

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/bin/bash", "/entrypoint.sh"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Running the Container
&lt;/h2&gt;

&lt;p&gt;Now you can build your image once:&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; my-angular-app &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run it anywhere by just changing the environment variable:&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="c"&gt;# Run for Production&lt;/span&gt;
docker run &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Prod &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 my-angular-app

&lt;span class="c"&gt;# Run for Dev&lt;/span&gt;
docker run &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Dev &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 my-angular-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One Build:&lt;/strong&gt; Saves CI/CD time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx:&lt;/strong&gt; High-performance serving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Agnostic:&lt;/strong&gt; Move the same artifact from Dev to Prod with zero code changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>angular</category>
    </item>
    <item>
      <title>.NET Core Web API Middleware Order Configuration</title>
      <dc:creator>Basit Jamil</dc:creator>
      <pubDate>Thu, 09 Dec 2021 13:12:39 +0000</pubDate>
      <link>https://forem.com/chbasitgill/net-core-web-api-middleware-order-configuration-1e0d</link>
      <guid>https://forem.com/chbasitgill/net-core-web-api-middleware-order-configuration-1e0d</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Exception Handler&lt;/li&gt;
&lt;li&gt;HSTS&lt;/li&gt;
&lt;li&gt;HTTPS Redirection&lt;/li&gt;
&lt;li&gt;Static Files&lt;/li&gt;
&lt;li&gt;Routing&lt;/li&gt;
&lt;li&gt;CORS&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Custom Middleware&lt;/li&gt;
&lt;li&gt;Endpoint Configuration&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Singleton design pattern eager initialization in C#</title>
      <dc:creator>Basit Jamil</dc:creator>
      <pubDate>Thu, 08 Oct 2020 08:06:51 +0000</pubDate>
      <link>https://forem.com/chbasitgill/singleton-design-pattern-eager-initialization-in-c-4gl4</link>
      <guid>https://forem.com/chbasitgill/singleton-design-pattern-eager-initialization-in-c-4gl4</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Code
public class SingletonDesignPattern
{
    private static SingletonDesignPattern instance = new SingletonDesignPattern();
    private SingletonDesignPattern() { }
    public static SingletonDesignPattern GetInstance
    {
        get { return instance; } //can only be get no set
    }
}

// Usage
SingletonDesignPattern singleton = 
SingletonDesignPattern.GetInstance;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
