172 lines
5.7 KiB
Markdown
172 lines
5.7 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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**.
|