概要
ローカルのDockerコンテナ上にGitLabにてCIを動かすためのセッティングをします。
単純にGitlab Runnerの使用方法の記事はわかりやすいものがたくさんありますが、docker for macだと特殊なハマりポイントもあるので改めてまとめました。
(そもそもGitlabをローカルで使うゴリゴリ使うことはあまりないかもしれないですが)
今回のゴール
GitLabでコミットを検知したらDockerコンテナが起動し、コンテナの中でphpファイルの構文チェックが走るようにする
環境
version | |
---|---|
ホストOS | MacOS 10.14.6 |
Docker | 19.03.5, build 633a0ea |
gitlab-ce Image | gitlab/gitlab-ce:12.6.4-ce.0 |
gitlab-runner Image | gitlab/gitlab-runner:v12.7.1 |
※Imageのバージョンは2020/2/10時点でのlatest |
GitLab Runnerとは
Gitlabと連携し、プロジェクトのコミットを検知して動作するジョブの実行環境です。
GitLab上にはGitlab CI/CDという管理ツールがあり、ジョブの実行ログなどを管理できます。
公式ドキュメント
Runnerの種類
Runnerには共有範囲が3種類あります。
- Shared : 全プロジェクトで共有
- Group : 同一グループ内で共有
- Specific : プロジェクト占有
Runner自体はあくまで実行環境なので、ジョブの中身はプロジェクト毎に記載することになります。
特化した環境ならSpecific、汎用的ならShared、といった使い分けになると思われます。
Executor
ジョブの実行方法(Executor)にはいくつか種類があり、ジョブ毎に設定することができます。
簡単なものであればサーバ内で実行するShell Executor
、実行環境を気にするジョブの場合はコンテナを個別に起動させるDocker Executor
を用いるなど、臨機応変に使い分けることができます。
(Executor一覧はこちら)
Dockerコンテナの構築
まずはdocker-composeを用いてコンテナを作ります。
今回は172.20.10.1/24
のネットワーク内にgitlab本体とrunnerのコンテナを作ります。
version: '3.5'
services:
gitlab:
container_name: gitlab
image: gitlab/gitlab-ce:latest
hostname: 'gitlab-local'
restart: always
networks:
gitlab_net:
ipv4_address: 172.20.10.2
environment:
GITLAB_OMNIBUS_CONFIG : |
external_url 'http://gitlab'
unicorn['socket'] = '/opt/gitlab/var/unicorn/gitlab.socket'
gitaly['internal_socket_dir'] = '/var/opt/gitlab/gitaly/soc'
ports:
- '1080:80'
- '1443:443'
- '1024:22'
volumes:
- './gitlab/config:/etc/gitlab'
- './gitlab/logs:/var/log/gitlab'
- './gitlab/data:/var/opt/gitlab'
gitlab_runner:
container_name: gitlab_runner
image: 'gitlab/gitlab-runner:latest'
hostname: gitlab-runner
restart: always
networks:
gitlab_net:
ipv4_address: 172.20.10.3
volumes:
- ./gitlab-runner/config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
networks:
gitlab_net:
name: gitlab_net
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.10.1/24
コンテナ作成上の注意
-
GITLAB_OMNIBUS_CONFIG
の下2つの設定はdocker for macでgitlabを使う場合に起こる問題への対策です。詳しくはこちら - docker-composeのバージョン3.5以降の記法でしかnetworksに固定名称を与えられません。(公式のリリース情報)
Runnerの登録
コンテナを立ち上げてgitlab自体にアクセスできたら、続いてRunnerの登録をしていきます。
なお、今回はプロジェクト占有型のSpecificで設定を進めます。
トークンの取得
登録にはGitlab CIのトークンが必要になります。
「対象のプロジェクト」>「Settings」>「CI/CD」と進み、「Runner」の項目を開くと以下のような画面が表示されるので、トークンをコピーしておきます。
Runnerのセットアップ
トークンを取得できたらRunnerにトークンをセットします。
これによって、Gitlab本体とRunnerが連携され、ジョブを実行できるようになります。
なお、今回はphpのインストールが必要ということもあり、Docker Executor
を採用します。
セットアップにはRunnerのコンテナを立ち上げた状態で以下のコマンドを実行します。
docker exec -it gitlab_runner gitlab-runner register \
--url "http://gitlab" \
--registration-token "コピーしておいたトークン" \
--name "docker_php" \
--tag-list "docker_php" \
--executor "docker" \
--docker-image "php:7.4.3-apache" \
--docker-network-mode "gitlab_net" \
--docker-pull-policy "if-not-present"
ポイントは、必ずdocker-network-mode
でGitlab本体と同じネットワークを指定することです。
docker for macの場合、私の知る限りSocksプロキシなどを使わないとホストOSからドメインで当たれないので、こうしないとジョブ実行時に立ち上がるコンテナからGitlab本体にアクセスができず詰みます。
このコマンドを実行すると、対話形式で各設定項目について確認されますが、オプションで指定してあればそれがデフォルトになるのでEnterを連打していればOKです。
(逆にオプション1つもつけず対話形式で設定を入力する方法もあります)
設定が成功すると先ほどの画面に有効なRunnerとして表示されます。
ジョブの作成
実行環境となるRunnerの登録が完了したので、いよいよ実際に実行するジョブを作成します。
.gitlab-ci.yml
という名前のファイルを実際に使用したいプロジェクト直下にを配置することでジョブの定義を行います。
なお、プロジェクトのTOPに表示されるSet up CI/CD
を押すと.gitlab-ci.yml
の作成画面が表示されます。
いくつかテンプレートも用意されていますが、今回はただコマンドラインで構文チェックできればいいので手で作ります。
lint:
tags:
- docker_php
script:
- pwd
- echo 'start lint'
- php -l ./test.php
lint
はジョブの名前で、自由に命名することができますし、複数のジョブを定義することもできます。
script
にはジョブの中で実行するコマンドを記載します。今回はほぼlintを走らせているだけです。
tags
にはRunnerの登録時に記入したタグを記載します。これによって、1つのプロジェクトでもジョブによって実行環境を変えることができます。
※もっと色々設定できるので興味ある方は公式ドキュメントへどうぞ
実行結果の確認
以上でジョブの設定は完了しました。
肝心なtest.php
を用意していなかったので、以下のファイルをpushして実行結果を確認していきます。
<?php
echo 'Hello World!';
実行結果は「CI/CD」>「Pipeline」または「CI/CD」>「Jobs」から確認できます。
ここで今回の結果を選択し、さらにジョブを選択すると実行内容の詳細を確認できます。
今回は問題のない記述だったので普通に成功しています。
次に、問題があるファイルをpushしてみます。
<?php
echoooo 'Hello World!';
すると、先ほどはPassed
だったのがFailed
になりました。
しっかりシンタックスエラーが出ています。
これで問題のある記述がある場合は簡単に検知することができますし、どこに問題があるのかもわかります。
感想とまとめ
mac特有の問題で何度かくじけかけましたが、なんとか無事lintを走らせることができました。
実用的にするにはもっと.gitlab-ci.yml
を作りこむ必要がありますが、ひとまずここで切ります。
今後はユニットテストやデプロイ的なことも含め、複数のジョブを走らせたり色々試してみたいと思います。