Skip to content
Learni
View all tutorials
Cloud

How to Deploy a Node.js App on Azure App Service in 2026

Lire en français

Introduction

Azure App Service is a fully managed PaaS platform from Microsoft for hosting web apps, APIs, and static sites without managing the underlying infrastructure. In 2026, it natively integrates AI for intelligent auto-scaling and advanced diagnostics via Azure Monitor. This intermediate tutorial guides you through deploying a complete Node.js API: from creating the service to production rollout with deployment slots and horizontal scaling.

Why does this matter? App Service cuts time-to-market by 70% compared to manual VMs, auto-handles SSL certificates, and scales automatically under load. Imagine your app handling 10 to 10k users without any intervention—that's the norm with App Service. We use Azure CLI for CI/CD automation, a hands-on Node.js app with Express, and advanced configs. By the end, you'll have a production-ready, monitored, and scalable stack.

Prerequisites

Log in to Azure CLI

terminal
az login
az account set --subscription "Votre Subscription ID"
az extension add --name webapp --upgrade

This command logs you into your Azure account and sets the active subscription. The webapp extension adds App Service-specific commands. Verify with az --version; pitfall: skipping az login causes silent deployment failures.

Create Resource Group and App Service Plan

A resource group bundles all related Azure assets (like a project folder). The App Service plan defines resources (CPU, RAM, region) and pricing tier (Free, Basic, Premium v3 for scaling).

Create RG and App Service Plan

terminal
az group create --name rg-appservice-tutorial --location "westeurope"
az appservice plan create --name plan-appservice-tutorial --resource-group rg-appservice-tutorial --sku P1V3 --is-linux

Creates a resource group in West Europe and a Premium v3 Linux plan (scales to 30 instances). --is-linux optimizes for Node.js. Pitfall: Free tier limits CPU to 60 min/day; upgrade for production high availability.

Create the App Service

terminal
az webapp create --resource-group rg-appservice-tutorial --plan plan-appservice-tutorial --name monapp-nodejs-2026 --runtime "NODE|20-lts" --deployment-local-git

Creates an empty app with Node 20 LTS runtime and enables local Git for direct pushes. Replace monapp-nodejs-2026 with a globally unique name. Final URL: https://monapp-nodejs-2026.azurewebsites.net. Pitfall: name taken = error; add a timestamp.

Prepare the Node.js Application

Create a local Node.js project with Express for a simple REST API. We include health checks and logging for Azure diagnostics.

Complete package.json

package.json
{
  "name": "api-nodejs-appservice",
  "version": "1.0.0",
  "description": "API pour Azure App Service",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "express": "^4.19.2"
  },
  "engines": {
    "node": "20.x"
  }
}

Declares the required start script (mandatory for App Service) and locks Node to 20.x via engines. Run npm install afterward. Pitfall: no start script causes app crashes; Azure runs npm start on boot.

Complete Express Server

server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());

app.get('/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date().toISOString() });
});

app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: 'User1' }, { id: 2, name: 'User2' }]);
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

module.exports = app;

Basic API with /health endpoint (for Azure liveness probes) and /api/users. process.env.PORT is mandatory (Azure assigns dynamically). Pitfall: hardcoding port 3000 causes 230s timeouts and crashes.

Initialize Git and Deploy

terminal
git init
git add .
git commit -m "Initial commit"

az webapp deployment source config-local-git --name monapp-nodejs-2026 --resource-group rg-appservice-tutorial

git remote add azure $(az webapp deployment source show --name monapp-nodejs-2026 --resource-group rg-appservice-tutorial --query url --output tsv)
git push azure main

Initializes Git, configures Git deployment, and pushes to Azure (auto-builds with npm install). App goes live in <1 min. Pitfall: missing --query url sets wrong remote; check logs with az webapp log tail.

Advanced Configuration: Environment Variables

In production, store secrets in App Settings (encrypted and injected as env vars).

Add Env Vars and HTTPS Config

terminal
az webapp config appsettings set --resource-group rg-appservice-tutorial --name monapp-nodejs-2026 --settings WEBSITE_NODE_DEFAULT_VERSION="20-lts" API_KEY="supersecret"

az webapp update --resource-group rg-appservice-tutorial --name monapp-nodejs-2026 --https-only true

Sets API_KEY accessible via process.env.API_KEY in code. Forces HTTPS (free). Pitfall: auto-restart; test with curl https://monapp-nodejs-2026.azurewebsites.net/health.

Horizontal Scaling and Staging Slot

terminal
az appservice plan update --name plan-appservice-tutorial --resource-group rg-appservice-tutorial --number-of-workers 3 --sku P2V3

az webapp deployment slot create --name monapp-nodejs-2026 --resource-group rg-appservice-tutorial --slot staging
az webapp deployment source config --name monapp-nodejs-2026 --resource-group rg-appservice-tutorial --slot staging --remote-url $(git remote get-url azure)
git push azure staging:main
az webapp deployment slot swap --name monapp-nodejs-2026 --resource-group rg-appservice-tutorial --slot staging

Scales to 3 P2v3 instances (more CPU). Creates staging slot, pushes code, and swaps for zero-downtime. Pitfall: slots share the plan; monitor costs with az monitor metrics.

Best Practices

  • Use slots for zero-downtime deployments and A/B testing.
  • Enable Application Insights: az webapp insight component create for automatic traces.
  • Scaling rules: Auto-scale on CPU >70% via Azure Portal.
  • CI/CD with GitHub Actions: Integrate azure/webapps-deploy for production.
  • Daily backups: az webapp config backup create.

Common Errors to Avoid

  • Fixed port: Always use process.env.PORT; otherwise, Azure timeouts.
  • Memory leaks: Monitor via Kudu (https://monapp.scm.azurewebsites.net); recycle workers.
  • Cold starts: Use Premium plan for always-ready instances.
  • Lost logs: console.log goes to Log Stream; use Winston for persistence.

Next Steps