Azure Container Apps Deployment
Deploy Jiffoo Mall on Azure using Container Apps and Azure services
Azure Container Apps Deployment
Prerequisites
- Azure CLI 2.40+
- Azure Account with appropriate permissions
- Docker for building images
- Azure Container Registry created
Architecture Overview
This guide deploys Jiffoo Mall using:
- Azure Container Apps for container orchestration
- Azure Container Registry for container images
- Azure Database for PostgreSQL for database
- Azure Cache for Redis for caching
- Azure Key Vault for sensitive configuration
Quick Start
1. Create Resource Group
az group create \
--name jiffoo-mall-rg \
--location eastus2. Create Azure Container Registry
az acr create \
--resource-group jiffoo-mall-rg \
--name jiffooregistry \
--sku Basic
# Login to ACR
az acr login --name jiffooregistry3. Build and Push Images
# Get ACR login server
ACR_LOGIN_SERVER=$(az acr show --name jiffooregistry --query loginServer --output tsv)
# Build and push API
docker build -t $ACR_LOGIN_SERVER/jiffoo/api:latest -f apps/api/Dockerfile .
docker push $ACR_LOGIN_SERVER/jiffoo/api:latest
# Build and push Shop
docker build -t $ACR_LOGIN_SERVER/jiffoo/shop:latest -f apps/shop/Dockerfile .
docker push $ACR_LOGIN_SERVER/jiffoo/shop:latest
# Build and push Admin
docker build -t $ACR_LOGIN_SERVER/jiffoo/admin:latest -f apps/admin/Dockerfile .
docker push $ACR_LOGIN_SERVER/jiffoo/admin:latest4. Create PostgreSQL Database
az postgres flexible-server create \
--resource-group jiffoo-mall-rg \
--name jiffoo-postgres \
--location eastus \
--admin-user postgres \
--admin-password '<your-password>' \
--sku-name Standard_B1ms \
--tier Burstable \
--storage-size 32
# Create database
az postgres flexible-server db create \
--resource-group jiffoo-mall-rg \
--server-name jiffoo-postgres \
--database-name jiffoo
# Configure firewall to allow Azure services
az postgres flexible-server firewall-rule create \
--resource-group jiffoo-mall-rg \
--name jiffoo-postgres \
--rule-name AllowAzureServices \
--start-ip-address 0.0.0.0 \
--end-ip-address 0.0.0.05. Create Redis Cache
az redis create \
--resource-group jiffoo-mall-rg \
--name jiffoo-redis \
--location eastus \
--sku Basic \
--vm-size c06. Create Key Vault
az keyvault create \
--resource-group jiffoo-mall-rg \
--name jiffoo-keyvault \
--location eastus
# Store secrets
az keyvault secret set --vault-name jiffoo-keyvault --name database-url --value "postgresql://postgres:<password>@jiffoo-postgres.postgres.database.azure.com:5432/jiffoo"
az keyvault secret set --vault-name jiffoo-keyvault --name redis-url --value "redis://jiffoo-redis.redis.cache.windows.net:6380?ssl=true"
az keyvault secret set --vault-name jiffoo-keyvault --name jwt-secret --value "<your-jwt-secret>"Container Apps Environment
1. Create Container Apps Environment
az containerapp env create \
--name jiffoo-env \
--resource-group jiffoo-mall-rg \
--location eastus2. Deploy API Container App
az containerapp create \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--environment jiffoo-env \
--image $ACR_LOGIN_SERVER/jiffoo/api:latest \
--target-port 3001 \
--ingress external \
--registry-server $ACR_LOGIN_SERVER \
--registry-username $(az acr credential show -n jiffooregistry --query username -o tsv) \
--registry-password $(az acr credential show -n jiffooregistry --query passwords[0].value -o tsv) \
--cpu 0.5 \
--memory 1.0Gi \
--min-replicas 1 \
--max-replicas 3 \
--env-vars NODE_ENV=production \
--secrets database-url=keyvaultref:<key-vault-uri>/secrets/database-url,identityref:<managed-identity-id> \
redis-url=keyvaultref:<key-vault-uri>/secrets/redis-url,identityref:<managed-identity-id> \
jwt-secret=keyvaultref:<key-vault-uri>/secrets/jwt-secret,identityref:<managed-identity-id>3. Deploy Shop Container App
az containerapp create \
--name jiffoo-shop \
--resource-group jiffoo-mall-rg \
--environment jiffoo-env \
--image $ACR_LOGIN_SERVER/jiffoo/shop:latest \
--target-port 3000 \
--ingress external \
--registry-server $ACR_LOGIN_SERVER \
--registry-username $(az acr credential show -n jiffooregistry --query username -o tsv) \
--registry-password $(az acr credential show -n jiffooregistry --query passwords[0].value -o tsv) \
--cpu 0.25 \
--memory 0.5Gi \
--min-replicas 1 \
--max-replicas 5 \
--env-vars NEXT_PUBLIC_API_URL=https://jiffoo-api.azurecontainerapps.io4. Deploy Admin Container App
az containerapp create \
--name jiffoo-admin \
--resource-group jiffoo-mall-rg \
--environment jiffoo-env \
--image $ACR_LOGIN_SERVER/jiffoo/admin:latest \
--target-port 3003 \
--ingress external \
--registry-server $ACR_LOGIN_SERVER \
--registry-username $(az acr credential show -n jiffooregistry --query username -o tsv) \
--registry-password $(az acr credential show -n jiffooregistry --query passwords[0].value -o tsv) \
--cpu 0.25 \
--memory 0.5Gi \
--min-replicas 1 \
--max-replicas 3 \
--env-vars NEXT_PUBLIC_API_URL=https://jiffoo-api.azurecontainerapps.ioConfiguration
Environment Variables
API Service
| Variable | Description | Example |
|---|---|---|
NODE_ENV | Node environment | production |
DATABASE_URL | PostgreSQL connection string | From Key Vault |
REDIS_URL | Redis connection string | From Key Vault |
JWT_SECRET | JWT signing secret | From Key Vault |
PORT | API port | 3001 |
Shop Service
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_API_URL | API endpoint | https://jiffoo-api.azurecontainerapps.io |
PORT | Shop port | 3000 |
Admin Service
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_API_URL | API endpoint | https://jiffoo-api.azurecontainerapps.io |
PORT | Admin port | 3003 |
Scaling Configuration
Azure Container Apps supports automatic scaling based on HTTP traffic and custom metrics.
Configure HTTP Scaling
az containerapp update \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--min-replicas 1 \
--max-replicas 10 \
--scale-rule-name http-scale \
--scale-rule-type http \
--scale-rule-http-concurrency 50Configure CPU Scaling
az containerapp update \
--name jiffoo-shop \
--resource-group jiffoo-mall-rg \
--min-replicas 1 \
--max-replicas 5 \
--scale-rule-name cpu-scale \
--scale-rule-type cpu \
--scale-rule-metadata type=Utilization value=70Custom Domains
Add Custom Domain
# Add custom domain
az containerapp hostname add \
--hostname shop.yourdomain.com \
--resource-group jiffoo-mall-rg \
--name jiffoo-shop
# Bind SSL certificate
az containerapp ssl upload \
--hostname shop.yourdomain.com \
--resource-group jiffoo-mall-rg \
--name jiffoo-shop \
--certificate-file /path/to/cert.pfx \
--certificate-password <password>Monitoring and Logging
Enable Application Insights
# Create Application Insights
az monitor app-insights component create \
--app jiffoo-insights \
--location eastus \
--resource-group jiffoo-mall-rg
# Get instrumentation key
INSTRUMENTATION_KEY=$(az monitor app-insights component show \
--app jiffoo-insights \
--resource-group jiffoo-mall-rg \
--query instrumentationKey \
--output tsv)
# Update container apps with instrumentation key
az containerapp update \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=$INSTRUMENTATION_KEY"View Logs
# Stream logs
az containerapp logs show \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--follow
# Query logs
az monitor log-analytics query \
--workspace <workspace-id> \
--analytics-query "ContainerAppConsoleLogs_CL | where ContainerAppName_s == 'jiffoo-api' | take 100"Backup and Disaster Recovery
Database Backup
# Enable automated backups (enabled by default)
az postgres flexible-server parameter set \
--resource-group jiffoo-mall-rg \
--server-name jiffoo-postgres \
--name backup_retention_days \
--value 7
# Manual backup
az postgres flexible-server backup create \
--resource-group jiffoo-mall-rg \
--server-name jiffoo-postgres \
--backup-name manual-backup-$(date +%Y%m%d)Redis Backup
# Enable Redis persistence
az redis patch \
--resource-group jiffoo-mall-rg \
--name jiffoo-redis \
--set redisConfiguration.rdb-backup-enabled=true \
--set redisConfiguration.rdb-storage-connection-string="<storage-connection-string>"CI/CD with GitHub Actions
Create .github/workflows/azure-deploy.yml:
name: Deploy to Azure
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Login to ACR
run: az acr login --name jiffooregistry
- name: Build and push API
run: |
docker build -t jiffooregistry.azurecr.io/jiffoo/api:${{ github.sha }} -f apps/api/Dockerfile .
docker push jiffooregistry.azurecr.io/jiffoo/api:${{ github.sha }}
- name: Deploy API to Container Apps
run: |
az containerapp update \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--image jiffooregistry.azurecr.io/jiffoo/api:${{ github.sha }}
- name: Build and push Shop
run: |
docker build -t jiffooregistry.azurecr.io/jiffoo/shop:${{ github.sha }} -f apps/shop/Dockerfile .
docker push jiffooregistry.azurecr.io/jiffoo/shop:${{ github.sha }}
- name: Deploy Shop to Container Apps
run: |
az containerapp update \
--name jiffoo-shop \
--resource-group jiffoo-mall-rg \
--image jiffooregistry.azurecr.io/jiffoo/shop:${{ github.sha }}Cost Optimization
Use Azure Reserved Instances
For predictable workloads, consider Azure Reserved Instances:
- Up to 72% savings compared to pay-as-you-go
- 1-year or 3-year commitment options
Scale to Zero
Configure Container Apps to scale to zero during off-hours:
az containerapp update \
--name jiffoo-shop \
--resource-group jiffoo-mall-rg \
--min-replicas 0 \
--max-replicas 5Use Spot Instances
For non-critical workloads, consider using Azure Spot VMs (when available for Container Apps).
Troubleshooting
Container App Not Starting
# Check revision status
az containerapp revision list \
--name jiffoo-api \
--resource-group jiffoo-mall-rg
# View container logs
az containerapp logs show \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--tail 100Database Connection Issues
# Test database connectivity
az postgres flexible-server connect \
--name jiffoo-postgres \
--admin-user postgres
# Check firewall rules
az postgres flexible-server firewall-rule list \
--resource-group jiffoo-mall-rg \
--name jiffoo-postgresPerformance Issues
# Check resource utilization
az containerapp show \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--query "properties.template.containers[0].resources"
# Scale up resources if needed
az containerapp update \
--name jiffoo-api \
--resource-group jiffoo-mall-rg \
--cpu 1.0 \
--memory 2.0GiSecurity Best Practices
- Use Managed Identity instead of service principals where possible
- Enable Key Vault for all sensitive configuration
- Configure firewall rules to restrict database access
- Enable HTTPS only for all container apps
- Regular security updates - rebuild and redeploy containers monthly
- Enable Azure Defender for Container Apps