ようへいの日々精進XP

よかろうもん

CircleCI の setup_remote_docker を設定した時に留意すべきこと

tl;dr

今更かもしれないけど, 実際に手を動かしてみて初めて遭遇したのでメモっておく.

何が起きたか

github.com

amiCtrl のインテグレーションテスト的なテストを docker-compose でやりたくて docker-compose.yml を書いた. もちろん, ローカルマシン (macOS 上の Docker マシン) ではテストは動いたんだけど CircleCI 上で実行した場合にはどうしても動かない... と調べていたら, ドキュメントに以下のように書かれていた.

circleci.com

but volume mounting and port forwarding do not work the same way in this setup.

ほう...ローカルマシンのボリュームをマウントすることが出来ないとのこと. これは, 全く意識していなかったけど, 留意が必要.

ちなみに, 以下は .circleci/config.yml を掲載.

version: 2
jobs:
  build:
    docker:
      - image: circleci/golang:1.9.7
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Install docker-compose
          command: |
            curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
            chmod +x ~/docker-compose
            sudo mv ~/docker-compose /usr/local/bin/docker-compose
      - run: 
          name: Run Test Environment
          command: |
            docker-compose up -d
      - run:
          name: Run Install Dependencies
          command: |
            docker-compose exec amictrl_circleci make ensure
      - run:
          name: Run Test
          command: |
            docker-compose exec amictrl_circleci make test

ということで

ローカルマシンのボリュームをマウントしてソースコードやテストコードを Docker コンテナ上で操作出来るようにしたかったんだけど, CircleCi 上ではローカルマシンのボリュームをコンテナにマウントすることが出来ないので, コンテナをビルドする際にソースコードを含めるようにした.

FROM golang:alpine
RUN apk update && apk add git make bash gcc libc-dev python py2-pip jq dep && pip install awscli
RUN mkdir /root/.aws && mkdir /go/src/amiCtrl
ADD ./ /go/src/amiCtrl/
RUN printf "[dummy_profile]\n\
aws_access_key_id = AKxxxxxxxxxxxxxxxxxx\n\
aws_secret_access_key = zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\n\
region = ap-northeast-1" >> /root/.aws/credentials

苦肉の策ではあるけど, 以下のようにローカルマシン上でも CircleCI 上でも意図した通りに動いてくれている.

以下はローカルマシンで実行結果.

$ docker-compose exec -T amictrl_local make test
=== RUN   TestVersionFlag
--- PASS: TestVersionFlag (2.21s)
=== RUN   TestStdoutList
--- PASS: TestStdoutList (3.62s)
=== RUN   TestStdoutCreate
--- PASS: TestStdoutCreate (2.99s)
=== RUN   TestStdoutCreateError
--- PASS: TestStdoutCreateError (2.93s)
=== RUN   TestStdoutDelete
--- PASS: TestStdoutDelete (3.91s)
=== RUN   TestStdoutDeleteError
--- PASS: TestStdoutDeleteError (3.59s)
=== RUN   TestStdoutDeleteNo
--- PASS: TestStdoutDeleteNo (3.70s)
=== RUN   TestStdoutState
--- PASS: TestStdoutState (5.08s)
=== RUN   TestStdoutJson
--- PASS: TestStdoutJson (4.88s)
PASS
ok      amiCtrl 32.913s

以下は CircleCI 上の実行結果.

f:id:inokara:20191124002300p:plain

そもそも, setup_remote_docker とは

circleci.com

上記のドキュメントではなんだか小難しく書かれているが, ビルド用の Docker コンテナ内で更に docker コマンドを利用出来るようにしたもの. Docker in Docker, Docker のマトリョーシカということだと思っている.

以下, setup_remote_docker 有り, 無しの違い.

version: 2
jobs:
  build:
    docker:
      - image: docker:19.03.5-git
    steps:
      - checkout
      - run:
          name: Test
          command: |
            docker info

setup_remote_docker を付与していない場合には, 下図のようにビルドは失敗する.

f:id:inokara:20191124082706p:plain

setup_remote_docker を付与している場合.

version: 2
jobs:
  build:
    docker:
      - image: docker:19.03.5-git
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Test
          command: |
            docker info

下図のように docker info の結果がちゃんと返ってくる.

f:id:inokara:20191124082946p:plain

なーんだ, 普通の Docker じゃないかーと思って油断していると, 今回のようにホスト (こやつも Docker コンテナ) のボリュームをマウント出来ないという制約があるので注意が必要というお話.

以上

現場からの報告でした.