Day 3 presentation1 / 29

Zero to MVP AI Bootcamp

Deploy apps, backend & cloud on Azure

Move the Flutter app and NestJS API from GitHub into a secure, observable Azure environment with an automated delivery pipeline.

Today you ship

An installable Flutter build and production-ready NestJS container on Azure, connected safely to Supabase and Stripe and deployed through GitHub Actions.

Scroll to move through the presentation.

Learning objectives2 / 29

By the end of today

  1. 1Draw the production path from the Flutter app through the NestJS API to Supabase, Stripe, and Azure services.
  2. 2Create an Azure resource group with a deliberate region, naming convention, ownership, and budget boundary.
  3. 3Prepare the NestJS backend for containers using runtime configuration, a health endpoint, logs, and the platform port.
  4. 4Build and publish the backend image, then deploy it to Azure Container Apps over HTTPS.
  5. 5Protect the GitHub repository and automate backend validation, image publishing, and Azure deployment with GitHub Actions.
  6. 6Store runtime secrets outside source code and configure Supabase and Stripe safely.
  7. 7Create development and production environments for Flutter without embedding server secrets.
  8. 8Build an installable mobile release that calls the live backend.
  9. 9Use Azure logs, health checks, revisions, and cost controls to diagnose and recover from failure.
Run of show3 / 29

Today’s learning path

  1. Module 130 min

    Design the production architecture

  2. Module 235 min

    Set up the Azure foundation

  3. Module 340 min

    Prepare NestJS for production

  4. Module 445 min

    Deploy the backend to Azure

  5. Module 540 min

    Automate delivery with GitHub Actions

  6. Module 635 min

    Configure secrets and integrations

  7. Module 740 min

    Build the Flutter release

  8. Module 835 min

    Observe, troubleshoot, and recover

  9. Guided build

    AI Service Booking Marketplace · Stage 3

    Build, test, checkpoint, and ship.

Module 1 · Learn · 30 min4 / 29

Design the production architecture

Deployment begins with a map of responsibilities and trust boundaries. The Flutter app is installed on a user's device and calls the public NestJS API. Azure runs the protected API, Supabase stores marketplace records, and Stripe processes test payments and sends signed events back to the backend.

A real example

The customer taps Pay deposit in Flutter. NestJS creates the Stripe checkout request, Stripe handles payment, a signed webhook reaches NestJS, and Supabase records the verified result before the app displays confirmation.

Technical terms

Trust boundary
A point where data moves between environments with different permissions, such as a phone, public API, database, or payment provider.
Runtime
The environment in which deployed application code is actively executed.
Module 1 · Diagram5 / 29

Flutter to Azure production journey

The mobile client uses one public backend boundary while protected integrations remain on the server.

  1. 1

    Flutter app

    Collects user input and sends an authenticated HTTPS request.

  2. 2

    Azure ingress

    Receives traffic at the public Container App address.

  3. 3

    NestJS API

    Validates identity and input, then applies business rules.

  4. 4

    Supabase

    Stores users, services, bookings, and verified payment state.

  5. 5

    Stripe

    Processes the test payment and signs the completion webhook.

  6. 6

    NestJS webhook

    Verifies the event before changing booking state.

  7. 7

    Mobile result

    The app refreshes trusted status and displays confirmation or recovery.

The phone never receives database administrator credentials, the Stripe secret key, or webhook signing secret.

Module 1 · Apply it6 / 29

Apply the concept

Draw one request from the Flutter screen through NestJS, Supabase, and Stripe, then back to the user.

  1. 1Place Flutter, NestJS, Azure, Supabase, and Stripe on one architecture page.
  2. 2Draw each request and response in the booking and payment journey.
  3. 3Mark public endpoints, authenticated requests, server-only actions, and external callbacks.
  4. 4Label every configuration value as public, sensitive, or secret.

Success looks like

A teammate can trace the live booking journey and identify where each component runs, which party initiates each request, and where credentials are allowed.

Watch for

  • The Flutter package is public to whoever installs it, so anything inside it must be treated as discoverable.
  • Supabase is still an external production dependency even though the NestJS backend runs on Azure.
Module 2 · Learn · 35 min7 / 29

Set up the Azure foundation

Azure resources need an intentional home before deployment. A subscription is the billing and policy scope. A resource group is the lifecycle boundary for this application. Region, names, tags, access roles, and budgets make the environment understandable and controllable.

A real example

The marketplace uses one workshop resource group in a selected region. Its registry, Container Apps environment, backend, and monitoring resources share consistent names and ownership tags.

Technical terms

Resource group
An Azure container for related resources that share ownership, lifecycle, access, and cost reporting.
RBAC
Role-Based Access Control: Azure permissions assigned to identities at a defined scope.
Module 2 · Reference8 / 29

Azure scopes in plain language

ConceptPurposeMarketplace decision
TenantIdentity and organizational directoryUse the approved organization or workshop tenant
SubscriptionBilling, quota, and policy boundaryConfirm the subscription before deployment
Resource groupApplication lifecycle and cost groupingKeep workshop cloud resources together
RegionPhysical service locationChoose one supported region deliberately
RBAC rolePermitted Azure operationsGrant least privilege at the smallest useful scope
BudgetSpend visibility and alertsSet thresholds before the first deployment
Module 2 · Apply it9 / 29

Apply the concept

Create the project resource group, naming sheet, ownership tags, and a budget alert.

  1. 1Confirm the correct tenant and subscription before creating anything.
  2. 2Choose one supported region using user location, service availability, and policy requirements.
  3. 3Create the resource group and agree on short, consistent resource names and tags.
  4. 4Assign only required access and create a budget alert for the workshop environment.

Success looks like

Every resource has a known subscription, resource group, region, owner, purpose, and cost boundary.

Watch for

  • If the expected subscription is missing, stop before creating resources under a personal or incorrect account.
  • A budget alert warns about spend but does not automatically stop resources; replica limits and cleanup still matter.
Module 3 · Learn · 40 min10 / 29

Prepare NestJS for production

A backend that works in a local development process is not automatically ready for a managed container. Production readiness means a repeatable image, validated runtime configuration, correct network binding, a health endpoint, safe logs, and predictable startup and shutdown.

A real example

Azure chooses the container's runtime settings. NestJS reads the assigned port, listens on all interfaces, validates required Supabase and Stripe values at startup, and reports health without revealing secrets.

Technical terms

Container image
An immutable package containing the compiled application and production runtime dependencies.
Health endpoint
A small endpoint used to show whether the running service can respond and, when appropriate, reach critical dependencies.
Module 3 · Apply it11 / 29

Apply the concept

Build and run the production container locally, then test health, Supabase access, and one Stripe test request.

  1. 1Create or inspect the multi-stage Dockerfile and exclude local files, credentials, and development dependencies.
  2. 2Read configuration from validated environment variables and bind NestJS to the platform port on all interfaces.
  3. 3Add a lightweight health endpoint and structured logs with request identifiers.
  4. 4Build and run the production image locally, then test startup, health, Supabase access, and one Stripe test action.

Use this prompt

Review this NestJS backend for Azure Container Apps readiness. Check its Docker stages, production command, host and port binding, environment validation, health endpoint, graceful shutdown, logs, and secret handling. Explain blockers first, then propose the smallest changes. Do not place secrets in the Dockerfile or image.

Success looks like

The production image starts from a clean environment, responds to health checks, reaches required dependencies, and logs useful failures without exposing private values.

Watch for

  • If the container exits immediately, inspect the first startup error and validate required configuration.
  • If it works locally but cannot receive platform traffic, verify host binding, target port, and ingress configuration.
Module 4 · Learn · 45 min12 / 29

Deploy the backend to Azure

Azure Container Registry stores versioned application images. Azure Container Apps runs a selected image as a managed HTTPS service, creates a revision for configuration or image changes, and can scale replicas within explicit limits.

A real example

The class publishes a NestJS image tagged with the release identifier, creates the marketplace API Container App, exposes only HTTPS ingress, and verifies the active revision before connecting Flutter.

Technical terms

Container registry
A private service that stores and distributes versioned container images.
Revision
An immutable version of an Azure Container App created from a specific image and configuration.
Module 4 · Apply it13 / 29

Apply the concept

Push a tagged image, create the Container App, verify its health URL, and record the active revision.

  1. 1Create the registry and Container Apps environment inside the approved resource group and region.
  2. 2Build the production image, give it a traceable tag, and publish it to the registry.
  3. 3Create the Container App with the correct target port, external HTTPS ingress, CPU, memory, and replica limits.
  4. 4Open the health endpoint, inspect the active revision, and record the public backend URL.

Use this prompt

Create a deployment checklist for this Dockerized NestJS API using Azure Container Registry and Azure Container Apps. Include placeholders for subscription, resource group, region, registry, image tag, environment, app name, target port, health URL, and replica limits. Explain every command before it runs and stop if the active Azure context is unexpected.

Success looks like

A traceable backend revision is healthy at an Azure HTTPS address and its image, configuration, and resource ownership can be identified.

Watch for

  • Do not reuse an unversioned image tag as proof of what is deployed; record a unique release tag or digest.
  • If the revision is unhealthy, inspect revision and container logs before changing several settings at once.
Module 5 · Learn · 40 min14 / 29

Automate delivery with GitHub Actions

GitHub is the shared source of truth for code, review, and release history. GitHub Actions turns repository events into repeatable checks and deployments. A pull request proves the change is safe to merge; an approved main-branch commit builds one traceable image, publishes it to Azure Container Registry, and deploys that same artifact to Azure Container Apps.

A real example

A developer opens a pull request for the NestJS API. GitHub Actions installs locked dependencies, runs lint, tests, type checks, and a container build. After review and merge, the deployment job authenticates to Azure with a short-lived identity, publishes an image tagged with the commit SHA, deploys it, and verifies the health endpoint.

Technical terms

CI/CD
Continuous Integration and Continuous Delivery: automatically validate changes and deliver approved versions through a repeatable pipeline.
OpenID Connect
A federation method that lets GitHub request short-lived Azure access for a specific repository and workflow instead of storing a permanent cloud password.
Module 5 · Reference15 / 29

GitHub Actions: what to do and what not to do

ConceptDoDo not
Source controlUse branches, small commits, pull requests, and reviewPush unreviewed production changes directly to main
ValidationRequire lint, tests, type checks, and container validationDeploy merely because the code compiled on one laptop
IdentityUse OpenID Connect and least-privilege Azure rolesStore a permanent Azure password or broad owner credential
SecretsLimit secrets to approved environments and runtime servicesExpose production secrets to pull-request jobs or logs
ArtifactTag one image with the commit SHA and deploy that exact imageRely only on a mutable latest tag or rebuild unknown code
ReleaseRequire approval, health verification, and rollback evidenceAssume a green workflow means the user journey works

Repository checks protect code quality. Azure runtime secrets still belong in the deployment platform, not in workflow YAML.

Module 5 · Diagram16 / 29

GitHub to Azure delivery pipeline

Review first, then build and deploy one traceable artifact through controlled identities and environments.

  1. 1

    Feature branch

    A focused code change is committed without secrets.

  2. 2

    Pull request

    Reviewers inspect the change, purpose, and risk.

  3. 3

    CI checks

    GitHub Actions runs lint, tests, types, and container validation.

  4. 4

    Approved merge

    Required review and green checks permit main to advance.

  5. 5

    OIDC login

    The approved workflow receives short-lived, scoped Azure access.

  6. 6

    Build + publish

    One image tagged with the commit SHA enters Azure Container Registry.

  7. 7

    Deploy revision

    Azure Container Apps runs that exact image as a new revision.

  8. 8

    Verify or roll back

    Health and journey checks accept the release or restore the healthy revision.

The pipeline can deploy the backend automatically. Mobile store distribution needs its own signing, review, and release workflow.

Module 5 · Apply it17 / 29

Apply the concept

Create the workflow, open a pull request, inspect the checks, approve production, and verify the deployed revision.

  1. 1Protect the main branch and require pull requests, review, and successful validation checks.
  2. 2Create a pull-request workflow that uses locked dependencies and runs lint, tests, type checks, and the production container build.
  3. 3Create a production GitHub environment with required approval and only the non-secret deployment configuration it needs.
  4. 4Configure GitHub-to-Azure OpenID Connect with least-privilege access to the registry and Container App.
  5. 5On an approved main-branch change, tag the image with the commit SHA, publish it once, deploy that exact artifact, and run a health smoke test.
  6. 6Inspect the workflow summary, Azure revision, image tag, and deployment URL, then rehearse rollback to the previous healthy revision.

Use this prompt

Design a secure GitHub Actions pipeline for this Dockerized NestJS API and Azure Container Apps. Separate pull-request validation from production deployment. Include locked dependency installation, lint, tests, type checks, container build, immutable commit-SHA image tag, Azure Container Registry push, GitHub environment approval, OpenID Connect authentication, Container App deployment, health smoke test, concurrency control, and rollback evidence. Explain required repository settings and permissions before writing YAML. Do not use long-lived Azure credentials or expose application secrets to pull-request jobs.

Success looks like

An invalid pull request is blocked, while an approved main-branch commit produces one traceable image and a healthy Azure revision with visible GitHub deployment history.

Watch for

  • Do not run untrusted pull-request code with production secrets or write permissions.
  • Do not deploy a mutable latest tag when the release must be traced to a specific commit.
  • If validation and deployment rebuild separately, prove they produce the same artifact or publish once and promote that image.
Module 6 · Learn · 35 min18 / 29

Configure secrets and integrations

Deployment separates public client configuration from server secrets. Flutter may know the public API address and publishable Stripe key. NestJS alone receives privileged Supabase and Stripe values through runtime secret references.

A real example

The Stripe secret key and webhook signing secret are configured on the Container App. Stripe sends test events to the Azure webhook URL, and NestJS verifies the signature before updating Supabase.

Technical terms

Secret reference
A runtime setting that refers to protected secret storage instead of embedding the value in code or an image.
Webhook signature
Cryptographic evidence used to verify that an incoming event was sent by the expected provider and was not altered.
Module 6 · Apply it19 / 29

Apply the concept

Configure runtime values, register the Stripe test webhook, and prove that no secret appears in Git or the Flutter bundle.

  1. 1Classify every Flutter, NestJS, Supabase, and Stripe value as public or secret.
  2. 2Configure backend secrets as Container App secret references and keep them out of source and image layers.
  3. 3Register the Azure HTTPS webhook in Stripe test mode and verify the signature using the raw request body.
  4. 4Review CORS, Supabase redirect URLs, database policies, and logs for the production origin.

Use this prompt

Audit this Flutter, NestJS, Supabase, Stripe, and Azure configuration. Create a table with value, owner, public-or-secret classification, allowed location, rotation action, and exposure test. Treat service-role keys, Stripe secret keys, and webhook signing secrets as server-only.

Success looks like

The live integrations work, every sensitive value has one approved runtime location, and no privileged credential appears in Git, image history, logs, or the Flutter package.

Watch for

  • Changing a webhook URL usually creates or requires a corresponding signing secret; do not assume the local secret is valid in Azure.
  • CORS is a browser control, not authentication, and it does not replace Supabase authorization policies.
Module 7 · Learn · 40 min20 / 29

Build the Flutter release

A mobile app is not hosted like the API. Flutter produces signed Android or iOS artifacts that are installed or distributed. Build-time environments keep local and production API addresses separate, while server credentials remain outside the package.

A real example

The production flavor points to the Azure HTTPS API. The signed build is installed on a physical phone and completes login, booking, and Stripe test payment without referring to localhost.

Technical terms

Build flavor
A named application configuration, such as development or production, with its own identifiers and public settings.
App signing
Cryptographically signing a mobile release so devices and stores can verify its publisher and updates.
Module 7 · Apply it21 / 29

Apply the concept

Create a production build, install it on a device, and complete one booking against the Azure API.

  1. 1Create development and production configurations with explicit API addresses and public client values.
  2. 2Remove localhost assumptions and confirm timeout, offline, expired-session, and API-error behavior.
  3. 3Build the signed Android or iOS release artifact using the approved workshop path.
  4. 4Install it on a physical device and complete the live booking and Stripe test journey.

Use this prompt

Review this Flutter app for a production build that calls the Azure NestJS API. Check environment selection, API URL, public versus secret values, Android/iOS network settings, signing requirements, error states, and release commands. Identify any value that must not be compiled into the app.

Success looks like

An installable production build uses the Azure API and completes the core journey on a physical device without containing server credentials.

Watch for

  • A simulator may reach a host address that a physical phone cannot; always test the real Azure HTTPS URL on a device.
  • Do not put Supabase service-role credentials, Stripe secret keys, or Azure credentials in Flutter build variables.
Module 8 · Learn · 35 min22 / 29

Observe, troubleshoot, and recover

A deployment is complete only when the team can see its health and recover from failure. Azure revision status, container logs, request evidence, metrics, replica settings, and budgets provide the operational picture.

A real example

A revision starts with a missing Supabase value and fails health checks. The team finds the startup error, restores traffic to the healthy revision, corrects the configuration, and retests from the phone.

Technical terms

Observability
The ability to understand a running system from logs, metrics, traces, health, and other evidence.
Rollback
Restoring traffic to a previously healthy application revision.
Module 8 · Apply it23 / 29

Apply the concept

Trigger one safe configuration failure, locate the evidence, restore the healthy revision, and rerun the mobile smoke test.

  1. 1Record the healthy revision, image tag, health result, and baseline core journey.
  2. 2Trigger one instructor-approved configuration failure without changing production data.
  3. 3Use Azure revision state and logs to identify the first real cause.
  4. 4Restore the healthy revision, rerun the mobile smoke test, and verify budget and replica limits.

Use this prompt

Create an Azure Container Apps incident worksheet with time, active revision, image, symptom, health state, relevant logs, suspected cause, safe rollback, verification, and follow-up. Exclude secrets and private customer content.

Success looks like

The team can identify the live revision, explain a controlled failure from evidence, restore service, and prove the mobile journey works afterward.

Watch for

  • Do not delete the last healthy revision before the new release and mobile smoke test pass.
  • If logs are noisy, correlate one request or startup attempt rather than reading unrelated messages.
Guided project24 / 29

Build brief

AI Service Booking Marketplace · Stage 3

Deploy the working NestJS backend from GitHub to Azure through GitHub Actions and connect an installable Flutter release to the live environment.

User story

As a mobile user, I can complete the existing booking and test-payment journey against a secure, observable cloud backend.

Guided build · Part 125 / 29

Build it step by step

1

Map the live architecture

Document each request, trust boundary, public endpoint, secret, and external dependency.

2

Create the Azure foundation

Set the resource group, region, names, tags, access, budget, and required providers.

3

Harden the NestJS runtime

Validate configuration, expose health, emit safe logs, and build the production container.

Guided build · Part 226 / 29

Build it step by step

4

Publish and deploy

Push the tagged image to Azure Container Registry and run it on Azure Container Apps.

5

Automate with GitHub Actions

Validate pull requests and deploy approved main-branch commits using short-lived Azure access.

6

Connect Supabase and Stripe

Set runtime secrets, allowed URLs, and the signed Stripe test webhook.

Guided build · Part 327 / 29

Build it step by step

7

Build the mobile release

Use the production API environment, sign the app, and install it on a physical device.

8

Prove and recover

Complete the live journey, inspect logs, trigger a safe failure, and restore the healthy revision.

Ship checkpoint28 / 29

Do not ship until

  • The NestJS health endpoint responds over the Azure HTTPS address.
  • GitHub blocks an invalid pull request and records the successful production deployment.
  • The workflow uses short-lived Azure authentication and does not contain cloud passwords.
  • The Flutter production build is installed and uses the live API rather than localhost.
  • Supabase reads and writes work through the deployed backend.
  • A Stripe test payment reaches a signature-verified webhook.
  • Server secrets are absent from Git, the container image, logs, and the mobile bundle.
  • Azure logs identify a controlled failure and the known-good revision can be restored.
  • A budget alert and replica limits are configured for the workshop environment.
Wrap and prepare29 / 29

Ship it. Show it. Prepare the next move.

Before the next day

  • Keep the Azure backend running and record any failure observed from the mobile app.
  • Define one narrow job the marketplace agent should perform on Day 4.
  • List the NestJS actions the agent may call and which actions require human confirmation.