Skip to content
Innovialabs

How to Deploy a Web App to Azure App Service

Practice4 min

In short

Create an App Service plan (it sets region, OS and pricing tier), add a web app with the right runtime, deploy via GitHub Actions or zip deploy, keep secrets in app settings, and release through a staging slot and swap for zero downtime.

The short version

Azure App Service is managed hosting for web apps: you ship code, and Azure handles servers, the OS, load balancing and platform updates. Everything revolves around two resources:

  • App Service plan — the compute: region, operating system (Linux or Windows), pricing tier and instance count. You pay for the plan.
  • Web App — the application inside the plan: runtime, code, settings, domains. One plan can host several apps, and they share its resources.

The order is: resource group → plan → web app → deploy → settings → domain and SSL → slots for releases.

Step 1. Create the plan and the app

Azure CLI is the most convenient route because the commands can be saved and repeated:

az group create --name shop-rg --location westeurope
az appservice plan create --name shop-plan --resource-group shop-rg --sku B1 --is-linux
az webapp create --name shop-app --resource-group shop-rg --plan shop-plan --runtime "NODE:20-lts"

The app name must be globally unique, since it becomes shop-app.azurewebsites.net. Run az webapp list-runtimes to see current runtimes for Node.js, .NET and other stacks.

Step 2. Deploy the code

Zip deploy is the fastest option for a first launch or a manual release. Build the project, zip it and push:

az webapp deploy --resource-group shop-rg --name shop-app --src-path app.zip --type zip

If the archive contains sources without node_modules, enable a platform-side build with the setting SCM_DO_BUILD_DURING_DEPLOYMENT=true. For .NET you usually zip the output of dotnet publish.

GitHub Actions is the right choice for ongoing work. The wizard in Deployment Center generates the workflow file and the credentials secret for you. The key step looks like this:

- uses: azure/webapps-deploy@v3
  with:
    app-name: shop-app
    slot-name: staging
    publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
    package: .

For production projects, prefer OpenID Connect sign-in over a publish profile, so no long-lived secret sits in the repository.

Step 3. Configure app settings

Connection strings, API keys and environment mode do not belong in code. In App Service they are app settings, exposed to the app as environment variables:

az webapp config appsettings set --resource-group shop-rg --name shop-app --settings NODE_ENV=production API_URL=https://api.example.com

Also worth enabling right away:

  • HTTPS Only — forces redirects to HTTPS;
  • Always On (paid tiers) — keeps the app from idling when there is no traffic;
  • Health check — a path such as /health the platform uses to know an instance is alive;
  • application logging — otherwise post-deploy errors become guesswork.

Step 4. Zero-downtime releases with slots

A deployment slot is a separate copy of the app with its own address, for example shop-app-staging.azurewebsites.net. The release flow:

  1. Create the slot: az webapp deployment slot create --name shop-app --resource-group shop-rg --slot staging.
  2. Deploy the new version to staging and test it.
  3. Swap: az webapp deployment slot swap --name shop-app --resource-group shop-rg --slot staging --target-slot production.

The platform warms up instances before switching, so users never hit a cold start. If something breaks, swapping again brings the previous version back.

One important detail: settings that must not travel with the code (such as a test database connection string) should be marked as a deployment slot setting so they stay pinned to their slot.

Step 5. Custom domain and free SSL

  1. Add the domain under Custom domains. For www, create a CNAME at your registrar pointing to shop-app.azurewebsites.net; for the root domain, use an A record with the app's IP.
  2. Add a TXT record asuid.<subdomain> with the verification ID from the portal so Azure can confirm you own the domain.
  3. Create an App Service Managed Certificate and bind it to the domain using SNI SSL. It is free and renews automatically, but it does not cover wildcard domains.

Choosing a pricing tier

TierWhen it fits
Free / SharedExperiments and demos: shared compute, no SLA, many features missing
BasicSmall production apps without slots or autoscaling
StandardYou need slots, autoscaling and backups
PremiumHeavy load, more memory and slots, private networking

Decide by features, not price alone: zero-downtime releases rule out Basic. Start with the lowest tier that fits — the plan can be scaled later without redeploying. Prices depend on region and OS; use the official Azure pricing calculator.

Common mistakes

  • Hardcoded port. A Node.js app must read its port from process.env.PORT.
  • Secrets in the repository instead of app settings.
  • Deploying straight to production without a slot, so every bug is public.
  • Too many apps in one plan, all competing for memory and CPU.

FAQ

On a VM you patch the OS, configure the web server and load balancing yourself. App Service handles that, leaving you only code and settings, at the cost of less control.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.