DEV Community

Cover image for A Step-by-Step Guide to CI/CD Pipeline for Angular App with Azure Container Apps
Hassan Aftab
Hassan Aftab

Posted on

4 1 1 1 1

A Step-by-Step Guide to CI/CD Pipeline for Angular App with Azure Container Apps

Table of Contents

  1. Prerequisites
  2. Step 1: Dockerfile
  3. Step 2: Azure Pipelines Configuration
  4. Step 3: Additional Azure CLI Configuration
  5. Best Practices
  6. Troubleshooting
  7. Conclusion
  8. Resources
  9. Dockerizing Other Technology Stacks

Prerequisites

  • Azure DevOps account
  • Azure Subscription
  • Angular project
  • Azure CLI installed
  • Docker installed
  • Azure Container Registry
  • Azure Container Apps environment

Step 1: Dockerfile

# Stage 1: Build Angular application
FROM node:16-alpine AS build
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build --configuration=production

# Stage 2: Serve with Nginx
FROM nginx:alpine
COPY --from=build /usr/src/app/dist/your-angular-app /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Enter fullscreen mode Exit fullscreen mode

Step 2: Azure Pipelines Configuration

trigger:
  - main

variables:
  # Azure Container Registry details
  acrName: 'yourcontainerregistry'
  imageRepository: 'angular-app'
  dockerfilePath: 'Dockerfile'
  tag: '$(Build.BuildId)'

  # Azure Container Apps details
  containerAppName: 'your-container-app-name'
  resourceGroup: 'your-resource-group'

stages:
- stage: Build
  displayName: Build and Test
  jobs:
  - job: BuildAndTest
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '16.x'
      displayName: 'Install Node.js'

    - script: |
        npm ci
        npm run lint
        npm run test -- --watch=false --browsers=ChromeHeadless
      displayName: 'npm install, lint, and test'

    - task: Docker@2
      displayName: 'Build Docker Image'
      inputs:
        command: build
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        tags: 
          - $(tag)
          - latest

    - task: Docker@2
      displayName: 'Push to Azure Container Registry'
      inputs:
        command: push
        repository: $(imageRepository)
        containerRegistry: $(acrServiceConnection)
        tags: 
          - $(tag)
          - latest

- stage: Approval
  displayName: Deployment Approval
  jobs:
  - job: ApprovalJob
    pool: server
    steps:
    - task: ManualValidation@0
      inputs:
        instructions: 'Please review and approve the deployment'
        onTimeout: 'reject'
        timeoutInMinutes: 120

- stage: Deploy
  displayName: Deploy to Azure Container Apps
  dependsOn: 
    - Build
    - Approval
  condition: succeeded()
  jobs:
  - deployment: DeployToContainerApp
    pool: 
      vmImage: 'ubuntu-latest'
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureCLI@2
            displayName: 'Deploy to Azure Container Apps'
            inputs:
              azureSubscription: 'Your-Azure-Subscription'
              scriptType: 'bash'
              scriptLocation: 'inlineScript'
              inlineScript: |
                # Login to Azure Container Registry
                az acr login --name $(acrName)

                # Update Container App with new image
                az containerapp update \
                  --name $(containerAppName) \
                  --resource-group $(resourceGroup) \
                  --image $(acrName).azurecr.io/$(imageRepository):$(tag)
Enter fullscreen mode Exit fullscreen mode

Step 3: Additional Azure CLI Configuration

Before running the pipeline, set up your Azure Container Apps:

# Create Container Registry
az acr create --resource-group your-resource-group \
              --name yourcontainerregistry \
              --sku Basic

# Create Container Apps Environment
az containerapp env create \
  --name your-container-app-environment \
  --resource-group your-resource-group \
  --location eastus

# Create Container App
az containerapp create \
  --name your-container-app-name \
  --resource-group your-resource-group \
  --environment your-container-app-environment \
  --image yourcontainerregistry.azurecr.io/angular-app:latest \
  --target-port 80 \
  --ingress external
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Use Azure Key Vault for sensitive configurations
  • Implement comprehensive testing before deployment
  • Use managed identities for secure access
  • Set up proper RBAC for deployment
  • Configure health checks in Container Apps
  • Use staging slots for zero-downtime deployments

Troubleshooting

  • Verify network configurations
  • Check container logs in Azure Portal
  • Ensure proper IAM roles are assigned
  • Validate ACR permissions
  • Check Container Apps network settings

Conclusion

This pipeline provides a robust CI/CD workflow for deploying an Angular application to Azure Container Apps with a manual approval stage.

Resources

so in summary, The pipeline includes:

  • Build and test stage
  • Manual approval stage
  • Deployment to Azure Container Apps
  • Azure Container Registry integration

Dockerizing Other Technology Stacks

The Dockerfile approach demonstrated for the Angular application can be easily adapted to other popular technology stacks as well

Billboard image

Imagine monitoring that's actually built for developers

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitor creation and configuration with Monitoring as Code.

Start Monitoring

Top comments (0)

Billboard image

Try REST API Generation for Snowflake

DevOps for Private APIs. Automate the building, securing, and documenting of internal/private REST APIs with built-in enterprise security on bare-metal, VMs, or containers.

  • Auto-generated live APIs mapped from Snowflake database schema
  • Interactive Swagger API documentation
  • Scripting engine to customize your API
  • Built-in role-based access control

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay