Jiffoo Docs

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 eastus

2. Create Azure Container Registry

az acr create \
  --resource-group jiffoo-mall-rg \
  --name jiffooregistry \
  --sku Basic

# Login to ACR
az acr login --name jiffooregistry

3. 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:latest

4. 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.0

5. Create Redis Cache

az redis create \
  --resource-group jiffoo-mall-rg \
  --name jiffoo-redis \
  --location eastus \
  --sku Basic \
  --vm-size c0

6. 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 eastus

2. 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.io

4. 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.io

Configuration

Environment Variables

API Service

VariableDescriptionExample
NODE_ENVNode environmentproduction
DATABASE_URLPostgreSQL connection stringFrom Key Vault
REDIS_URLRedis connection stringFrom Key Vault
JWT_SECRETJWT signing secretFrom Key Vault
PORTAPI port3001

Shop Service

VariableDescriptionExample
NEXT_PUBLIC_API_URLAPI endpointhttps://jiffoo-api.azurecontainerapps.io
PORTShop port3000

Admin Service

VariableDescriptionExample
NEXT_PUBLIC_API_URLAPI endpointhttps://jiffoo-api.azurecontainerapps.io
PORTAdmin port3003

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 50

Configure 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=70

Custom 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 5

Use 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 100

Database 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-postgres

Performance 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.0Gi

Security Best Practices

  1. Use Managed Identity instead of service principals where possible
  2. Enable Key Vault for all sensitive configuration
  3. Configure firewall rules to restrict database access
  4. Enable HTTPS only for all container apps
  5. Regular security updates - rebuild and redeploy containers monthly
  6. Enable Azure Defender for Container Apps

Additional Resources

On this page