はじめに
GitLab CIでせっかくbuild、testのステージに分けたのにbuildの結果がtestに引き継がれずになんでや!ってなったことありませんか?ありますよね。少なくとも僕はあった。
テストのジョブごとに毎回ビルドして貴重な電力を消費してしまうのは心が痛みます。
ということで、docker-in-docker (dind)というぱっと見だと頭の悪そうな構成で解決できるようだったのでメモしておきます。
やり方
GitLab Runnerとかの設定は一通り済んでいるものとして話を進めます。
- Docker Container Registry の設定を行い、ビルドした結果のイメージを保存してテスト時にそのイメージをpullして状態を引き継げるようにする。
- GitLab Runner の設定
-
.gitlab-ci.yml
の設定
以下、だいたいのことは
Using Docker Build - GitLab Documentation
を参考にしています。
Docker Container Registry を使う
GitLab Container Registry - Qiita
こちらの記事によくまとまっているので、これを読んで設定すれば大丈夫なはずです。
GitLab Runner の設定
GitLab Runnerの登録は
sudo gitlab-runner register
で行い、executor
にはdocker
、デフォルトのイメージはdocker:latest
などとしておきます。
その後/etc/gitlab-runner/config.toml
を編集し、
privileged = false
となっているのを
privileged = true
に変更し、特権モードで動作するようにしておきます。
dindの構成は特権モードでないと動作しないようです。
次に、これは必須ではないのですが
environment = ["DOCKER_DRIVER=overlay2"]
を[[runners]]
の項に追加しておきます。
詳しいことはよく分かりませんが、これを指定しておくと無駄なディスクアクセスが行われなくなるようです(参考:Using the OverlayFS driver)。
.gitlab-ci.yml
の設定
下みたいな感じで設定してあげると良い感じになると思います。
image: docker:latest
services:
- docker:dind
variables:
CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project/my-image:$CI_COMMIT_REF_NAME
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.example.com
build:
stage: build
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
test1:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/tests
test2:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test
ただ、GitLabをhttpで運用している場合、ホスト上でDockerのhttp接続の設定を行っていてもDockerのコンテナ上でhttpのRegistryに接続しようとすると怒られてしまいます。
その場合、
services:
- docker:dind
の部分を
services:
- name: docker:dind
command: ["--insecure-registry", "registry.example.com"]
と変更すると良いです。
この辺の情報はなかなか見つからなくて、docker:dind
のイメージをベースにして新しいイメージを作っている情報しか見つからないのですが、command
でオプションを指定してあげるだけでできました。
おわりに
この方法はDocker imageのpush、pullで割と時間を食うので、小規模なプロジェクトではあまりよい方法とは言えないです。
ビルドするのに10分くらいかかってしまうくらいのプロジェクトでは良い選択であると思います。