似たような記事は複数見つけられたのですが、現状はもっと簡単なようなのでメモ。最大の罠は公式ドキュメントの探しにくさ。
やること
GitLab上のCIでdocker buildして、GitLab上のDocker registryにdocker pushする。
更に作ったdocker imageを他のGitLabのプロジェクトでCIのランナーとして利用する。
同じプロジェクト内でイメージを作って使うこともできますが、ある程度汎用なイメージを作れるのであればプロジェクトは分けたほうが良さそうです。
自前でDockerイメージを作るのは、例えばマイコンの開発環境とかで必要な共通ライブラリ郡をコンパイル済みにしておいて、CIしたい側でCIにかかる時間を減らせるとかとかの理由で。
イメージをつくるほう
Dockerfile
これは普通に必要なように作ります。特別な設定などはありません。
CIの設定
基本は公式ドキュメント のとおりです。
このドキュメントがCIの項目になくて、registryの項目にあるのが最大の罠だと思う。
ちなみに自分は公式ドキュメントからほんの少しだけ変えて下のような感じにしています。
image: docker:19.03.12
services:
- docker:19.03.12-dind
stages:
- build
- test
- release
variables:
IMAGE_NAME: "hoge"
TEST_IMAGE: $IMAGE_NAME:mr-$CI_COMMIT_SHORT_SHA
RELEASE_IMAGE: $IMAGE_NAME:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE/$TEST_IMAGE .
- docker push $CI_REGISTRY_IMAGE/$TEST_IMAGE
only:
refs:
- merge_requests
run-test:
stage: test
script:
- docker pull $CI_REGISTRY_IMAGE/$TEST_IMAGE
- docker run --rm -w /work -v $PWD:/work $CI_REGISTRY_IMAGE/$TEST_IMAGE /work/runtest.sh
only:
refs:
- merge_requests
release-image:
stage: release
script:
- docker pull $CI_REGISTRY_IMAGE/$TEST_IMAGE
- docker tag $CI_REGISTRY_IMAGE/$TEST_IMAGE $CI_REGISTRY_IMAGE/$RELEASE_IMAGE
- docker push $CI_REGISTRY_IMAGE/$RELEASE_IMAGE
only:
- master
主な変更点は、
- ビルドをマージリクエストに関係するイベントでしか行わないようにしたこと
- イメージのタグにコミットハッシュをつけることで、マージリクエスト上でイメージが残るようにしたこと
- プロジェクト名≠イメージ名にしたかった(ここではhogeになってる)
という点です。
自前開発をしているとしても、masterは健全に保ちたく作業の見通しを良くするのに変更は必ずマージリクエストで行いたいので、マージリクエストでイメージを作り、masterにマージされたらタグを付け直してlatestしてregistryに登録しています。
こんな感じの設定ファイルをおいて、マージリクエストを作ってそこにDockerfileをpushすればpipelineが走り、成功すればイメージが作られ、Container Registryに登録されているはずです。
次の段階に移る前にまずは、自分のローカル環境にDocker pullしてみてちゃんと目的のイメージが作れているか確認してみると良いでしょう。
ローカルにpullするのは公式ドキュメントのこのあたりを見ればできる。
注意するのはイメージ名で、 registry.gitlab.com/group/project/image:tag
となります。group
は、プロジェクトのグループ名(ユーザ名)、project
は各プロジェクト名、image
は上のyamlでいうところの hoge
になる。プロジェクトがサブグループ以下にあるなら当然 group
と project
の間に含めます。
Container Registry上に表示されているCLI Commandsからコピペしたものは、上記でいうところの project
までしか含まれていないため、上で例示したyamlみたいに独自にイメージ名を設定している場合は、自分で image
を追加しなくてはいけないです。
イメージを使うほう
使う方は特に難しくないです。公式ドキュメントのとおりです。
.gitlab-ci.yml
で利用するイメージ名を上記で作ったものにするだけです。具体的には、yamlファイルに
image: "registry.gitlab.com/group/project/image:tag"
で利用するイメージ名を指定します。
同じグループ内であれば、それぞれプライベートリポジトリであっても内部でトークンを利用してくれるため、特に設定は必要なく利用できます。