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)
- In the Stripe Dashboard, add a webhook endpoint pointing to:
https://<your-domain>/stripe/webhook - Select events:
customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,invoice.payment_succeeded,invoice.payment_failed - Copy the webhook signing secret into
Stripe__WebhookSecretabove.
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
dataprotectionAzure Blob container askeys.xml. This allows auth cookies to survive app restarts and work across multiple instances. - Local development is unaffected — it uses
appsettings.Development.jsonand a local filesystem key store. No Azure credentials are required for local dev (though the dev storage account is already configured inappsettings.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.