CodeBuildでdocker run --nameがコンフリクトする問題


概要

CodeBuildとGithubを連携していたりすると、連続でビルドが走ることがよくあります。
たとえば、以下のようにバックグラウンドでコンテナを動かしておいてテストなどをしていると、コミットが一気に押し寄せて複数のビルドが同時に走ってしまうことはよくあります。

$ docker run -d --name nginx1 nginx:alpine
$ docker run --link nginx1 alpine \
    sh -c 'apk add curl && curl nginx1:80 && sleep 100'

そんなときに、以下のようなエラーが発生することがあります。

docker: Error response from daemon: Conflict. The container name "/nginx1" is already in use by container "XXXXXXXXX". You have to remove (or rename) that container to be able to reuse that name.

これは、nginx1という名前ですでにコンテナが動いていて、その名前は使えないのでrenameしてくださいという旨の警告文です。

通常の検証環境だとrenameすれば問題ないのですが、CodeBuildなどCI環境だと困ります。

結論

以下のリポジトリで検証しました。

前回、DOCKER_BUILDKITが原因と書きましたが、実はローカルキャッシュのDockerLayerCacheが原因でした

検証

以下のようなbuildspec.yamlを用意して検証しています。

echo $rand は、latestのイメージが他のビルドで上書きされないかの検証

version: 0.2 

env:
  variables:
    DOCKER_BUILDKIT: "1"

phases:
  build:
    commands:
# 省略
      - |
        docker build -t app --build-arg rand=$RANDOM .
        docker run app sh -c 'echo $rand'
        docker run --name test alpine sh -c 'sleep 120'
        docker run app sh -c 'echo $rand'

DockerLayerCacheありの場合

以下のようなエラーが出ます。

21546 # echo $randの結果
docker: Error response from daemon: Conflict. The container name "/test" is already in use by container "XXX". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
21546

DockerLayerCacheありの場合は、実行中のビルドでコンテナリソースを共有しているみたいです。
逆に、CustomCacheやSouceCacheは影響がありませんでした。

どうでもいいこと

bashなどでdocker run --nameを使いたいけど、毎回動かすとコンフリクトが面倒というかたは$RANDOMをお使いください

$ docker run -d --name nginx-$RANDOM