Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022
この記事では、Docker で Azure Pipelines エージェントを実行する手順について説明します。 Docker を使って Windows Server Core (Windows ホストの場合) または Ubuntu コンテナー (Linux ホストの場合) 内で実行するセルフホステッド エージェントを Azure Pipelines に設定できます。 これは、Azure Container Instances などの外部オーケストレーションを使ってエージェントを実行する場合に便利です。 この記事では、エージェントの自己更新の処理など、完全なコンテナーの例について説明します。
Windows と Linux の両方がコンテナー ホストとしてサポートされています。 Windows コンテナーは Windows vmImage で実行する必要があります。
Docker でエージェントを実行するには、いくつかの環境変数を docker run に渡します。これにより、Azure Pipelines または Azure DevOps Server に接続するようにエージェントが構成されます。 最後に、ニーズに合わせてコンテナーをカスタマイズします。 タスクとスクリプトによっては、コンテナーの PATH で使用できる特定のツールに依存する場合があり、これらのツールが使用可能であることを確認するのはユーザーの責任です。
ウィンドウズ
Hyper-V の有効化
Hyper-V は、Windows では既定では有効になっていません。 コンテナー間の分離を提供する場合は、Hyper-V を有効にする必要があります。 それ以外の場合、Docker for Windows は起動しません。
注
マシンで仮想化を有効にする必要があります。 これは通常、既定で有効になっています。 ただし、Hyper-V のインストールが失敗する場合は、システムのドキュメントで仮想化を有効にする方法を参照してください。
Docker for Windows のインストール
Windows 10を使っている場合は、Docker Community Edition をインストールできます。 Windows Server 2016の場合は、Mirantis Container Runtime (旧称 Docker Enterprise Edition) をインストールします。
Windows コンテナーを使用するように Docker を切り替える
既定では、Docker for Windows は Linux コンテナーを使用するように構成されています。 Windows コンテナーの実行を許可するには、Docker for Windows が Windows デーモンを実行していることを確認します。
Dockerfile を作成してビルドする
次に Dockerfile を作成します。
コマンド プロンプトを開きます。
新しいディレクトリを作成します。
mkdir "C:\azp-agent-in-docker\"この新しいディレクトリに移動します。
cd "C:\azp-agent-in-docker\"次の内容を
C:\azp-agent-in-docker\azp-agent-windows.dockerfileというファイルに保存します。FROM mcr.microsoft.com/windows/servercore:ltsc2022 WORKDIR /azp/ COPY ./start.ps1 ./ CMD powershell .\start.ps1次のコンテンツを
C:\azp-agent-in-docker\start.ps1に保存します。function Print-Header ($header) { Write-Host "`n${header}`n" -ForegroundColor Cyan } if (-not (Test-Path Env:AZP_URL)) { Write-Error "error: missing AZP_URL environment variable" exit 1 } if (-not (Test-Path Env:AZP_TOKEN_FILE)) { if (-not (Test-Path Env:AZP_TOKEN)) { Write-Error "error: missing AZP_TOKEN environment variable" exit 1 } $Env:AZP_TOKEN_FILE = "\azp\.token" $Env:AZP_TOKEN | Out-File -FilePath $Env:AZP_TOKEN_FILE } Remove-Item Env:AZP_TOKEN if ((Test-Path Env:AZP_WORK) -and -not (Test-Path $Env:AZP_WORK)) { New-Item $Env:AZP_WORK -ItemType directory | Out-Null } New-Item "\azp\agent" -ItemType directory | Out-Null # Let the agent ignore the token env variables $Env:VSO_AGENT_IGNORE = "AZP_TOKEN,AZP_TOKEN_FILE" Set-Location agent Print-Header "1. Determining matching Azure Pipelines agent..." $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(Get-Content ${Env:AZP_TOKEN_FILE})")) $package = Invoke-RestMethod -Headers @{Authorization=("Basic $base64AuthInfo")} "$(${Env:AZP_URL})/_apis/distributedtask/packages/agent?platform=win-x64&`$top=1" $packageUrl = $package[0].Value.downloadUrl Write-Host $packageUrl Print-Header "2. Downloading and installing Azure Pipelines agent..." $wc = New-Object System.Net.WebClient $wc.DownloadFile($packageUrl, "$(Get-Location)\agent.zip") Expand-Archive -Path "agent.zip" -DestinationPath "\azp\agent" try { Print-Header "3. Configuring Azure Pipelines agent..." .\config.cmd --unattended ` --agent "$(if (Test-Path Env:AZP_AGENT_NAME) { ${Env:AZP_AGENT_NAME} } else { hostname })" ` --url "$(${Env:AZP_URL})" ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" ` --pool "$(if (Test-Path Env:AZP_POOL) { ${Env:AZP_POOL} } else { 'Default' })" ` --work "$(if (Test-Path Env:AZP_WORK) { ${Env:AZP_WORK} } else { '_work' })" ` --replace Print-Header "4. Running Azure Pipelines agent..." .\run.cmd } finally { Print-Header "Cleanup. Removing Azure Pipelines agent..." .\config.cmd remove --unattended ` --auth PAT ` --token "$(Get-Content ${Env:AZP_TOKEN_FILE})" }そのディレクトリで次のコマンドを実行します。
docker build --tag "azp-agent:windows" --file "./azp-agent-windows.dockerfile" .最終的なイメージには、
azp-agent:windowsというタグが付けられます。
イメージを開始する
これでイメージが作成されたので、コンテナーを実行できます。 これにより、最新バージョンのエージェントがインストールされ、構成され、実行されます。 任意の指定された Azure DevOps または Azure DevOps Server インスタンスの指定されたエージェント プール (既定では Default エージェント プール) が対象となります。
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Windows" --name "azp-agent-windows" azp-agent:windows
ネットワークの問題が発生した場合は、--network パラメーターの指定が必要になることがあります。
docker run --network "Default Switch" < . . . >
--interactive
--tty
-it キーを使用して、コンテナーを停止してエージェントを削除できるようにする場合は、Ctrl と + フラグ (または単にC) の指定が必要になることがあります。
docker run --interactive --tty < . . . >
パイプライン ジョブごとに新しいエージェント コンテナーが必要な場合は、--once フラグを run コマンドに渡します。
docker run < . . . > --once
--once フラグを使用すると、Kubernetes や Azure Container Instances などのコンテナー オーケストレーション システムを使用して、ジョブの完了時にコンテナーの新しいコピーを開始できます。
オプションの環境変数を使用して、エージェント名、エージェント プール、およびエージェント作業ディレクトリを制御できます。
Linux
Docker のインストール
Linux ディストリビューションに応じて、Docker Community Edition または Docker Enterprise Edition をインストールできます。
Dockerfile を作成してビルドする
次に Dockerfile を作成します。
ターミナルを開きます。
新しいディレクトリを作成します (推奨)。
mkdir ~/azp-agent-in-docker/この新しいディレクトリに移動します。
cd ~/azp-agent-in-docker/次のコンテンツを
~/azp-agent-in-docker/azp-agent-linux.dockerfileに保存します。Alpine の場合、この問題で説明されている手法を使用します。
FROM python:3-alpine ENV TARGETARCH="linux-musl-x64" # Another option: # FROM arm64v8/alpine # ENV TARGETARCH="linux-musl-arm64" RUN apk update && \ apk upgrade && \ apk add bash curl gcc git icu-libs jq musl-dev python3-dev libffi-dev openssl-dev cargo make # Install Azure CLI RUN pip install --upgrade pip RUN pip install azure-cli WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh RUN adduser -D agent RUN chown agent ./ USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]Ubuntu 24.04 の場合:
FROM ubuntu:24.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update && \ apt upgrade -y && \ apt install -y curl git jq libicu74 # Install Azure CLI RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh # Create agent user and set up home directory RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]Ubuntu 22.04 の場合:
FROM ubuntu:22.04 ENV TARGETARCH="linux-x64" # Also can be "linux-arm", "linux-arm64". RUN apt update && \ apt upgrade -y && \ apt install -y curl git jq libicu70 # Install Azure CLI RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash WORKDIR /azp/ COPY ./start.sh ./ RUN chmod +x ./start.sh # Create agent user and set up home directory RUN useradd -m -d /home/agent agent RUN chown -R agent:agent /azp /home/agent USER agent # Another option is to run the agent as root. # ENV AGENT_ALLOW_RUNASROOT="true" ENTRYPOINT [ "./start.sh" ]
エージェントを root として実行する場合は、
ENV AGENT_ALLOW_RUNASROOT="true"行のコメントを解除し、この行の前でagentユーザーを追加する記述を削除します。注
タスクは、コンテナーが提供すると予想される実行可能ファイルに依存する場合があります。 たとえば、
zipおよびunzipタスクを実行するために、RUN apt install -yおよびArchiveFilesパッケージをExtractFilesコマンドに追加する必要があります。 また、これはエージェントが使用する Linux Ubuntu イメージであるため、必要に応じてイメージをカスタマイズできます。 例: .NET アプリケーションをビルドする必要がある場合は、「Ubuntu に .NET SDK または .NET ランタイムをインストールする」のドキュメントに従って、これをイメージに追加できます。必ず Unix スタイル (LF) の改行コードを使って、次の内容を
~/azp-agent-in-docker/start.shに保存します。#!/bin/bash set -e # Load a token either from the environment variable or by using the service principal credentials. load_azp_token() { # Always un-export AZP_CLIENTSECRET so it is never inherited by # child processes (e.g., agent job processes). It remains available # as a shell variable so that it can be used to generate a token. export -n AZP_CLIENTSECRET if [ -n "$AZP_CLIENTID" ]; then if [ -z "$AZP_CLIENTSECRET" ]; then echo 1>&2 "error: AZP_CLIENTSECRET must be set when AZP_CLIENTID is used" exit 1 fi if [ -z "$AZP_TENANTID" ]; then echo 1>&2 "error: AZP_TENANTID must be set when AZP_CLIENTID is used" exit 1 fi echo "Using service principal credentials to get token" # Isolate Azure CLI state to a dedicated, restrictive directory to avoid # leaking cached credentials/tokens to subsequent pipeline job processes. AZP_TOKEN="$( export AZURE_CONFIG_DIR="$(mktemp -d)" chmod 700 "$AZURE_CONFIG_DIR" az_cli_cleanup() { # Log out and remove the isolated Azure CLI config directory to purge cached tokens. az logout --username "$AZP_CLIENTID" >/dev/null 2>&1 || true az account clear >/dev/null 2>&1 || true rm -rf "$AZURE_CONFIG_DIR" } trap az_cli_cleanup EXIT az login --allow-no-subscriptions --service-principal --username "$AZP_CLIENTID" --password "$AZP_CLIENTSECRET" --tenant "$AZP_TENANTID" >/dev/null # adapted from https://learn.microsoft.com/en-us/azure/databricks/dev-tools/user-aad-token az account get-access-token --query accessToken --output tsv )" echo "Token retrieved" fi if [ -z "${AZP_TOKEN_FILE}" ]; then if [ -z "${AZP_TOKEN}" ]; then echo 1>&2 "error: missing AZP_TOKEN environment variable" exit 1 fi AZP_TOKEN_FILE="$(dirname "$0")/.token" fi if [ -n "${AZP_TOKEN-}" ]; then if [ -d "${AZP_TOKEN_FILE}" ]; then echo 1>&2 "error: AZP_TOKEN_FILE is a directory, expected a file path: ${AZP_TOKEN_FILE}" exit 1 fi # If the file already exists, it must itself be writable. if [ -e "${AZP_TOKEN_FILE}" ]; then if [ ! -w "${AZP_TOKEN_FILE}" ]; then echo 1>&2 "error: existing AZP_TOKEN_FILE is not writable: ${AZP_TOKEN_FILE}" exit 1 fi else if [ ! -w "$(dirname "${AZP_TOKEN_FILE}")" ]; then echo 1>&2 "error: AZP_TOKEN_FILE parent directory is missing or not writable: $(dirname "${AZP_TOKEN_FILE}")" exit 1 fi fi (umask 177 && echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}") chmod 600 "${AZP_TOKEN_FILE}" || true else if [ ! -r "${AZP_TOKEN_FILE}" ]; then echo 1>&2 "error: AZP_TOKEN_FILE is not readable: ${AZP_TOKEN_FILE}" exit 1 fi if [ ! -s "${AZP_TOKEN_FILE}" ]; then echo 1>&2 "error: AZP_TOKEN_FILE is empty: ${AZP_TOKEN_FILE}" exit 1 fi fi # Unset the AZP_TOKEN environment variable to prevent it from being exposed. # At this point the token is only available in the file specified by AZP_TOKEN_FILE. unset AZP_TOKEN } # Cleanup function to remove the agent configuration. cleanup() { trap "" EXIT if [ -e ./config.sh ]; then print_header "Cleanup. Removing Azure Pipelines agent..." # Try to get a new token if using service principal credentials, as the old one # might have expired between the time it was waiting to run a job and now. # If refresh fails, continue cleanup with the existing token file. if [ -n "$AZP_CLIENTID" ]; then if ! ( load_azp_token ); then echo "Warning: failed to refresh Azure Pipelines token during cleanup. Continuing with the existing token." fi fi # If the agent has some running jobs, the configuration removal process will fail. # So, give it some time to finish the job. But only try max_attempts and then exit. max_attempts=10 attempt=1 while [ $attempt -le $max_attempts ]; do ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break echo "Attempt $attempt failed. Retrying in 30 seconds..." attempt=$((attempt+1)) sleep 30 done if [ $attempt -gt $max_attempts ]; then echo 1>&2 "warning: failed to remove agent configuration after $max_attempts attempts" fi fi } print_header() { lightcyan="\033[1;36m" nocolor="\033[0m" echo -e "\n${lightcyan}$1${nocolor}\n" } if [ -z "${AZP_URL}" ]; then echo 1>&2 "error: missing AZP_URL environment variable" exit 1 fi # Load the AZP token for initial setup. load_azp_token if [ -n "${AZP_WORK}" ]; then mkdir -p "${AZP_WORK}" fi # Let the agent ignore sensitive env variables, including tokens and the client secret. export VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE,AZP_CLIENTSECRET" print_header "1. Determining matching Azure Pipelines agent..." AZP_AGENT_PACKAGES=$(curl -LsS \ -u user:$(cat "${AZP_TOKEN_FILE}") \ -H "Accept:application/json" \ "${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&top=1") AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl") if [ -z "${AZP_AGENT_PACKAGE_LATEST_URL}" -o "${AZP_AGENT_PACKAGE_LATEST_URL}" == "null" ]; then echo 1>&2 "error: could not determine a matching Azure Pipelines agent" echo 1>&2 "check that account "${AZP_URL}" is correct and the token is valid for that account" exit 1 fi print_header "2. Downloading and extracting Azure Pipelines agent..." curl -LsS "${AZP_AGENT_PACKAGE_LATEST_URL}" | tar -xz & wait $! . ./env.sh trap "cleanup; exit 0" EXIT trap "cleanup; exit 130" INT trap "cleanup; exit 143" TERM print_header "3. Configuring Azure Pipelines agent..." # Despite it saying "PAT", it can be the token through the service principal ./config.sh --unattended \ --agent "${AZP_AGENT_NAME:-$(hostname)}" \ --url "${AZP_URL}" \ --auth "PAT" \ --token $(cat "${AZP_TOKEN_FILE}") \ --pool "${AZP_POOL:-Default}" \ --work "${AZP_WORK:-_work}" \ --replace \ --acceptTeeEula & wait $! print_header "4. Running Azure Pipelines agent..." chmod +x ./run.sh # To be aware of TERM and INT signals call ./run.sh # Running it with the --once flag at the end will shut down the agent after the build is executed ./run.sh "$@" & wait $!注
また、Kubernetes や Azure Container Instances などのコンテナー オーケストレーション システムを使って、作業が完了したときにコンテナーの新しいコピーを開始する必要があります。
そのディレクトリで次のコマンドを実行します。
docker build --tag "azp-agent:linux" --file "./azp-agent-linux.dockerfile" .最終的なイメージには、
azp-agent:linuxというタグが付けられます。
イメージを開始する
これでイメージが作成されたので、コンテナーを実行できます。 これにより、最新バージョンのエージェントがインストールされ、構成され、実行されます。 任意の指定された Azure DevOps または Azure DevOps Server インスタンスの指定されたエージェント プール (既定では Default エージェント プール) が対象となります。
docker run -e AZP_URL="<Azure DevOps instance>" -e AZP_TOKEN="<Personal Access Token>" -e AZP_POOL="<Agent Pool Name>" -e AZP_AGENT_NAME="Docker Agent - Linux" --name "azp-agent-linux" azp-agent:linux
--interactive
--tty
-it キーを使用して、コンテナーを停止してエージェントを削除できるようにする場合は、Ctrl と + フラグ (または単にC) の指定が必要になることがあります。
docker run --interactive --tty < . . . >
パイプライン ジョブごとに新しいエージェント コンテナーが必要な場合は、--once フラグを run コマンドに渡します。
docker run < . . . > --once
--once フラグを使用すると、Kubernetes や Azure Container Instances などのコンテナー オーケストレーション システムを使用して、ジョブの完了時にコンテナーの新しいコピーを開始できます。
オプションの環境変数を使用して、エージェント名、エージェント プール、およびエージェント作業ディレクトリを制御できます。
環境変数
| 環境変数 | 説明 |
|---|---|
| AZP_URL | Azure DevOps または Azure DevOps Server インスタンスの URL。 |
| AZP_TOKEN | 個人用アクセス トークン (PAT) |
| AZP_CLIENTID | サービス プリンシパル クライアント ID |
| AZP_CLIENTSECRET | サービス プリンシパル クライアント シークレット |
| AZP_TENANTID | サービス プリンシパル テナント ID |
| AZP_AGENT_NAME | エージェント名 (既定値: コンテナーのホスト名)。 |
| AZP_POOL | エージェント プール名 (既定値: Default)。 |
| AZP_WORK | 作業ディレクトリ (既定値: _work)。 |
認証
次のいずれかが必要です。
- PAT を使用する場合:
AZP_TOKEN - サービス プリンシパルを使用する場合、
AZP_CLIENTID、AZP_CLIENTSECRETおよびAZP_TENANTID
認可
トークンまたはサービス プリンシパルは、AZP_URL の組織レべルでエージェント プール (読み取り、書き込み) スコープを保持している必要があります。 PAT を使用する場合、トークンは、構成エージェントのアクセス許可が付与されているユーザーが作成する必要があります。
ツールを追加してコンテナーをカスタマイズする
基本的なビルド エージェントを作成しました。 追加のツールとその依存関係を含めるように Dockerfile を拡張したり、これを基本レイヤーとして使って独自のコンテナーを構築したりできます。 次の点が変更されていないことを確認してください。
-
start.shスクリプトは Dockerfile によって呼び出されます。 -
start.shスクリプトは Dockerfile の最後のコマンドです。 - 派生コンテナーで、Dockerfile で指定されている依存関係が削除されないことを確認します。
Docker コンテナー内で Docker を使用する
Docker コンテナー内から Docker を使用するには、Docker ソケットをバインドマウントします。
注意
これを行うと、セキュリティに重大な影響があります。 コンテナー内のコードを Docker ホストでルートとして実行できるようになりました。
これを行う必要があることが確実な場合は、Docker.com のバインド マウントに関するドキュメントを参照してください。
注
Azure Pipelines コンテナー ジョブの場合、ホスト Docker ソケット (/var/run/docker.sock) は既定ではジョブ コンテナーにマップされません。 コンテナー ジョブでホスト デーモンへの Docker-in-container アクセスが必要な場合は、コンテナー リソースに mapDockerSocket: true 設定します。 詳細については、「 Docker ソケットマッピング」を参照してください。
Azure Kubernetes Service クラスターを使用する
注意
docker in docker の制限により、Docker ベースのタスクは AKS 1.19 以降では機能しないことに注意してください。 Docker は Kubernetes 1.19 にコンテナー化されたものに置き換えられ、Docker-in-Docker は使用できなくなりました。
Azure Kubernetes Service をデプロイし構成する
「クイック スタート: Azure portal を使用して Azure Kubernetes Service (AKS) クラスターをデプロイする」の手順に従います。 その後、PowerShell または Shell コンソールで kubectl コマンド ラインを使用できます。
Azure Container Registry をデプロイし構成する
「クイック スタート: Azure portal を使用して Azure コンテナー レジストリを作成する」の手順に従います。 その後、Azure Container Registry からコンテナーをプッシュおよびプルできます。
シークレットを構成し、レプリカ セットをデプロイする
AKS クラスターにシークレットを作成します。
kubectl create secret generic azdevops \ --from-literal=AZP_URL=https://dev.azure.com/yourOrg \ --from-literal=AZP_TOKEN=YourPAT \ --from-literal=AZP_POOL=NameOfYourPoolこのコマンドを実行して、コンテナーを Container Registry にプッシュします。
docker push "<acr-server>/azp-agent:<tag>"既存の AKS クラスターの Container Registry 統合を構成します。
注
Azure portal で複数のサブスクリプションがある場合は、最初にこのコマンドを使用してサブスクリプションを選択してください
az account set --subscription "<subscription id or subscription name>"az aks update -n "<myAKSCluster>" -g "<myResourceGroup>" --attach-acr "<acr-name>"次のコンテンツを
~/AKS/ReplicationController.ymlに保存します。apiVersion: apps/v1 kind: Deployment metadata: name: azdevops-deployment labels: app: azdevops-agent spec: replicas: 1 # here is the configuration for the actual agent always running selector: matchLabels: app: azdevops-agent template: metadata: labels: app: azdevops-agent spec: containers: - name: kubepodcreation image: <acr-server>/azp-agent:<tag> env: - name: AZP_URL valueFrom: secretKeyRef: name: azdevops key: AZP_URL - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops key: AZP_TOKEN - name: AZP_POOL valueFrom: secretKeyRef: name: azdevops key: AZP_POOL volumeMounts: - mountPath: /var/run/docker.sock name: docker-volume volumes: - name: docker-volume hostPath: path: /var/run/docker.sockこの Kubernetes YAML では、レプリカ セットとデプロイを作成します。ここで
replicas: 1は、クラスターで実行されているエージェントの数を示します。次のコマンドを実行します。
kubectl apply -f ReplicationController.yml
これで、エージェントで AKS クラスターが実行されます。
カスタム MTU パラメーターを設定する
コンテナー ジョブで使用されるネットワークの MTU 値の指定を許可します (k8s クラスターの docker-in-docker シナリオに役立ちます)。
環境変数 AGENT_DOCKER_MTU_VALUE を設定して MTU 値を設定してから、セルフホステッド エージェントを再起動する必要があります。 エージェントの再起動の詳細についてはこちらを、個々のエージェントに別々の環境変数を設定する方法についてはこちらを参照してください。
これにより、ジョブ コンテナーのネットワーク パラメーターを設定できます。このコマンドの使用はコンテナー ネットワーク構成時の次のコマンドの使用に似ています。
-o com.docker.network.driver.mtu=AGENT_DOCKER_MTU_VALUE
Docker コンテナー内で Docker を使ったボリュームのマウント
Docker コンテナーが別の Docker コンテナー内で実行されている場合は、両方ともホストのデーモンを使用するため、すべてのマウント パスでコンテナーではなくホストが参照されます。
たとえば、ホストから外部 Docker コンテナーへのパスをマウントする場合は、次のコマンドを使用できます。
docker run ... -v "<path-on-host>:<path-on-outer-container>" ...
ホストから内部 Docker コンテナーへのパスをマウントする場合は、次のコマンドを使用できます。
docker run ... -v "<path-on-host>:<path-on-inner-container>" ...
ただし、外部コンテナーから内部コンテナーへのパスをマウントすることはできません。この問題を回避するには、ENV 変数を宣言する必要があります。
docker run ... --env DIND_USER_HOME=$HOME ...
その後、次のコマンドを使って、外部コンテナーから内部コンテナーを開始することができます。
docker run ... -v "${DIND_USER_HOME}:<path-on-inner-container>" ...
一般的なエラー
Windows を使っていて、次のエラーが表示される場合は、次のようにします。
standard_init_linux.go:178: exec user process caused "no such file or directory"
git-scm をダウンロードしインストールして、Git Bash をインストールします。
次のコマンドを実行します。
dos2unix ~/azp-agent-in-docker/Dockerfile
dos2unix ~/azp-agent-in-docker/start.sh
git add .
git commit -m "Fixed CR"
git push
やり直してください。 エラーは表示されなくなります。