AzureでCIを行う場合はAzure Pipelinesを使うことになります。 また、最近のCIは都度同じ環境でCIを動かせるようにコンテナの上で実行するのがスタンダードです。
このため、開発しているプロダクトではalpineベースのコンテナでCIジョブを動作させていました。たとえば以下の通り、hashicorp/terraformはAlpineベースのイメージです。
$ docker run --rm -it --entrypoint head hashicorp/terraform:1.0.0 -1 /etc/os-release NAME="Alpine Linux"
このようなイメージをAzure Pipelinesで動かした場合、CIジョブが起動しないという問題に遭遇しました。
Azure PipelinesのInitialize containers
のログを見ると、以下のようなエラーが出力されています。
/usr/bin/docker exec 3ba25f3ee0c4f689807bc4dc44c307c1bd21896b228221502ac11bf017dfcfe1 \ sh -c "command -v bash" cannot exec in a stopped state: unknown ##[error]Docker exec fail with exit code 126 Finishing: Initialize containers
原因
Azure Pipelinesでは、Linuxベースのコンテナには以下のような要件が課されます。
The Azure Pipelines system requires a few things in Linux-based containers:
- Bash
- glibc-based
- Can run Node.js (which the agent provides)
- Does not define an ENTRYPOINT
- USER has access to groupadd and other privileges commands without sudo
Alpineベースのコンテナイメージでは、これらの要件を満たせません。
実際に先ほどのInitialize containers
のログを見ると以下のようにbash
が使えるかをAzure Pipelinesが確認しています。これが正常終了しないとコンテナの初期化を失敗させてしまいます。
$ /usr/bin/docker exec 3ba25f3ee0c4f689807bc4dc44c307c1bd21896b228221502ac11bf017dfcfe1 sh -c "command -v bash"
対策
alpineにこだわる場合は、Non glibc-based containersにしたがって対応すれば良いでしょう。
ぼくはalpineにこだわる理由もなかったので、ベースイメージをdebianベースに変更しました。