<?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: Khuzaima Khalid</title>
    <description>The latest articles on DEV Community by Khuzaima Khalid (@khuzaima_khalid_f3aae24da).</description>
    <link>https://dev.to/khuzaima_khalid_f3aae24da</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4064160%2F45f3974b-34b8-407c-9cbd-5a9a0e9e6281.png</url>
      <title>DEV Community: Khuzaima Khalid</title>
      <link>https://dev.to/khuzaima_khalid_f3aae24da</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khuzaima_khalid_f3aae24da"/>
    <language>en</language>
    <item>
      <title>Episode 3: Setting Up a Managed PostgreSQL Database on Azure &amp; Connecting Your Express API</title>
      <dc:creator>Khuzaima Khalid</dc:creator>
      <pubDate>Sun, 09 Aug 2026 15:45:24 +0000</pubDate>
      <link>https://dev.to/khuzaima_khalid_f3aae24da/episode-3-setting-up-a-managed-postgresql-database-on-azure-connecting-your-express-api-1caj</link>
      <guid>https://dev.to/khuzaima_khalid_f3aae24da/episode-3-setting-up-a-managed-postgresql-database-on-azure-connecting-your-express-api-1caj</guid>
      <description>&lt;p&gt;In Episode 1, we hosted an Express API on Azure App Service, and in Episode 2, we deployed a React frontend to Azure Static Web Apps. Now, we will connect our full-stack application to a managed, production-ready relational database: Azure Database for PostgreSQL Flexible Server.&lt;/p&gt;

&lt;p&gt;In this guide, we will provision a PostgreSQL instance, configure its firewall rules, secure connection credentials using environment variables, and query the database directly from our Express backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Before getting started, make sure you have:&lt;/p&gt;

&lt;p&gt;The Express project from Episode 1 running locally and on Azure.&lt;/p&gt;

&lt;p&gt;PostgreSQL client tool or extension installed (such as pgAdmin, DBeaver, or the PostgreSQL extension in VS Code).&lt;/p&gt;

&lt;p&gt;An active Azure Account (or Azure for Students).&lt;/p&gt;

&lt;p&gt;Visual Studio Code installed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Create an Azure Database for PostgreSQL Flexible Server
&lt;/h2&gt;

&lt;p&gt;Sign in to the Azure Portal.&lt;/p&gt;

&lt;p&gt;Search for Azure Database for PostgreSQL flexible servers in the top search bar and click Create.&lt;/p&gt;

&lt;p&gt;Configure the Basics tab:&lt;/p&gt;

&lt;p&gt;Subscription: Select your subscription.&lt;/p&gt;

&lt;p&gt;Resource Group: Choose the same resource group used in Episode 1 (e.g., rg-express-azure).&lt;/p&gt;

&lt;p&gt;Server name: Choose a unique server name (e.g., pg-express-db-server).&lt;/p&gt;

&lt;p&gt;Region: Select the same region as your App Service.&lt;/p&gt;

&lt;p&gt;Workload type: Select Development or Hobby to stay cost-effective.&lt;/p&gt;

&lt;p&gt;Authentication method: Select PostgreSQL authentication only.&lt;/p&gt;

&lt;p&gt;Admin username: Set an admin username (e.g., pgadmin).&lt;/p&gt;

&lt;p&gt;Password: Enter a strong password and save it securely.&lt;/p&gt;

&lt;p&gt;Move to the Networking tab:&lt;/p&gt;

&lt;p&gt;Connectivity method: Select Public access (allowed IP addresses).&lt;/p&gt;

&lt;p&gt;Check Allow public access from any Azure service within Azure to this server (this allows your Azure App Service to connect).&lt;/p&gt;

&lt;p&gt;Click + Add current client IP address so you can connect locally from your development machine.&lt;/p&gt;

&lt;p&gt;Click Review + create, then click Create. Wait 2–3 minutes for deployment to complete.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Install PostgreSQL Client in Express
&lt;/h2&gt;

&lt;p&gt;Open your local Express project in VS Code and install the official PostgreSQL node driver (pg) along with dotenv to manage secrets locally:&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;pg dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Configure Local Environment Variables
&lt;/h2&gt;

&lt;p&gt;Create a .env file in the root of your Express project (ensure .env is added to your .gitignore file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5000&lt;/span&gt;
&lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pg-express-db-server.postgres.database.azure.com&lt;/span&gt;
&lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pgadmin&lt;/span&gt;
&lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;YourStrongPassword123!&lt;/span&gt;
&lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Create Database Connection Module
&lt;/h2&gt;

&lt;p&gt;Create a file named db.js in your Express project root:&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rejectUnauthorized&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// Required for Azure PostgreSQL SSL connections&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connected to Azure PostgreSQL database successfully.&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="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Update Your Express API Routes
&lt;/h2&gt;

&lt;p&gt;Update your index.js or server.js file to verify the connection and query data:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Root endpoint testing DB connection time&lt;/span&gt;
&lt;span class="nx"&gt;app&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;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SELECT NOW()&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;Express API is running and connected to Azure PostgreSQL!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;serverTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Database connection error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Database connection failed&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;p&gt;Test it locally by running node index.js and visiting &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Configure Environment Variables in Azure App Service
&lt;/h2&gt;

&lt;p&gt;Never commit passwords or database host credentials to GitHub. To pass credentials securely to your live Azure deployment:&lt;/p&gt;

&lt;p&gt;Go to the Azure Portal and open your App Service resource from Episode 1.&lt;/p&gt;

&lt;p&gt;In the left menu, under Settings, select Environment variables (or Configuration).&lt;/p&gt;

&lt;p&gt;Under App settings, click + Add to add each variable:&lt;/p&gt;

&lt;p&gt;DB_HOST = pg-express-db-server.postgres.database.azure.com&lt;/p&gt;

&lt;p&gt;DB_USER = pgadmin&lt;/p&gt;

&lt;p&gt;DB_PASSWORD = YourStrongPassword123!&lt;/p&gt;

&lt;p&gt;DB_NAME = postgres&lt;/p&gt;

&lt;p&gt;DB_PORT = 5432&lt;/p&gt;

&lt;p&gt;Click Apply at the bottom, then click Confirm. Your App Service will restart automatically with the new environment variables active.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Push Changes and Verify Deployment
&lt;/h2&gt;

&lt;p&gt;Push your updated code to GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add PostgreSQL connection logic"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your CI/CD pipeline or deployment finishes, visit your live Azure App Service URL in the browser (https://.azurewebsites.net/). You should see the success response along with the real-time timestamp generated directly by your Azure PostgreSQL database!&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Issues &amp;amp; Troubleshooting
&lt;/h2&gt;

&lt;p&gt;error: no pg_hba.conf entry for host...: Azure PostgreSQL requires SSL connections by default. Ensure ssl: { rejectUnauthorized: false } is included in your pg Pool configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Timeout / ECONNREFUSED:
&lt;/h2&gt;

&lt;p&gt;Check the Networking firewall rules on your PostgreSQL server in Azure. Make sure "Allow public access from any Azure service within Azure" is checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credentials Exposed:
&lt;/h2&gt;

&lt;p&gt;Ensure .env is listed inside your .gitignore file so database keys are never pushed to GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Helpful Resources &amp;amp; Documentation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;a href="https://learn.microsoft.com/azure/postgresql/single-server/overview?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://learn.microsoft.com/azure/postgresql/single-server/overview?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2. &lt;a href="https://code.visualstudio.com/docs/nodejs/nodejs-tutorial?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/nodejs/nodejs-tutorial?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;3. &lt;a href="https://learn.microsoft.com/azure/app-service/overview-security?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://learn.microsoft.com/azure/app-service/overview-security?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;4. &lt;a href="https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>postgres</category>
      <category>devops</category>
    </item>
    <item>
      <title>Episode 2: How to Deploy a React SPA to Azure Static Web Apps for Free</title>
      <dc:creator>Khuzaima Khalid</dc:creator>
      <pubDate>Fri, 07 Aug 2026 11:21:46 +0000</pubDate>
      <link>https://dev.to/khuzaima_khalid_f3aae24da/episode-2-how-to-deploy-a-react-spa-to-azure-static-web-apps-for-free-49ne</link>
      <guid>https://dev.to/khuzaima_khalid_f3aae24da/episode-2-how-to-deploy-a-react-spa-to-azure-static-web-apps-for-free-49ne</guid>
      <description>&lt;p&gt;Now that our Express API from Episode 1 is deployed and running in the cloud, the next step is hosting the frontend. If you build React applications with Vite or Create React App, deploying them to a traditional web server can be overkill and unnecessarily expensive.&lt;/p&gt;

&lt;p&gt;In this guide, we will deploy a React single-page application (SPA) to Azure Static Web Apps. It comes with a generous free tier, global content delivery network (CDN) distribution, automatic SSL certificates, and direct integration with your API.&lt;/p&gt;

&lt;p&gt;Prerequisites&lt;br&gt;
Before starting, make sure you have:&lt;/p&gt;

&lt;p&gt;Node.js and npm installed.&lt;/p&gt;

&lt;p&gt;A GitHub account with a repository for your React project.&lt;/p&gt;

&lt;p&gt;An active Azure Account. You can grab free student credits via Azure for Students:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visual Studio Code installed. Download it directly from VS Code Docs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Create Your React Application
&lt;/h2&gt;

&lt;p&gt;If you already have a React app ready, push it to a GitHub repository and skip to Step 2. Otherwise, let's create a fast React app using Vite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest my-react-app &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt; react
&lt;span class="nb"&gt;cd &lt;/span&gt;my-react-app
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open src/App.jsx and replace its content to connect to our Episode 1 Express backend:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;apiData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setApiData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Replace with your live Azure App Service URL from Episode 1&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://&amp;lt;your-app-name&amp;gt;.azurewebsites.net/&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;res&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setApiData&lt;/span&gt;&lt;span class="p"&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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 Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;Azure&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt; &lt;span class="nx"&gt;Web&lt;/span&gt; &lt;span class="nx"&gt;Apps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;Express&lt;/span&gt; &lt;span class="nx"&gt;Backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;apiData&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f4f4f4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push this project to a new GitHub repository on your profile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create the Azure Static Web App Resource
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sign in to the Azure Portal:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://portal.azure.com/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://portal.azure.com/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search for Static Web Apps in the top search bar and click Create.&lt;/p&gt;

&lt;p&gt;Fill in the basic configuration:&lt;/p&gt;

&lt;p&gt;Subscription: Select your active subscription.&lt;/p&gt;

&lt;p&gt;Resource Group: Select existing or create new (e.g., rg-react-azure).&lt;/p&gt;

&lt;p&gt;Name: my-react-static-app&lt;/p&gt;

&lt;p&gt;Plan type: Select Free: For hobby or personal projects.&lt;/p&gt;

&lt;p&gt;Region: Pick a region closest to your users (e.g., East US or West Europe).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Link GitHub and Deployment Details
&lt;/h2&gt;

&lt;p&gt;Under Deployment Details, select GitHub as the source.&lt;/p&gt;

&lt;p&gt;Click Sign in with GitHub and authorize Azure.&lt;/p&gt;

&lt;p&gt;Select your GitHub Organization, Repository, and Branch (usually main).&lt;/p&gt;

&lt;p&gt;Under Build Details, select the preset for your framework:&lt;/p&gt;

&lt;p&gt;Build Presets: Select Vite (or React if using Create React App).&lt;/p&gt;

&lt;p&gt;App location: /&lt;/p&gt;

&lt;p&gt;Api location: Leave blank for now.&lt;/p&gt;

&lt;p&gt;Output location: dist (for Vite) or build (for CRA).&lt;/p&gt;

&lt;p&gt;Click Review + Create, then click Create.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Automated GitHub Actions CI/CD Pipeline
&lt;/h2&gt;

&lt;p&gt;Once Azure provisions the resource, it automatically generates a GitHub Actions workflow file inside your repository at .github/workflows/.&lt;/p&gt;

&lt;p&gt;Go to your GitHub repository and click the Actions tab.&lt;/p&gt;

&lt;p&gt;You will see a workflow running titled Azure Static Web Apps CI/CD.&lt;/p&gt;

&lt;p&gt;Wait about 1–2 minutes for the workflow to complete.&lt;/p&gt;

&lt;p&gt;Once finished, open your Static Web App resource in the Azure Portal, locate the URL, and open it in your browser.&lt;/p&gt;

&lt;p&gt;Your React app is now globally distributed on Azure with HTTPS enabled out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Issues &amp;amp; Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Blank Screen / 404 on Refresh: If using React Router, single-page routing might break on refresh. Add a staticwebapp.config.json file to your public/ folder with fallback routes:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"navigationFallback"&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="nl"&gt;"rewrite"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/index.html"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failed Build Step: Ensure your package.json includes the standard "build": "vite build" script and that your output directory (dist or build) matches what you specified in Step 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Helpful Resources &amp;amp; Documentation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Official Azure Static Web Apps Documentation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/azure/static-web-apps/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://learn.microsoft.com/azure/static-web-apps/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get Started with Azure Free for Students:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure Static Web Apps Routing:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/azure/static-web-apps/configuration?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://learn.microsoft.com/azure/static-web-apps/configuration?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next episode, we'll look at how to set up a managed PostgreSQL database on Azure and connect it safely to our Node.js backend using environment variables.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Episode 1: Deploying Your First Node.js &amp; Express API to Azure App Service</title>
      <dc:creator>Khuzaima Khalid</dc:creator>
      <pubDate>Wed, 05 Aug 2026 11:57:41 +0000</pubDate>
      <link>https://dev.to/khuzaima_khalid_f3aae24da/episode-1-deploying-your-first-nodejs-express-api-to-azure-app-service-2ddi</link>
      <guid>https://dev.to/khuzaima_khalid_f3aae24da/episode-1-deploying-your-first-nodejs-express-api-to-azure-app-service-2ddi</guid>
      <description>&lt;p&gt;When I built my first Express API, running it on localhost:5000 felt great until I wanted to share it with someone else. Sending local endpoints to teammates or setting up temporary tunnels like ngrok gets annoying fast.&lt;br&gt;
If you build backends with Node.js and Express, pushing your API to the cloud is a fundamental skill. In this guide, we will take a simple Express API and deploy it to Azure App Service so you have a live, HTTPS-enabled production URL.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before diving into the setup, make sure you have the following ready:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Node.js installed on your local machine.&lt;/li&gt;
&lt;li&gt; An active Azure Account. If you don't have one, grab the Azure for Students plan which gives you free credits without needing a credit card:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Visual Studio Code with the Azure App Service extension installed. You can download the editor directly from VS Code Docs:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set Up Your Express Server&lt;/strong&gt;&lt;br&gt;
If you already have a Node.js project, you can skip to Step 2. Otherwise, let's create a minimal Express server.&lt;/p&gt;

&lt;p&gt;Initialize a new directory and install Express:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bash&lt;/strong&gt;&lt;br&gt;
mkdir express-azure-demo&lt;br&gt;
cd express-azure-demo&lt;br&gt;
npm init -y&lt;br&gt;
npm install express dotenv&lt;/p&gt;

&lt;p&gt;Create a file named server.js in the root folder:&lt;br&gt;
&lt;strong&gt;JavaScript&lt;/strong&gt;&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Azure dynamically assigns a PORT environment variable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&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;/&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;Express API is running smoothly on Azure App Service!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&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;/api/health&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;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;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;p&gt;&lt;strong&gt;Important Rule for Azure: package.json&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure needs to know how to start your application once it deploys the code. Open your package.json and ensure your scripts section includes a start command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
"scripts": {&lt;br&gt;
  "start": "node server.js"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create the App Service Resource&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are multiple ways to deploy—using the Azure CLI, Git integration, or VS Code. Using VS Code is the straightest path for a quick deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open your project folder in Visual Studio Code.&lt;/li&gt;
&lt;li&gt; Click on the Azure icon in the left sidebar.&lt;/li&gt;
&lt;li&gt; Sign in to your Azure account if prompted.&lt;/li&gt;
&lt;li&gt; Under the App Service section, click the + (Plus) button to create a new Web App.&lt;/li&gt;
&lt;li&gt; Enter a unique name for your API (e.g., my-express-api-2026).&lt;/li&gt;
&lt;li&gt; Select your runtime stack: Node.js (LTS version).&lt;/li&gt;
&lt;li&gt; Select the Free (F1) pricing tier for testing.
Azure will spend about a minute provisioning your server environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Deploy the Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the resource creation finishes, deploying your code takes just a few clicks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In VS Code, open the Command Palette (Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on macOS).&lt;/li&gt;
&lt;li&gt; Type and select Azure App Service: Deploy to Web App...&lt;/li&gt;
&lt;li&gt; Select your project folder (express-azure-demo).&lt;/li&gt;
&lt;li&gt; Select the Web App resource you created in Step 2.&lt;/li&gt;
&lt;li&gt; A popup will ask if you want to overwrite previous deployments. Click Deploy.
VS Code will package your files, upload them to Azure, run npm install inside the cloud environment, and execute npm start.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 4: Verify Your API Live&lt;br&gt;
Once the deployment output window displays "Deployment successful," copy your app's public URL:&lt;/p&gt;

&lt;p&gt;https://.azurewebsites.net&lt;br&gt;
Open your browser or Postman and hit the URL. You should get back the JSON response:&lt;br&gt;
&lt;strong&gt;JSON&lt;/strong&gt;&lt;br&gt;
{&lt;br&gt;
  "message": "Express API is running smoothly on Azure App Service!",&lt;br&gt;
  "status": "Success",&lt;br&gt;
  "timestamp": "2026-08-05T16:35:23.000Z"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Issues &amp;amp; Troubleshooting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• 502 Bad Gateway / Application Error: Check your port setup. Make sure your code relies on process.env.PORT instead of hardcoding 5000 or 3000. Azure handles internal routing dynamically using its own port mapping.&lt;br&gt;
• Missing Dependencies: Ensure node_modules is listed in your .gitignore file so VS Code doesn't try to upload local modules. Let Azure run npm install on its own server.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Helpful Resources &amp;amp; Documentation
&lt;/h2&gt;

&lt;p&gt;• &lt;strong&gt;Official Azure App Service Documentation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/azure/app-service/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://learn.microsoft.com/azure/app-service/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Get Started with Azure Free for Students:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://azure.microsoft.com/free/students/?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;br&gt;
• Visual Studio Code Node.js Tutorial Guide:&lt;br&gt;
&lt;a href="https://code.visualstudio.com/docs/nodejs/nodejs-tutorial?wt.mc_id=studentamb_512515" rel="noopener noreferrer"&gt;https://code.visualstudio.com/docs/nodejs/nodejs-tutorial?wt.mc_id=studentamb_512515&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next episode, we'll look at how to take a React frontend, host it for free on Azure Static Web Apps, and connect it directly to this Express backend.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
