Files
PowderCoatingLogix/AZURE_SETUP.md
T
2026-04-23 21:38:24 -04:00

5.7 KiB

Azure Deployment Setup Guide

Overview

The app uses environment-specific config layering:

  • appsettings.json — base defaults (checked into source)
  • appsettings.Production.json — production log levels (checked into source)
  • Azure App Service Configuration — secrets and environment-specific values (overrides everything, never in source)

Azure App Service flattens nested JSON keys using __ (double underscore). For example, Stripe:SecretKey in JSON becomes Stripe__SecretKey in Azure.


Step 1 — Create Azure Resources

You will need the following Azure resources:

Resource Purpose
App Service (Windows or Linux, .NET 8) Hosts the web application
Azure SQL Database Production database
Azure Storage Account (powdercoatingappdev or prod equivalent) Blob storage for files + Data Protection keys

Storage containers to create (or they auto-create on first run):

Container Name Purpose
profileimages User profile photos
jobimages Job photos
companylogos Company logo images
manuals Equipment PDF manuals
dataprotection ASP.NET Data Protection keys (auto-created on startup)

Step 2 — App Service Configuration (Application Settings)

Navigate to: App Service → Configuration → Application Settings

Add each of the following as individual Application Settings entries.

Required — Environment

Name Value
ASPNETCORE_ENVIRONMENT Production

Required — Database

Name Value
ConnectionStrings__DefaultConnection Server=<your-server>.database.windows.net;Database=PowderCoatingDb;User Id=<user>;Password=<password>;MultipleActiveResultSets=true;TrustServerCertificate=true;Encrypt=true

Required — Azure Storage

Name Value
Storage__ConnectionString DefaultEndpointsProtocol=https;AccountName=<account>;AccountKey=<key>;EndpointSuffix=core.windows.net

The container names default to the values below and only need to be set here if you want to override them:

Name Default Value
Storage__Containers__ProfileImages profileimages
Storage__Containers__JobImages jobimages
Storage__Containers__Manuals manuals
Storage__Containers__CompanyLogos companylogos

Required — Stripe

Replace with your live keys (not test keys) for production.

Name Value
Stripe__SecretKey sk_live_...
Stripe__PublishableKey pk_live_...
Stripe__WebhookSecret whsec_...
Stripe__Prices__Basic price_... (your live Stripe price ID)
Stripe__Prices__Pro price_... (your live Stripe price ID)
Stripe__Prices__Enterprise price_... (your live Stripe price ID)

Required — SendGrid

Name Value
SendGrid__ApiKey SG....
SendGrid__FromEmail noreply@yourdomain.com
SendGrid__FromName Your Company Name

Optional — Twilio (SMS)

Only needed if SMS notifications are enabled.

Name Value
Twilio__AccountSid AC...
Twilio__AuthToken ...
Twilio__FromNumber +1XXXXXXXXXX

Optional — App Settings Overrides

Name Value
AppSettings__CompanyName Your Powder Coating Company
AppSettings__BaseUrl https://yourdomain.azurewebsites.net
AppSettings__TaxRate 0.0
AppSettings__Currency USD

Step 3 — Stripe Webhook (if using billing)

  1. In the Stripe Dashboard, add a webhook endpoint pointing to: https://<your-domain>/stripe/webhook
  2. Select events: customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, invoice.payment_failed
  3. Copy the webhook signing secret into Stripe__WebhookSecret above.

Step 4 — Database

EF Core migrations run automatically on startup in Production. No manual dotnet ef database update step is needed after the first deployment.

For the very first deployment only, ensure the Azure SQL firewall allows connections from your App Service (or enable "Allow Azure services to access this server").


Step 5 — Deploy

# Publish to a local folder
dotnet publish src/PowderCoating.Web -c Release -o ./publish

# Or use Azure CLI to deploy directly
az webapp deployment source config-zip \
  --resource-group <rg> \
  --name <app-service-name> \
  --src publish.zip

Or connect the App Service to your git repo/GitHub Actions for CI/CD.


Step 6 — First Run Checklist

After deploying and before handing off to users:

  • App loads at the Azure URL without errors
  • Log in with SuperAdmin credentials (superadmin@powdercoating.com / SuperAdmin123!) or company admin (admin@demo.com / CompanyAdmin123!)
  • Platform Management → Seed Data → seed System Data
  • Platform Management → Storage Migration → migrate any existing local files to Azure
  • Verify a profile photo and job photo load correctly
  • Verify Stripe webhook is receiving events (check Stripe Dashboard → Webhooks)
  • Update SuperAdmin password to something strong

Notes

  • Data Protection keys are stored in the dataprotection Azure Blob container as keys.xml. This allows auth cookies to survive app restarts and work across multiple instances.
  • Local development is unaffected — it uses appsettings.Development.json and a local filesystem key store. No Azure credentials are required for local dev (though the dev storage account is already configured in appsettings.Development.json).
  • Logs write to both console (captured by Azure Log Stream) and the logs/ folder on the App Service filesystem. View live logs via: App Service → Log stream.