Skip to main content

Azure DevOps Pipeline: Build Container Image and push the Image to Azure Container Registry

729 words·
Azure Azure DevOps CI Pipeline Container Registry Docker
Azure-DevOps - This article is part of a series.
Part 2: This Article

This tutorial uses an Azure Container Registry, for more details about it, check out my previous post.

Azure DevOps Organization
#


Add SSH Key
#

Add your public SSH key:

# List (default) public SSH key (Windows)
C:\Users\username\.ssh\id_rsa.pub

# Add your public SSH key to Azure DevOps
https://dev.azure.com/jueklu/_usersSettings/keys

Create Project
#

Create a new Azure DevOps Project, mine is called Project1.


Create Repository
#

Create a new repository in the project:


Switch to new Repository
#

Open the newly created repository:

  • Go to: Project1 > “Repos”

  • Click jueklu / Project1 / Repos / Files / Project1 ˇ and select azure-devops-container-example


Clone Repository
#

Clone the azure-devops-container-example repository to a local client:

# Clone the repository
git clone git@ssh.dev.azure.com:v3/jueklu/Project1/azure-devops-container-example

Repository Components
#

Overview
#

Add the following Dockerfile and HTML/index.html file to the repository, the file and folderstructure should look like this:

├── Dockerfile
├── HTML
│   └── index.html
└── README.md

Dockerfile
#

# Dockerfile
FROM httpd:latest

COPY HTML/index.html /usr/local/apache2/htdocs/
EXPOSE 80

HTML file
#

HTML/index.html
<!DOCTYPE html>
<html>

<head>
	<title>jklug.work</title>
</head>

<body>
	<h1>Azure DevOps Example</h1>
	<p>Build Container</p>
</body>

</html>



Parallel Jobs
#

# Open the your Azure DevOps Organization page: URL Syntax
https://dev.azure.com/my-organization-name

# Open the your Azure DevOps Organization page: Example
https://dev.azure.com/jueklu/
  • Go to “Organization Settings”
  • Select the (Pipelines) “Parallel jobs” tab
  • Configure a Parallel Job (Necessary to run the pipeline, similar to a GitLab Runner)

Pipeline
#

Add Service Connection
#

  • Go to: (Project) > “Project Settings”

  • Select “Pipelines” > “Service connections”

  • Click “Create service connection”

Note: An Azure authentication window will pop up. If it does not show up, try again until it shows up, otherwise the “Resource group” can not be selected.

  • Select “Azure Resource Manager” and click “Next”
  • Authentication Method:
  1. Service principal (automatic): Azure DevOps will handle the creation and management of the service principal.

  2. Service principal (manual): You provide the details of an existing service principal.

  • Click “Next”
  • Scope Level: Select your subscription ID and the resource group where the Azure container registry is deployed

  • Define a service connection name, like Azure Container Registry

  • Click “Save”

  • Verify the new service connection:

Create Pipeline
#

  • Go to: (Project) “Pipelines”

  • Click “Create Pipeline”

  • Select “Azure Repos Git”
  • Select the repository azure-devops-container-example
  • Select your Azure subscription (and login again - another popup)

  • Select “Build and push an image to Azure Container Registry”

  • Select your Azure Container Registry

  • Define a image name (defaults to repository name)

  • Click validate and configure

  • Click “Build and run”

Pipeline Manifest
#

The pipeline is automatically created and looks as follows:

# Docker
# Build and push an image to Azure Container Registry
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- main

resources:
- repo: self

variables:
  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '875a58dd-registry-service-connection'
  imageRepository: 'azuredevopscontainerexample'
  containerRegistry: 'jkwregistry.azurecr.io'
  dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
  tag: '$(Build.BuildId)'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

Verify the Pipeline Run
#

Verify the pipeline run through:


Verify the Image in the Registry
#

Azure CLI
#

# List images in the Azure Container Registry
az acr repository list --name jkwregistry --output table

# Shell output:
Result
---------------------------
azuredevopscontainerexample
# List available tags of the container image
az acr repository show-tags --name jkwregistry --repository azuredevopscontainerexample --output table

# Shell output:
Result
--------
2

Pull Image & Run Container
#

Create a new service principal for the container registry
#

# Create service principal
az ad sp create-for-rbac \
    --name jkwuser \
    --scopes /subscriptions/0176a19a-some-subscription-id.../resourceGroups/container-playground/providers/Microsoft.ContainerRegistry/registries/jkwregistry \
    --role acrpush

# Shell output:
{
  "appId": "2ec0b720-some-app-id",
  "displayName": "jkwuser",
  "password": "9wA8Q~some-password...",
  "tenant": "30d87815-some-tenant..."
}

Login to Azure Container Registry
#

# Login to Azure Container Registry
docker login jkwregistry.azurecr.io --username 2ec0b720-some-app-id --password 9wA8Q~some-password...

Pull the Image & Run the Container
#

User Docker to pull and run the image:

# Run container
docker run -d --name azuredevopscontainerexample -p 8080:80 jkwregistry.azurecr.io/azuredevopscontainerexample:2
# Verify the container
curl localhost:8080

# Shell output:
<!DOCTYPE html>
<html>

<head>
        <title>jklug.work</title>
</head>

<body>
        <h1>Azure DevOps Example</h1>
        <p>Build Container</p>
</body>

Links #

https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/containers/build-image?view=azure-devops
Azure-DevOps - This article is part of a series.
Part 2: This Article