2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure DevOps で Dev Container Build and Run を使う

2
Posted at

Dev Container Build and Run とは?

Azure DevOpsの拡張機能として提供されており、
Azure PipelinesでDev Containersのコンテナをビルド、Azure Container Registryにイメージをpushするタスクが利用できます。

Dev Containersはクライアント環境でビルドされたそれぞれのコンテナ イメージを利用するシナリオが多いですが、
ビルドをAzure上で実行させ利用者(開発者)はビルドされたイメージをpullするだけになり、より固定的な環境として開発チーム内で共通化する事ができます。

Dev Containersは開発環境をコンテナ上で構築する事により、セットアップ手順の省力化やチーム内での共通化、他のプロジェクトに影響のない環境の独立化など、様々なメリットのあるVisual Stucio Code 開発環境のソリューションの1つです。
ここではDev Containersについての詳しい説明は割愛します。

前提

説明では、Azure DevOps(Repos、Pipelines)、Azure Container Registryを利用しているものとします。

プロジェクト

リポジトリ

DevOps 拡張機能

以下機能が提供されます。

  • PipelineでのDevcontainersCiタスクの実行
  • Pipeline エディタ上でのDevcontainersCiタスクの追加

ライセンス

MIT

Azure DevOpsへの拡張機能のインストール

  1. Marketplace から Get it free をクリック
    image.png

  2. インストール先の組織を選択し、Install をクリック
    image.png

  3. Proceed to organization をクリック
    image.png

  4. Organization Settings の Extensions に追加されます。
    image.png

Dev Containers 作成

  1. Azure Reposに新しいリポジトリを作成し、.devcontainers/devcontainer.jsonを作成、リポジトリにpush
    (Debian 環境を作る例)

    .devcontainer/devcontainer.json
    // For format details, see https://aka.ms/devcontainer.json. For config options, see the
    // README at: https://github.com/devcontainers/templates/tree/main/src/debian
    {
        "name": "Debian",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "mcr.microsoft.com/devcontainers/base:bullseye"
    
        // Features to add to the dev container. More info: https://containers.dev/features.
        // "features": {},
    
        // Use 'forwardPorts' to make a list of ports inside the container available locally.
        // "forwardPorts": [],
    
        // Configure tool-specific properties.
        // "customizations": {},
    
        // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
        // "remoteUser": "root"
    }
    

    チュートリアル: Developing inside a Container using Visual Studio Code Remote Development

パイプライン 作成

パイプラインがContainer Registryにpushするためのトークンを作成

  1. Container Registryのポータルから、トークン追加 をクリック
    image.png

  2. トークン に名前を、スコープ マップ から _repositries_push を選択し、作成 をクリック
    image.png

  3. 作成されたトークンをクリックし、password1アクション から (生成)をクリック
    image.png

  4. 有効期限を設定しますか? をクリックし、有効期限を設定する(省略可能だが、セキュアにするために設定した方がよい)。
    生成 をクリック
    image.png

  5. はい を選択
    image.png

  6. パスワードが生成されるので、記録しておく。
    image.png

新しいパイプラインを作成

  1. DevOps プロジェクトの Pipelines から New pipeline をクリック
    image.png

  2. Azure Repos Git を選択
    image.png

  3. ビルド対象のリポジトリを選択
    image.png

  4. Starter pipeline を選択
    image.png

  5. azure-pipelines.ymlファイルが作成されるので、scriptdocker loginのコマンドと環境変数ACR_TOKENの設定を記述する。
    docker login-uパラメータ(ユーザー名)にはContainer Registryに作成したトークンの名前、-pパラメータ(パスワード)に変数ACR_TOKENを指定

    azure-pipelines.yml
    # Starter pipeline
    # Start with a minimal pipeline that you can customize to build and deploy your code.
    # Add steps that build, run tests, deploy, and more:
    # https://aka.ms/yaml
    
    trigger:
    - main
    
    pool:
      vmImage: ubuntu-latest
    
    steps:
    - script: |
          docker login -u build-container -p $ACR_TOKEN yourregistry.azurecr.io
      displayName: 'Log in to Container Registry'
      env:
        ACR_TOKEN: $(ACR_TOKEN)
    
  6. Show assistant をクリック
    image.png

Devcontainers CI Taskの追加

  1. Devcontainers CI Task をクリック
    image.png

  2. 対話形式で項目を入力し、Add をクリック
    image.png

    設定内容は下記の"設定値"に反映されるため、記述式がわかる場合にはこの対話形式を利用する必要はありません。

    項目 設定値 入力値 入力例
    Image name (including registry) imageName イメージの名前(レジストリ含む) yourregistry.azurecr.io/example-dev-container
    One or more comma-separated image tags (defaults to latest) imageTag pushされるイメージに設定されるタグ 1.0,latest
    Platforms for which the image should be built.
    If omitted, defaults to the platform of the Azure DevOps Agent.
    Multiple platforms should be comma separated.
    platform Multiplatform Dev Container Builds linux/amd64,linux/arm64
    Specify the command to run after building the dev container image runCmd コンテナー イメージのビルド後に実行するコマンド make ci-build
    Specify a child folder (containing a .devcontainer) instead of using the repository root subFolder .devcontainerフォルダーを含むフォルダーへのリポジトリ ルートからの相対パス folderB
    Specify environment variables to pass to the docker run command env 実行時に開発コンテナに渡す環境変数 ACR_TOKEN: $(ACR_TOKEN)
    Control when images are pushed to the registry push filterに設定すると、sourceBranchFilterForPushbuildReasonsForPush、及びpushOnFailedBuildの条件が満たされた場合にイメージがpushされる。imageNameが設定されている場合は既定でfilter Never push(never)
    Push if buildReasonsForPush, sourceBranchFilterForPush, and pushOnFailedBuild conditions are met(filter)
    Always push(always)
    ☑Control whether to push the image on failed builds (if push==filter) pushOnFailedBuild ビルド失敗時にpushを実行するかどうか
    Set the Build Reasons that should trigger a push of the dev container image (if push=filter).
    Defaults to Manual, IndividualCI, BatchedCI.
    (see https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&viewFallbackFrom=vsts&tabs=yaml)
    buildReasonsForPush レジストリにpushできる Build.Reason 値を指定 Manual
    InidividualCI
    Set the source branches (e.g. refs/heads/main) that are allowed to trigger a push of the dev container image (if push=filter).
    Leave empty to allow all.
    sourceBranchFilterForPush レジストリにpushされるブランチの指定
    (※main等ではなく、refs等からコミット ハッシュの書き込まれている箇所を指定する必要があります)
    refs/heads/main
    ☑For non-root Dev Containers (i.e. where remoteUser is specified), the action attempts to make the container user UID and GID match those of the host user. Set this to true to skip this step (defaults to false) skipContainerUserIdUpdate ルート以外の Dev Container(remoteUserが指定されている)場合、コンテナー ユーザーのユーザーIDとグループIDをホスト ユーザーのものと一致させる
    Specify additional images to use for build caching cacheFrom ビルド キャッシュに使用する追加のイメージを指定
    ☑Builds the image with --no-cache (takes precedence over cacheFrom) noCache ビルドに--no-cacheオプションを指定
  3. YAMLファイルにDevcontainersCiのタスクが追加される。

    azure-pipelines.yml
    # Starter pipeline
    # Start with a minimal pipeline that you can customize to build and deploy your code.
    # Add steps that build, run tests, deploy, and more:
    # https://aka.ms/yaml
    
    trigger:
    - main
    
    pool:
      vmImage: ubuntu-latest
    
    steps:
    - script: |
          docker login -u build-container -p $ACR_TOKEN yourregistry.azurecr.io
      displayName: 'Log in to Container Registry'
      env:
        ACR_TOKEN: $(ACR_TOKEN)
    - task: DevcontainersCi@0
      inputs:
        imageName: 'yourregistry.azurecr.io/debian'
        push: 'filter'
        sourceBranchFilterForPush: 'refs/heads/main'
      displayName: 'Run a DevcontainersCi'
    
  4. Variables をクリック
    image.png

  5. New variable をクリック
    image.png

  6. Name に変数名を指定、Keep this value secret にチェックを入れ、Value にContainer Registryに作成したトークンのパスワードを入力し、OKをクリック
    image.png

  7. Save をクリック
    image.png

  8. vをクリックし、Save をクリック
    image.png

パイプライン 実行

  1. Azure Pipelinesから作成されたパイプラインをクリック
    image.png

  2. Run pipeline をクリック
    image.png

  3. 成功すると、Container Registryのリポジトリにイメージがpushされる。
    image.png

バージョン タグについて

パイプライン タスク内でカウンタが利用できます。
以下のように設定すれば、latestのタグを最新のイメージに更新、ver_major.ver_minorの値でタグが設定される。
ver_majorは 1、ver_minorver_majorが変化するまで0からインクリメントされ、
ver_majorが 2 等に変化するとver_minorは 0 にリセットされる。

azure-pipelines.yml
variables:
  ver_major: 1
  ver_minor: $[counter(variables['ver_major'], 0)]

- task: DevcontainersCi@0
  inputs:
    # ...
    imageTag: '$(ver_major).$(ver_minor),latest'
    # ...

image.png

参考

Pipelineで利用する変数、式について

Visual Studio Codeでの利用

WSL+Ubuntu の場合

  1. Dev ContainerはContainer Registryのイメージを利用するように変更します。

    .devcontainer/devcontainer.json
    {
        "name": "Debian",
        "image": "yourregistry.azurecr.io/debian/releases:latest"
    }
    
  2. Azure CLIを利用し、Azureにログイン
    az acr | Microsoft Learn

    $ az acr login --name (Container Registry名)
    
  3. Visual Studio Codeを起動

    $ cd (リポジトリ クローン先ディレクトリ)
    $ code .
    
  4. 左下の><をクリックし、Reopen in Container をクリック
    image.png
    image.png

  5. 左下に Dev Container :~ と表示されればコンテナ環境での開発が利用できるようになります。
    image.png

応用

Pull Requestでmain以外のブランチでも実行してみたい。
でもその時にバージョンがインクリメントされたら困る。

そのような場合のテクニック

  • main ブランチ以外への push は Pipeline でトリガしない。
    但し、Manual Run で実行は可能。
  • マイナー バージョン番号はブランチ別に管理
  • main ブランチの更新は releases ディレクトリに push
  • Dev Container は devcontainer-build ディレクトリで開発
  • 開発者の Dev Container は Azure Container Registry のイメージを使用
.devcontainer/devcontainer.json
{
    "name": "Debian",
    "image": "yourregistry.azurecr.io/debian/releases:latest"
}
devcontainer-build/.devcontainer/devcontainer.json
{
    "name": "Debian",
    "image": "mcr.microsoft.com/devcontainers/base:bullseye"
}
azure-pipelines.yml
trigger:
  branches:
    include:
    # IndividualCI をトリガするのは main のみ (Manual は他のブランチも実行可能)
    - main
  paths:
    include:
    # トリガ対象のディレクトリ
    - devcontainer-build/*

pool:
  vmImage: ubuntu-latest

variables:
  ver_major: 1
  # ブランチ名.(major) 別に minor のカウンタを管理
  ver_minor: $[counter(format('{0}.{1}', variables['Build.SourceBranch'], variables['ver_major']), 0)]
  ${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
    # main ブランチの更新は releases に push
    stage: 'releases'
  ${{ else }}:
    # main ブランチ以外はブランチ名に push
    stage: '$(Build.SourceBranchName)'

steps:
- script: |
      docker login -u build-container -p $ACR_TOKEN yourregistry.azurecr.io
  displayName: 'Log in to Container Registry'
  env:
    # Container Registry のトークン(パスワードは環境変数で管理)
    ACR_TOKEN: $(ACR_TOKEN)
- task: DevcontainersCi@0
  inputs:
    # ステージ別のディレクトリに push
    imageName: 'yourregistry.azurecr.io/debian/$(stage)'
    # インクリメントされるバージョンを設定、latest を更新
    imageTag: '$(ver_major).$(ver_minor),latest'
    # ビルド対象のディレクトリ
    subFolder: 'devcontainer-build'
  displayName: 'Run a DevcontainersCi'

その他

Azure DevOpsに拡張機能をインストールする事により、これらの機能が提供されます。
拡張機能のバージョンが指定できない事により、破壊的変更があった場合の対応や
提供終了された場合の対応等は、考慮する必要があるかもしれません。
(但し幸いにも、プロジェクトはオープンソース、ライセンスはMITとなっています)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?