GuyStore – Deployment Guide

Step-by-step instructions for cloud and iPhone deployment of the ASP.NET Core 9 MVC platform

App: GuyStore v1.0 Runtime: .NET 9 Prepared: 2026-05-08

Table of Contents

  1. Overview
  2. Deployment 1 – Azure App Service (Cloud)
    1. Required Tools & Accounts
    2. Step 1 – Install Prerequisites
    3. Step 2 – Prepare the Application
    4. Step 3 – Provision Azure Resources
    5. Step 4 – Configure Application Settings
    6. Step 5 – Build & Publish
    7. Step 6 – Deploy to Azure
    8. Step 7 – HTTPS & Custom Domain
    9. Step 8 – Verify Deployment
  3. Deployment 2 – iPhone (iOS)
    1. Strategy & Options
    2. Required Tools & Accounts
    3. Step 1 – Create the PWA Manifest
    4. Step 2 – Create App Icons
    5. Step 3 – Add iOS Meta Tags
    6. Step 4 – Register a Service Worker
    7. Step 5 – Deploy Updated App to Azure
    8. Step 6 – Install on iPhone
    9. App Store Distribution (Optional)
  4. Voice Feature – iOS Browser Compatibility
  5. Production Configuration Reference

Overview

GuyStore is an ASP.NET Core 9 MVC application. This guide covers two deployment targets. Deployment 1 publishes the app to the cloud so it is reachable over a secure HTTPS URL. Deployment 2 installs it on an iPhone as a Progressive Web App (PWA) using that same HTTPS URL. The two deployments are sequential: you must complete Deployment 1 before Deployment 2 can work, because iPhone microphone and camera access are blocked by browsers on non-HTTPS origins.

☁️
Deployment 1 – Azure App Service
Publishes the .NET 9 app to a managed cloud host. Provides the HTTPS URL required by the Voice Feature and the iPhone PWA install.
📱
Deployment 2 – iPhone (iOS PWA)
Configures GuyStore as an installable PWA. Users tap "Add to Home Screen" in Safari to pin the app to their iPhone with a full-screen, app-like experience.

Architecture after both deployments

Developer PC  ──dotnet publish──►  Azure App Service (HTTPS)
                                         │
                          ┌──────────────┼──────────────┐
                    Desktop Browser   iPhone Safari    iPhone Home Screen
                                      (PWA install)   (standalone, full-screen)

Deployment 1 – Azure App Service (Cloud)

☁️

Azure App Service is a fully managed PaaS that runs ASP.NET Core apps with zero infrastructure configuration. It provides automatic HTTPS via *.azurewebsites.net, built-in load balancing, and a free-tier plan suitable for demos. The deployment uses the Azure CLI and a zip-based publish — no Docker, no CI/CD pipeline required.

Required Tools & Accounts

.NET 9 SDK
9.0 or later
Compiles and publishes the ASP.NET Core app. Download from dot.net.
Required Free
Azure CLI
2.59 or later
Command-line tool to create and manage Azure resources and deploy the app.
Required Free
Azure Subscription
Free or Pay-as-you-go
Azure account to host the App Service. Free tier (F1) is sufficient for demos.
Required
PowerShell 5.1+
Built into Windows 10
Used to zip the published output for deployment. Already present on the dev machine.
Required Free
Visual Studio 2022
17.x (Community or higher)
Optional IDE with built-in Azure publish wizard as an alternative to the CLI.
Optional Free (Community)
Git
Any recent version
Required only if you choose GitHub Actions CI/CD instead of manual zip deploy.
Optional Free
ℹ️ Azure Free Tier (F1)

The F1 plan is free but limited to 60 CPU minutes/day and 1 GB RAM. It is sufficient for demos and testing. Upgrade to B1 (~$13 USD/month) for sustained usage. The F1 plan also does not support custom domains with managed SSL certificates — use B1 or above for a custom domain.

1

Install Prerequisites

Install .NET 9 SDK

Download and run the installer from https://dot.net/download. Choose the SDK (not the Runtime) for the x64 Windows installer. Verify after installation:

dotnet --version
# Expected: 9.0.x

Install Azure CLI

Download the MSI from https://aka.ms/installazurecliwindows and run it. Verify in a new PowerShell window:

az --version
# Expected: azure-cli 2.59.0 or later
2

Prepare the Application for Production

Two settings in appsettings.json must be changed before deploying. Do not commit credentials to source control — override them via Azure App Settings (Step 4) instead.

SettingDevelopment valueProduction valueReason
Demo:BypassWebhookAuthtruefalsePrevents unauthenticated webhook calls in production
Translation:SimulationModetruetrue until live API key is readyAvoids hitting the free MyMemory rate limit during testing
✅ Database configuration

GuyStore defaults to EF Core InMemory ("UseInMemoryDatabase": true in appsettings.json). No SQL Server provisioning is needed for demos. Set to false and supply ConnectionStrings__DefaultConnection as an Azure App Setting to persist data across restarts. If switching to SQL Server, run dotnet ef database update locally first to create the schema, then deploy — Azure will run MigrateAsync() on startup.

3

Provision Azure Resources

Run these commands in PowerShell. Replace guystore-app with a globally unique name — it becomes part of the URL (https://guystore-app.azurewebsites.net).

# 1. Log in to Azure (opens browser for authentication)
az login

# 2. Create a resource group (one logical container for all resources)
az group create `
  --name GuyStoreRG `
  --location eastus

# 3. Create an App Service plan
#    --sku F1  = free tier   |   --sku B1 = basic (~$13/month)
az appservice plan create `
  --name GuyStorePlan `
  --resource-group GuyStoreRG `
  --sku B1 `
  --is-linux

# 4. Create the Web App (Linux, .NET 9)
az webapp create `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --plan GuyStorePlan `
  --runtime "DOTNETCORE:9.0"
ℹ️ Linux vs Windows App Service

The --is-linux flag creates a Linux-based plan, which is faster to provision and slightly cheaper. ASP.NET Core 9 runs identically on both. Remove the flag to use Windows hosting if preferred.

4

Configure Application Settings

Azure App Settings are injected as environment variables at runtime and override values in appsettings.json. The double-underscore (__) separator maps to nested JSON keys.

az webapp config appsettings set `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --settings `
    "ASPNETCORE_ENVIRONMENT=Production" `
    "Demo__BypassWebhookAuth=false" `
    "Translation__SimulationMode=true" `
    "Kafka__BootstrapServers=localhost:9092" `
    "Extensiv__SimulationMode=true" `
    "Techship__SimulationMode=true" `
    "UseInMemoryDatabase=false" `
    "ConnectionStrings__DefaultConnection=YOUR_SQL_CONNECTION_STRING" `
    "Fido2__ServerDomain=yourdomain.com" `
    "Fido2__Origins=https://yourdomain.com"

To enable the live MyMemory translation API (no key required, 2 000 chars/day free), set Translation__SimulationMode=false. For Azure Cognitive Translator (unlimited), also add:

az webapp config appsettings set `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --settings `
    "Translation__SimulationMode=false" `
    "Translation__AzureKey=YOUR_KEY" `
    "Translation__AzureRegion=eastus"

For Passkey / WebAuthn in production, update the Fido2 settings to match your real domain:

az webapp config appsettings set `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --settings `
    "Fido2__ServerDomain=yourdomain.com" `
    "Fido2__Origins=https://yourdomain.com"
5

Build & Publish

Run from the solution root. The -c Release flag enables compiler optimisations and trims development tooling. The output is a self-contained folder ready for deployment.

cd "C:\Guy\Notes\Claud Projects\Guy\GuyStore"

dotnet publish GuyStore.csproj -c Release -o ./publish

# Create a zip archive of the published output
Compress-Archive -Path ./publish/* -DestinationPath ./publish.zip -Force
⚠️ Do not include test projects in the publish

Run dotnet publish against GuyStore.csproj directly, not against GuyStore.sln. Publishing the solution would attempt to publish the test projects, which fail because they are not web apps.

6

Deploy to Azure

Upload the zip to App Service using the az webapp deploy command. Azure extracts and runs the app automatically.

az webapp deploy `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --src-path ./publish.zip `
  --type zip

Deployment typically completes in 60–120 seconds. Watch the progress in the terminal output.

Alternative: Visual Studio Publish Wizard

Right-click GuyStore in Solution Explorer → PublishAzureAzure App Service (Linux) → select the App Service created in Step 3 → Publish. This performs build, publish, and zip-deploy in a single click.

7

HTTPS & Custom Domain

Default HTTPS (no configuration needed)

Azure automatically provides a free TLS certificate for the *.azurewebsites.net subdomain. The app is immediately reachable at https://guystore-app.azurewebsites.net — no certificate purchase or configuration required.

Custom domain (optional)

To use your own domain (e.g. https://guystore.example.com):

  1. In your DNS registrar, add a CNAME record pointing guystore.example.comguystore-app.azurewebsites.net.
  2. In the Azure Portal → App Service → Custom domainsAdd custom domain → enter the domain.
  3. In TLS/SSL settingsApp Service Managed Certificate → create a free certificate for the custom domain.
  4. Bind the certificate to the custom domain.
⚠️ Custom domains require B1 plan or higher

The free F1 plan does not support custom domains or App Service Managed Certificates. Upgrade the plan before adding a custom domain.

8

Verify Deployment

Open a browser and navigate to https://guystore-app.azurewebsites.net. Verify the following:

CheckExpected result
Home page loadsDashboard with KPI cards and SignalR connection established
Shop page30 seeded products displayed correctly (pagination at 12/page)
LoginAdmin and buyer accounts from DataSeeder work
Voice Translate pagePage loads; language dropdowns populated
Voice Camera pagePage loads; camera starts after granting permission
HTTPS padlockGreen padlock shown in browser address bar
# Quick smoke test from PowerShell
Invoke-WebRequest -Uri "https://guystore-app.azurewebsites.net" -UseBasicParsing | Select-Object StatusCode
# Expected: StatusCode : 200

Deployment 2 – iPhone (iOS)

📱

GuyStore is deployed to iPhone as a Progressive Web App (PWA). The user installs it from Safari by tapping "Add to Home Screen" — no App Store, no Apple Developer account, and no Xcode required for this path. The app then opens full-screen, with its own icon on the Home Screen, just like a native app.

Strategy & Options

OptionTools requiredApp StoreRecommended for
PWA via Safari (this guide) iPhone, Safari, HTTPS URL No Internal demos, B2B distribution, fast iteration
App Store (.NET MAUI Blazor Hybrid) Mac, Xcode 15+, Apple Developer Program ($99/yr), .NET MAUI Yes Public consumer app, requires Apple review
TestFlight (internal beta) Mac, Xcode 15+, Apple Developer Program ($99/yr) No (invite only) Closed beta testing before App Store release

Required Tools & Accounts

Mandatory for PWA deployment

iPhone
iOS 16 or later recommended
iOS 14.5+ is the minimum for Web Speech API (SpeechRecognition). iOS 16+ gives the most reliable camera and microphone permission handling. iOS 17+ is recommended for the Voice Translate feature.
Required
Safari (iOS)
Built into iOS
Must use Safari — not Chrome or Firefox — for "Add to Home Screen" PWA installation. Chrome and Firefox on iOS also cannot access SpeechRecognition.
Required Free
HTTPS URL
From Deployment 1
Camera and microphone APIs are blocked by all browsers on non-secure origins. The Azure App Service URL (*.azurewebsites.net) satisfies this requirement.
Required
Image editor
Any (e.g. Paint.NET, GIMP, Figma)
Used to create the PNG app icons in the sizes required by iOS. Only needed once to generate the icon set.
Required

Required only for App Store / TestFlight distribution

Mac Computer
macOS 13 Ventura or later
Xcode is macOS-only. Building and signing iOS apps requires a Mac.
App Store only
Xcode
Xcode 15 or later
Apple's IDE for building, signing, and submitting iOS apps. Free download from the Mac App Store.
App Store only Free
Apple Developer Program
Individual or Organization
Membership required to distribute via App Store or TestFlight. $99 USD per year billed annually.
App Store only $99/year
.NET MAUI
Included in .NET 9 SDK
Framework for wrapping the Blazor/web UI in a native iOS shell. Alternative: Capacitor (Node.js-based).
App Store only Free
⚠️ Safari is mandatory for PWA install on iPhone

Apple restricts "Add to Home Screen" PWA installation to Safari only. Chrome, Firefox, Edge, and other browsers on iOS are built on Apple's WebKit engine but do not expose the PWA install prompt. Users must open Safari to install the app.

1

Create the PWA Manifest

Create the file GuyStore/wwwroot/manifest.json. This file tells the browser the app name, icon set, colours, and display mode. Replace the icon paths once the icons are created in Step 2.

{
  "name": "GuyStore",
  "short_name": "GuyStore",
  "description": "B2B Supply Chain & Fulfilment Platform",
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "orientation": "portrait-primary",
  "background_color": "#0f172a",
  "theme_color": "#1a56db",
  "lang": "en",
  "icons": [
    { "src": "/images/icons/icon-76.png",  "sizes": "76x76",   "type": "image/png" },
    { "src": "/images/icons/icon-120.png", "sizes": "120x120", "type": "image/png" },
    { "src": "/images/icons/icon-152.png", "sizes": "152x152", "type": "image/png" },
    { "src": "/images/icons/icon-167.png", "sizes": "167x167", "type": "image/png" },
    { "src": "/images/icons/icon-180.png", "sizes": "180x180", "type": "image/png" },
    { "src": "/images/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/images/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
  ]
}

The display: "standalone" value removes the Safari browser chrome (address bar, toolbar) when the app is opened from the Home Screen, giving a native-app look.

2

Create App Icons

iOS requires PNG icons at specific sizes. Create the folder GuyStore/wwwroot/images/icons/ and save each PNG there.

File nameSize (px)Used for
icon-76.png76 × 76iPad non-Retina Home Screen
icon-120.png120 × 120iPhone Retina (older models)
icon-152.png152 × 152iPad Retina
icon-167.png167 × 167iPad Pro
icon-180.png180 × 180iPhone 6 Plus / current iPhones
icon-192.png192 × 192Android Chrome PWA (bonus compatibility)
icon-512.png512 × 512Splash screen / App Store preview
✅ Quickest approach

Design one 512 × 512 PNG with the GuyStore logo/branding. Use a free online tool such as realfavicongenerator.net to auto-generate all required sizes from the master image. Download the ZIP and copy the PNGs into the icons folder.

⚠️ iOS does not support SVG icons

All icons must be PNG. Safari on iOS ignores SVG apple-touch-icon links.

3

Add iOS Meta Tags to _Layout.cshtml

Open Views/Shared/_Layout.cshtml and add the following block inside the <head> element, after the existing <meta name="viewport"> tag.

<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.json" />

<!-- iOS Safari – standalone mode -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="GuyStore" />

<!-- iOS Touch Icons (Safari reads these when manifest icons are ignored) -->
<link rel="apple-touch-icon" sizes="180x180" href="/images/icons/icon-180.png" />
<link rel="apple-touch-icon" sizes="167x167" href="/images/icons/icon-167.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/images/icons/icon-152.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/images/icons/icon-120.png" />

<!-- Viewport – viewport-fit=cover fills the iPhone notch/Dynamic Island area -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

<!-- Theme colour for Safari tab bar -->
<meta name="theme-color" content="#1a56db" />
ℹ️ Why both manifest icons and apple-touch-icon tags?

Safari on iOS 14 and earlier ignores manifest.json icons and reads only apple-touch-icon link tags. iOS 15.4+ reads the manifest. Providing both ensures correct icon display on all iOS versions.

4

Register a Service Worker (Offline & Caching Support)

A service worker is optional for the basic PWA install, but it enables the "Add to Home Screen" prompt and can provide an offline splash page. Create a minimal service worker at wwwroot/sw.js:

// sw.js – minimal service worker for GuyStore PWA
const CACHE = 'guystore-v1';
const OFFLINE_URL = '/offline.html';

self.addEventListener('install', e => {
    e.waitUntil(
        caches.open(CACHE).then(c => c.addAll([OFFLINE_URL, '/manifest.json']))
    );
    self.skipWaiting();
});

self.addEventListener('activate', e => {
    e.waitUntil(clients.claim());
});

self.addEventListener('fetch', e => {
    if (e.request.mode === 'navigate') {
        e.respondWith(
            fetch(e.request).catch(() => caches.match(OFFLINE_URL))
        );
    }
});

Create a minimal wwwroot/offline.html page that tells the user they are offline. Then register the service worker at the bottom of _Layout.cshtml, before </body>:

<script>
  if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js')
          .catch(err => console.warn('SW registration failed:', err));
  }
</script>
⚠️ Service worker and SignalR

The service worker above uses a network-first strategy for page navigations, so SignalR WebSocket connections are not intercepted. Do not add SignalR hub URLs (/dashboardHub) to the cache list — service workers cannot proxy WebSocket connections.

5

Deploy Updated App to Azure

Rebuild and redeploy using the same commands as Deployment 1, Steps 5–6:

cd "C:\Guy\Notes\Claud Projects\Guy\GuyStore"

dotnet publish GuyStore.csproj -c Release -o ./publish

Compress-Archive -Path ./publish/* -DestinationPath ./publish.zip -Force

az webapp deploy `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --src-path ./publish.zip `
  --type zip

After deployment, verify the manifest is reachable in a browser: https://guystore-app.azurewebsites.net/manifest.json — it should return the JSON you created in Step 1.

6

Install on iPhone from Safari

These steps are performed on the iPhone by the end user (or during testing).

Install steps

  1. Open Safari on the iPhone. (Do not use Chrome or Firefox.)
  2. Navigate to https://guystore-app.azurewebsites.net
  3. Wait for the page to fully load (the Share button becomes active once the manifest is read).
  4. Tap the Share button — the box-with-upward-arrow icon at the bottom centre of the screen (iPhone) or top right (iPad).
  5. Scroll down the share sheet and tap "Add to Home Screen".
  6. Edit the name if desired (default: "GuyStore") and tap Add in the top-right corner.
  7. The GuyStore icon now appears on the Home Screen. Tap it to launch the app in full-screen standalone mode.

First launch — grant permissions

  1. On the Voice Camera page, tap the camera start button. iOS prompts: "GuyStore would like to access the Camera" → tap Allow.
  2. Tap the mic button. iOS prompts: "GuyStore would like to access the Microphone" → tap Allow.
  3. On the Voice Translate page, tap the mic button. iOS prompts for microphone access → tap Allow.
✅ Standalone mode shows no Safari address bar

When launched from the Home Screen (not from a Safari tab), GuyStore fills the entire screen with no browser chrome. The status bar background uses the theme-color meta tag value (#1a56db).

ℹ️ Permissions are stored per PWA origin

Camera and microphone permissions granted to the PWA installed from guystore-app.azurewebsites.net are stored separately from Safari's permissions. To reset them: iPhone Settings → Privacy & Security → Camera / Microphone → find GuyStore → toggle off and on.


App Store Distribution (Optional)

If App Store distribution is required (e.g. for public consumer download), the web app must be wrapped in a native iOS shell. The recommended approach for an existing .NET app is .NET MAUI Blazor Hybrid, which keeps the entire stack within the .NET ecosystem.

StepToolAction
1 Mac + Xcode 15+ Install Xcode from the Mac App Store and accept the license agreement.
2 Apple Developer Portal Enrol in the Apple Developer Program (developer.apple.com). Approval takes up to 48 hours.
3 .NET 9 SDK on Mac Install the .NET 9 SDK on the Mac and run dotnet workload install maui-ios.
4 .NET MAUI Create a new MAUI Blazor Hybrid project, replace the default Blazor content with the GuyStore Razor views, and configure the iOS platform project bundle ID and signing identity.
5 Xcode Open the .xcodeproj generated by MAUI. Set the Team (Apple Developer account) and Bundle Identifier. Archive the app (Product → Archive).
6 App Store Connect Upload the archive via Xcode Organizer → Distribute App → App Store Connect. Submit for review. Review typically takes 1–3 days.
⚠️ Web Speech API inside MAUI WKWebView

The WKWebView used by MAUI on iOS does not fully expose the Web Speech API to JavaScript. Voice Camera and Voice Translate may require replacement with native MAUI speech APIs (Microsoft.Maui.Media.SpeechToText) if wrapping for App Store distribution.

Voice Feature – iOS Browser Compatibility

The Voice Camera and Voice Translate features depend on browser APIs that have varying levels of support on iOS Safari. The table below reflects behaviour as of iOS 17 / Safari 17.

Browser API iOS Safari 14.x iOS Safari 16.x iOS Safari 17.x Chrome / Firefox on iOS
SpeechRecognition
Voice input (mic → text)
Partial
Requires user gesture, auto-stops on silence
Partial
More reliable, still auto-stops
Yes
Best support; continuous mode limited
No
WebKit engine but API not exposed
MediaDevices.getUserMedia
Camera access
Yes
Requires HTTPS + user permission
Yes Yes Yes
Camera works in Chrome/Firefox too
SpeechSynthesis
Read Aloud in Voice Translate
Partial
Requires user gesture to unlock audio
Yes Yes Yes
Service Worker
Offline / PWA caching
Yes (iOS 14.5+) Yes Yes Yes
PWA "Add to Home Screen"
Standalone install
Yes (Safari only) Yes (Safari only) Yes (Safari only) No

Known iOS Safari Limitations for Voice Features

SpeechRecognition stops automatically on silence

Safari's implementation of SpeechRecognition does not truly support continuous = true mode. It stops recording after a short period of silence (typically 5–8 seconds). The voice-translate.js and voice-camera.js handle the onend event and display a "Tap mic again to continue" message. Users should speak promptly after tapping the mic.

Microphone access requires a user gesture

iOS Safari does not allow recognition.start() to be called without a preceding user tap. Never call recognition.start() from DOMContentLoaded, a timer, or a programmatic trigger — only from inside a click event handler. Both voice scripts already follow this pattern.

SpeechSynthesis requires audio unlocking on older iOS

On iOS 14 and some iOS 15 versions, SpeechSynthesis.speak() is silently ignored unless audio has already been unlocked by a user gesture on the page. The Read Aloud button in Voice Translate is already a direct user-tap trigger, so this is not an issue in practice.

Recommended minimum iOS version

iOS 16.4+ is the recommended minimum for reliable Voice Feature operation. iOS 17+ is preferred. Users on iOS 14.x should be informed that voice recognition may stop unexpectedly or not be available.

ℹ️ Voice Camera works better than Voice Translate on older iOS

The Voice Camera page only needs the microphone briefly (to catch trigger words) and tolerates auto-stop behaviour well — the user simply speaks again. Voice Translate needs a longer dictation window and benefits most from iOS 17's improved SpeechRecognition stability.

Production Configuration Reference

All keys map to appsettings.json and can be overridden by Azure App Settings using double-underscore notation (e.g. Demo__BypassWebhookAuth). Never store secrets in appsettings.json committed to source control — use Azure App Settings or Azure Key Vault for secrets.

Key Development default Production recommendation Notes
ASPNETCORE_ENVIRONMENT Development Production Disables detailed error pages and developer exception pages
Demo:BypassWebhookAuth true false Set to false to enforce HMAC signature verification on Shopify webhooks
Translation:SimulationMode true false (when ready) false routes through MyMemory API (no key, 2 000 chars/day free per IP)
Translation:AzureKey (not set) Set when using Azure Translator Azure Cognitive Services Translator subscription key
Translation:AzureRegion eastus Match your Azure region Only used when AzureKey is set
Kafka:BootstrapServers localhost:9092 Kafka broker address or leave as-is If unreachable, app falls back to in-process Channel<T> automatically
Extensiv:SimulationMode true true until live Extensiv API credentials are available Set to false and supply Extensiv:ApiKey to go live
Techship:SimulationMode true true until live Techship API credentials are available Set to false and supply Techship:ApiKey to go live
UseInMemoryDatabase false false true = EF Core InMemory (demo/test only, data lost on restart); false = SQL Server (requires ConnectionStrings:DefaultConnection). Always InMemory when ASPNETCORE_ENVIRONMENT=Testing.
Fido2:ServerDomain localhost Your production hostname (e.g. yourdomain.com) Relying Party (RP) domain for WebAuthn / passkey ceremonies — must match the browser's origin exactly
Fido2:Origins http://localhost:5090,https://localhost:7091 https://yourdomain.com Comma-separated allowed origins for FIDO2. Add staging URLs if needed.

Quick Azure App Settings block (copy-paste)

az webapp config appsettings set `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --settings `
    "ASPNETCORE_ENVIRONMENT=Production" `
    "Demo__BypassWebhookAuth=false" `
    "Translation__SimulationMode=false" `
    "Extensiv__SimulationMode=true" `
    "Techship__SimulationMode=true" `
    "UseInMemoryDatabase=false" `
    "ConnectionStrings__DefaultConnection=YOUR_SQL_CONNECTION_STRING" `
    "Fido2__ServerDomain=yourdomain.com" `
    "Fido2__Origins=https://yourdomain.com"

Checking settings are applied

# List all current app settings
az webapp config appsettings list `
  --name guystore-app `
  --resource-group GuyStoreRG `
  --output table
✅ Restart the app after changing settings

Azure App Settings changes take effect immediately after save, but ASP.NET Core caches configuration on startup. Restart the app to pick up changes:

az webapp restart --name guystore-app --resource-group GuyStoreRG