A hands-on workshop for learning container technologies and Azure deployment strategies. This workshop guides you through containerizing applications, building Docker images, and deploying to various Azure services.
This workshop teaches you how to:
- Containerize applications using Docker
- Build and run containers locally
- Deploy containers to Azure App Service
- Deploy containers to Azure Container Apps
- Deploy containers to Azure Kubernetes Service (AKS)
Complete the tasks in order to build your skills progressively:
- Local Docker Setup - Learn Docker basics, build images, and run containers locally
- Azure App Service Deployment - Deploy containers to Azure App Service with ACR
- Azure Container Apps Deployment - Deploy to serverless Container Apps with auto-scaling
- Azure Kubernetes Service (AKS) Deployment - Deploy to AKS for production-grade orchestration
workshop.containers/
βββ docs/ # Workshop documentation
β βββ en/ # English language tasks
βββ eng/ # Engineering and deployment resources
β βββ infrastructure/ # Bicep infrastructure-as-code
β β βββ main.bicep # Main infrastructure template
β β βββ main-app-services.bicep # App Service specific template
β β βββ main-container-apps.bicep # Container Apps specific template
β β βββ main-aks.bicep # AKS specific template
β β βββ deploy.ps1 # Deployment script
β β βββ destroy.ps1 # Clean-up script
β β βββ modules/ # Reusable Bicep modules
β βββ kubernetes/ # Kubernetes manifests
β βββ api-deployment.yaml # API deployment definition
β βββ frontend-deployment.yaml # Frontend deployment definition
β βββ ingress.yaml # Ingress configuration
β βββ deploy.ps1 # Kubernetes deployment script
βββ scripts/ # Utility scripts
β βββ utils.ps1 # PowerShell utilities
βββ src/ # Application source code
β βββ Frontend/ # Frontend application (nginx + vanilla JS)
β β βββ index.html # Main HTML page
β β βββ app.js # JavaScript application logic
β β βββ styles.css # Application styles
β β βββ nginx.conf # Nginx configuration
β β βββ docker-entrypoint.sh # Container entrypoint script
β β βββ Dockerfile # Frontend container definition
β β βββ build.ps1 # Build script
β β βββ deploy.ps1 # Deployment script
β β βββ start.ps1 # Local development script
β βββ WebApi/ # Backend API (.NET 9)
β βββ Program.cs # API entry point
β βββ WebApi.csproj # .NET project file
β βββ appsettings.json # Application configuration
β βββ Dockerfile # API container definition
β βββ build.ps1 # Build script
β βββ deploy.ps1 # Deployment script
β βββ start.ps1 # Local development script
βββ check-prerequisites.ps1 # Prerequisites checker
βββ global.json # .NET SDK version specification
βββ Workshop.sln # Visual Studio solution file
The workshop includes two microservices that work together to create a pizza ordering system:
A REST API built with .NET 9 (ASP.NET Core Minimal APIs) that provides:
- Pizza Catalog: GET
/pizzas- Returns a list of available pizzas with descriptions and ingredients - Basket Management:
- GET
/basket- Retrieve current basket - POST
/basket- Add items to basket - PUT
/basket/{id}- Update basket item quantity - DELETE
/basket/{id}- Remove item from basket
- GET
- Order Processing: POST
/order- Confirm and place an order
Key Features:
- In-memory basket storage (singleton service)
- CORS enabled for cross-origin requests
- OpenAPI/Swagger support in development mode
- Runs on port 8080 in containers
A single-page application built with vanilla JavaScript and served by nginx that provides:
- Browse available pizzas
- View pizza details, descriptions, and ingredients
- Add pizzas to basket with quantity selection
- View and modify basket contents
- Place orders
Key Features:
- Lightweight nginx-based static file serving
- Dynamic API URL configuration via environment variables
- Responsive design with modern CSS
- Runs on port 8080 in containers
Both applications use multi-stage Docker builds for optimized images:
# Stage 1: Build - Uses SDK to compile the application
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
# - Restores NuGet packages
# - Compiles and publishes the app
# Stage 2: Runtime - Uses smaller runtime-only image
FROM mcr.microsoft.com/dotnet/aspnet:9.0
# - Copies published binaries from build stage
# - Runs as non-root user for security
# - Exposes port 8080Benefits:
- Smaller final image (runtime vs SDK)
- Layer caching for faster rebuilds
- Secure non-root execution
- Optimized for production
# Stage 1: Build - Prepares static files
FROM nginx:alpine AS build
# - Copies HTML, CSS, JS files
# - Configures nginx
# - Sets up entrypoint script
# Stage 2: Runtime - Minimal nginx image
FROM nginx:alpine
# - Copies configured files from build stage
# - Exposes port 8080
# - Dynamic API URL configuration via entrypointBenefits:
- Minimal Alpine-based image (~25MB)
- Runtime API URL configuration
- Custom nginx settings for SPA routing
- Fast startup and low memory footprint
Run containers locally with Docker:
# Build and run WebApi
cd src\WebApi
.\build.ps1
.\start.ps1
# Build and run Frontend
cd src\Frontend
.\build.ps1
.\start.ps1 -ApiUrl "http://localhost:8081"Deploy containers to Azure App Service for a fully managed PaaS experience:
- Uses Azure Container Registry (ACR) for image storage
- Deployed via Bicep templates
- Manual container configuration in Azure Portal
- Built-in scaling and SSL
cd eng\infrastructure
.\deploy.ps1 -DeploymentType "AppService"Deploy to Azure Container Apps for serverless container hosting:
- Automatic scaling (including scale-to-zero)
- Built-in revision management
- Traffic splitting between revisions
- Simplified networking and ingress
Make sure that the container images are pushed to ACR before deploying.
cd eng\infrastructure
.\deploy.ps1 -DeploymentType "ContainerApps"Deploy to AKS for full Kubernetes orchestration:
- Complete control over container orchestration
- Kubernetes-native tools (kubectl, helm)
- Advanced deployment strategies
- Production-grade cluster management
cd eng\infrastructure
.\deploy.ps1 -DeploymentType "AKS"
# Deploy applications to AKS
cd eng\kubernetes
.\deploy.ps1Before starting the workshop, ensure you have:
- Docker Desktop or Rancher Desktop (with Docker CLI)
- PowerShell Core (PowerShell 7+)
- Azure CLI (for cloud deployments)
- .NET 9 SDK (for local .NET development)
- Git (to clone the repository)
- kubectl (for AKS deployments)
- Visual Studio Code (recommended)
Run the prerequisites checker:
.\check-prerequisites.ps1- Clone the repository (if not already done)
- Run the prerequisites checker to verify your setup
- Start with Task 1 - Local Docker Setup
- Progress through each task sequentially
- Experiment with different deployment options
To remove Azure resources and avoid charges:
cd eng\infrastructure
.\destroy.ps1By completing this workshop, you will:
- β Understand Docker fundamentals and multi-stage builds
- β Build and run containers locally
- β Use Azure Container Registry for image management
- β Deploy containers to Azure App Service
- β Work with Azure Container Apps and revisions
- β Deploy and manage applications on AKS
- β Write infrastructure-as-code with Bicep
- β Work with Kubernetes manifests and kubectl
This workshop is provided for educational purposes.