Ubuntu16.04でGitLabCIを使用して継続的インテグレーションパイプラインを設定する方法
序章
GitLab Community Editionは、プロジェクト管理とソフトウェア開発を支援する追加機能を備えた、自己ホスト型のGitリポジトリプロバイダーです。 GitLabが提供する最も価値のある機能の1つは、 GitLabCIと呼ばれる組み込みの継続的インテグレーションおよびデリバリーツールです。
このガイドでは、リポジトリの変更を監視するようにGitLab CIを設定し、自動テストを実行して新しいコードを検証する方法を示します。 まず、実行中のGitLabインストールから始めます。ここでは、基本的なNode.jsアプリケーションのサンプルリポジトリをコピーします。 CIプロセスを構成した後、新しいコミットがリポジトリにプッシュされると、GitLabはCIランナーを使用して、分離されたDockerコンテナー内のコードに対してテストスイートを実行します。
前提条件
始める前に、初期環境をセットアップする必要があります。 コードを保存し、CI/CDプロセスを管理するように構成された安全なGitLabサーバーが必要です。 さらに、自動テストを実行する場所が必要です。 これは、GitLabがインストールされているのと同じサーバーでも、別のホストでもかまいません。 以下のセクションでは、要件について詳しく説明します。
SSLで保護されたGitLabサーバー
ソースコードを保存してCI/CDタスクを構成するには、Ubuntu16.04サーバーにGitLabインスタンスをインストールする必要があります。 GitLabは現在、少なくとも2CPUコアおよび4GBのRAMを搭載したサーバーを推奨しています。 コードが公開されたり改ざんされたりしないように、GitLabインスタンスはLet’sEncryptを使用してSSLで保護されます。 この手順を完了するには、サーバーにドメイン名またはサブドメインが関連付けられている必要があります。
次のチュートリアルを使用して、これらの要件を完了することができます。
- Ubuntu 16.04を使用したサーバーの初期設定:
sudo
ユーザーを作成し、基本的なファイアウォールを構成します - Ubuntu 16.04にGitLabをインストールして構成する方法:サーバーにGitLabをインストールし、Let’s Encrypt TLS/SSL証明書で保護します
プロジェクト間でCI/CDランナー(自動テストを実行するコンポーネント)を共有する方法と、それらを単一のプロジェクトにロックする方法を示します。 プロジェクト間でCIランナーを共有する場合は、パブリックサインアップを制限または無効にすることを強くお勧めします。 インストール中に設定を変更しなかった場合は、戻ってサインアップの制限または無効化に関するGitLabインストール記事のオプションの手順に従って、外部からの悪用を防ぎます。
GitLabCIランナーとして使用する1つ以上のサーバー
GitLab CIランナーは、コードをチェックアウトし、自動テストを実行して新しい変更を検証するサーバーです。 テスト環境を分離するために、Dockerコンテナ内ですべての自動テストを実行します。 これを行うには、テストを実行する1つまたは複数のサーバーにDockerをインストールする必要があります。
この手順は、GitLabサーバーまたは別のUbuntu 16.04サーバーで実行して、追加の分離を提供し、リソースの競合を回避できます。 次のチュートリアルでは、テストの実行に使用するホストにDockerをインストールします。
- Ubuntu 16.04を使用したサーバーの初期セットアップ:
sudo
ユーザーを作成し、基本的なファイアウォールを構成します(GitLabサーバーでCIランナーをセットアップする場合は、これを再度完了する必要はありません)。 - Ubuntu 16.04にDockerをインストールして使用する方法:手順1と2 に従って、サーバーにDockerをインストールします
始める準備ができたら、このガイドを続けてください。
GitHubからサンプルリポジトリをコピーする
まず、サンプルのNode.jsアプリケーションを含む新しいプロジェクトをGitLabで作成します。 元のリポジトリをGitHubから直接インポートするため、手動でアップロードする必要はありません。
GitLabにログインし、右上隅にあるプラスアイコンをクリックし、新しいプロジェクトを選択して新しいプロジェクトを追加します。
新しいプロジェクトページで、プロジェクトのインポートタブをクリックします。
次に、 Repo byURLボタンをクリックします。 GitHubインポートオプションがありますが、個人アクセストークンが必要であり、リポジトリと追加情報をインポートするために使用されます。 コードとGitの履歴のみに関心があるため、URLによるインポートの方が簡単です。
GitリポジトリのURLフィールドに、次のGitHubリポジトリのURLを入力します。
https://github.com/do-community/hello_hapi.git
次のようになります。
これはデモンストレーションであるため、リポジトリにPrivateのマークを付けておくのがおそらく最善です。 終了したら、プロジェクトの作成をクリックします。
新しいプロジェクトは、GitHubからインポートされたリポジトリに基づいて作成されます。
.gitlab-ci.ymlファイルを理解する
GitLab CIは、各リポジトリ内で.gitlab-ci.yml
というファイルを探して、コードをテストする方法を決定します。 インポートしたリポジトリには、プロジェクト用にすでに構成されているgitlab-ci.yml
ファイルがあります。 このフォーマットの詳細については、.gitlab-ci.ymlリファレンスドキュメントをご覧ください。
作成したプロジェクトのGitLabインターフェースで.gitlab-ci.yml
ファイルをクリックします。 CI構成は次のようになります。
image: node:latest
stages:
- build
- test
cache:
paths:
- node_modules/
install_dependencies:
stage: build
script:
- npm install
artifacts:
paths:
- node_modules/
test_with_lab:
stage: test
script: npm test
このファイルは、 GitLab CI YAML構成構文を使用して、実行するアクション、実行する順序、実行する条件、および各タスクを完了するために必要なリソースを定義します。 独自のGitLabCIファイルを作成する場合は、GitLabインスタンスの/ci/lint
に移動して構文リンターにアクセスし、ファイルが正しくフォーマットされていることを確認できます。
構成ファイルは、テストスイートの実行に使用する必要があるDockerimage
を宣言することから始まります。 HapiはNode.jsフレームワークであるため、最新のNode.jsイメージを使用しています。
image: node:latest
次に、実行するさまざまな継続的インテグレーションステージを明示的に定義します。
stages:
- build
- test
ここで選択する名前は任意ですが、順序によって、後続のステップの実行順序が決まります。 ステージは、個々のジョブに適用できるタグです。 GitLabは同じステージのジョブを並行して実行し、現在のステージのすべてのジョブが完了するまで次のステージの実行を待機します。 ステージが定義されていない場合、GitLabはbuild
、test
、deploy
という3つのステージを使用し、デフォルトですべてのジョブをtest
ステージに割り当てます。
ステージを定義した後、構成にはcache
定義が含まれます。
cache:
paths:
- node_modules/
これは、実行間またはステージ間でキャッシュ(後で使用するために保存)できるファイルまたはディレクトリーを指定します。 これにより、実行間で変更されない可能性のあるリソースに依存するジョブの実行にかかる時間を短縮できます。 ここでは、node_modules
ディレクトリをキャッシュしています。このディレクトリに、npm
がダウンロードした依存関係をインストールします。
私たちの最初の仕事はinstall_dependencies
と呼ばれます:
install_dependencies:
stage: build
script:
- npm install
artifacts:
paths:
- node_modules/
ジョブには任意の名前を付けることができますが、名前はGitLab UIで使用されるため、わかりやすい名前が役立ちます。 通常、npm install
は次のテスト段階と組み合わせることができますが、段階間の相互作用をよりよく示すために、このステップを抽出して独自の段階で実行します。
stage
ディレクティブを使用して、ステージを明示的に「ビルド」としてマークします。 次に、script
ディレクティブを使用して実行する実際のコマンドを指定します。 script
セクション内に行を追加することで、複数のコマンドを含めることができます。
artifacts
サブセクションは、保存してステージ間を通過するファイルまたはディレクトリのパスを指定するために使用されます。 npm install
コマンドはプロジェクトの依存関係をインストールするため、次のステップではダウンロードしたファイルにアクセスする必要があります。 node_modules
パスを宣言すると、次のステージでファイルにアクセスできるようになります。 これらは、テスト後にGitLab UIで表示またはダウンロードすることもできるため、バイナリなどのビルドアーティファクトにも役立ちます。 ステージで作成したものをすべて保存したい場合は、paths
セクション全体をuntracked: true
に置き換えてください。
最後に、test_with_lab
という2番目のジョブは、実際にテストスイートを実行するコマンドを宣言します。
test_with_lab:
stage: test
script: npm test
これをtest
ステージに配置します。 これは後の段階であるため、build
段階で生成されたアーティファクトにアクセスできます。これは、この場合はプロジェクトの依存関係です。 ここで、script
セクションは、アイテムが1つしかない場合に使用できる1行のYAML構文を示しています。 コマンドが1つしか指定されていないため、前のジョブでもこれと同じ構文を使用できたはずです。
.gitlab-ci.yml
ファイルがCI/CDタスクをどのように定義するかについての基本的な考え方がわかったので、テスト計画を実行できる1つ以上のランナーを定義できます。
継続的インテグレーションの実行のトリガー
リポジトリには.gitlab-ci.yml
ファイルが含まれているため、新しいコミットがあれば、新しいCIの実行がトリガーされます。 利用可能なランナーがない場合、CI実行は「保留中」に設定されます。 ランナーを定義する前に、CI実行をトリガーして、保留状態でのジョブの外観を確認しましょう。 ランナーが利用可能になると、保留中の実行をすぐに取得します。
hello_hapi
GitLabプロジェクトリポジトリビューに戻り、ブランチとプロジェクト名の横にあるプラス記号をクリックして、メニューから新しいファイルを選択します。
次のページで、ファイル名フィールドにdummy_file
と入力し、メインの編集ウィンドウにテキストを入力します。
終了したら、下部にあるコミット変更をクリックします。
ここで、メインプロジェクトページに戻ります。 小さな一時停止アイコンが最新のコミットに添付されます。 アイコンの上にマウスを置くと、「Commit:pending」と表示されます。
これは、コードの変更を検証するテストがまだ実行されていないことを意味します。
詳細については、ページの上部に移動し、パイプラインをクリックしてください。 パイプラインの概要ページが表示されます。このページでは、CI実行が保留中としてマークされ、「スタック」としてラベル付けされていることがわかります。
注:右側には、 CILintツールのボタンがあります。 ここで、作成したgitlab-ci.yml
ファイルの構文を確認できます。
ここから、保留中ステータスをクリックして、実行の詳細を取得できます。 このビューには、実行のさまざまなステージと、各ステージに関連付けられている個々のジョブが表示されます。
最後に、install_dependenciesジョブをクリックします。 これにより、実行を遅らせている原因に関する具体的な詳細がわかります。
ここで、メッセージは、ランナーが不足しているためにジョブがスタックしていることを示しています。 まだ構成していないので、これは予想されます。 ランナーが使用可能になると、この同じインターフェースを使用して出力を確認できます。 これは、ビルド中に生成されたアーティファクトをダウンロードできる場所でもあります。
保留中のジョブがどのように見えるかがわかったので、プロジェクトにCIランナーを割り当てて、保留中のジョブを取得できます。
GitLabCIランナーサービスのインストール
これで、GitLabCIランナーをセットアップする準備が整いました。 これを行うには、システムにGitLab CIランナーパッケージをインストールし、GitLabランナーサービスを開始する必要があります。 このサービスは、さまざまなプロジェクトに対して複数のランナーインスタンスを実行できます。
前提条件で述べたように、リソースの競合を確実に回避したい場合は、GitLabインスタンスをホストする同じサーバーまたは別のサーバーでこれらの手順を完了することができます。 どちらのホストを選択する場合でも、使用する構成にはDockerをインストールする必要があることに注意してください。
GitLab CIランナーサービスをインストールするプロセスは、GitLab自体をインストールするために使用されるプロセスと似ています。 スクリプトをダウンロードして、GitLabリポジトリをapt
ソースリストに追加します。 スクリプトを実行した後、ランナーパッケージをダウンロードします。 次に、GitLabインスタンスを提供するように構成できます。
まず、最新バージョンのGitLabCIランナーリポジトリ構成スクリプトを/tmp
ディレクトリにダウンロードします(これはGitLabサーバーで使用されるリポジトリとは異なります)。
- curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh -o /tmp/gl-runner.deb.sh
ダウンロードしたスクリプトを自由に調べて、実行するアクションに問題がないことを確認してください。 スクリプトのホストバージョンもここにあります。
- less /tmp/gl-runner.deb.sh
スクリプトの安全性に満足したら、インストーラーを実行します。
- sudo bash /tmp/gl-runner.deb.sh
このスクリプトは、GitLabが管理するリポジトリを使用するようにサーバーをセットアップします。 これにより、他のシステムパッケージに使用するのと同じパッケージ管理ツールを使用してGitLabランナーパッケージを管理できます。 これが完了したら、apt-get
を使用してインストールを続行できます。
- sudo apt-get install gitlab-runner
これにより、GitLab CIランナーパッケージがシステムにインストールされ、GitLabランナーサービスが開始されます。
GitLabランナーのセットアップ
次に、GitLab CIランナーをセットアップして、作業の受け入れを開始できるようにする必要があります。
これを行うには、ランナーがGitLabサーバーで認証できるようにGitLabランナートークンが必要です。 必要なトークンのタイプは、このランナーをどのように使用するかによって異なります。
プロジェクト固有のランナーは、ランナーに特定の要件がある場合に役立ちます。 たとえば、gitlab-ci.yml
ファイルが資格情報を必要とする展開タスクを定義している場合、展開環境で正しく認証するために特定のランナーが必要になる場合があります。 プロジェクトにCIプロセスでリソースを大量に消費するステップがある場合、これも良い考えかもしれません。 プロジェクト固有のランナーは、他のプロジェクトからのジョブを受け入れません。
一方、共有ランナーは、複数のプロジェクトで使用できる汎用ランナーです。 ランナーは、各プロジェクトで現在実行されているジョブの数を考慮したアルゴリズムに従って、プロジェクトからジョブを取得します。 このタイプのランナーはより柔軟性があります。 共有ランナーを設定するには、管理者アカウントでGitLabにログインする必要があります。
以下に、これら両方のランナータイプのランナートークンを取得する方法を示します。 自分に最適な方法を選択してください。
プロジェクト固有のランナーを登録するための情報の収集
ランナーを特定のプロジェクトに関連付けたい場合は、GitLabインターフェースでプロジェクトのページに移動することから始めます。
ここから、左側のメニューの設定項目をクリックします。 その後、サブメニューの CI /CD項目をクリックします。
このページには、ランナー設定セクションが表示されます。 詳細を表示するには、展開ボタンをクリックしてください。 詳細ビューでは、左側にプロジェクト固有のランナーを登録する方法が説明されています。 手順のステップ4で表示された登録トークンをコピーします。
このプロジェクトでアクティブな共有ランナーを無効にする場合は、右側の共有ランナーを無効にするボタンをクリックします。 これはオプションです。
準備ができたら、このページから収集した情報を使用してランナーを登録する方法を学ぶためにスキップしてください。
共有ランナーを登録するための情報の収集
共有ランナーの登録に必要な情報を見つけるには、管理者アカウントでログインする必要があります。
まず、上部のナビゲーションバーにあるレンチアイコンをクリックして、管理領域にアクセスします。 左側のメニューの概要セクションで、ランナーをクリックして、共有ランナー構成ページにアクセスします。
ページの上部に表示されている登録トークンをコピーします。
このトークンを使用して、プロジェクトのGitLabCIランナーを登録します。
GitLabCIランナーをGitLabサーバーに登録する
トークンを取得したら、GitLabCIランナーサービスがインストールされているサーバーに戻ります。
新しいランナーを登録するには、次のコマンドを入力します。
- sudo gitlab-runner register
ランナーを構成するための一連の質問が表示されます。
gitlab-ciコーディネーターのURLを入力してください(例: https://gitlab.com/ )
https://
を使用してSSLを指定し、GitLabサーバーのドメイン名を入力します。 オプションで/ci
をドメインの最後に追加できますが、最近のバージョンでは自動的にリダイレクトされます。
このランナーのgitlab-ciトークンを入力してください
前のセクションでコピーしたトークン。
このランナーのgitlab-ciの説明を入力してください
この特定のランナーの名前。 これは、コマンドラインとGitLabインターフェースのランナーサービスのランナーリストに表示されます。
このランナーのgitlab-ciタグを入力してください(カンマ区切り)
これらは、ランナーに割り当てることができるタグです。 GitLabジョブは、これらのタグに関して要件を表現し、正しい依存関係を持つホストで実行されるようにすることができます。
この場合、これを空白のままにすることができます。
ランナーを現在のプロジェクトにロックするかどうか[true/false]
ランナーを特定のプロジェクトに割り当てます。 他のプロジェクトでは使用できません。
ここで「false」を選択します。
エグゼキュータを入力してください
ランナーがジョブを完了するために使用する方法。
ここで「docker」を選択します。
デフォルトのDockerイメージを入力してください(例: ルビー:2.1)
.gitlab-ci.yml
ファイルにイメージ仕様が含まれていない場合にジョブを実行するために使用されるデフォルトのイメージ。 ここで一般的な画像を指定し、.gitlab-ci.yml
ファイルでより具体的な画像を定義することをお勧めします。
ここでは、小さくて安全なデフォルトとして「alpine:latest」と入力します。
プロンプトに応答した後、プロジェクトのCI/CDタスクを実行できる新しいランナーが作成されます。
次のように入力すると、GitLabCIランナーサービスが現在利用できるランナーを確認できます。
- sudo gitlab-runner list
OutputListing configured runners ConfigFile=/etc/gitlab-runner/config.toml
example-runner Executor=docker Token=e746250e282d197baa83c67eda2c0b URL=https://example.com
ランナーが利用できるようになったので、GitLabのプロジェクトに戻ることができます。
GitLabでのCI/CD実行の表示
Webブラウザーに戻り、GitLabのプロジェクトに戻ります。 ランナーを登録してからの経過時間によっては、ランナーが現在実行されている場合があります。
または、すでに完了している可能性があります。
状態に関係なく、実行中または合格アイコン(または問題が発生した場合は失敗)をクリックして、CI実行の現在の状態を表示します。 上部のパイプラインメニューをクリックすると、同様のビューを表示できます。
パイプラインの概要ページが表示され、GitLabCIの実行ステータスを確認できます。
Stages ヘッダーの下に、実行中の各ステージのステータスを示す円が表示されます。 ステージをクリックすると、ステージに関連付けられている個々のジョブが表示されます。
buildステージ内のinstall_dependenciesジョブをクリックします。 これにより、ジョブの概要ページに移動します。
これで、使用可能なランナーがないというメッセージを表示する代わりに、ジョブの出力が表示されます。 この場合、これは、npm
が各パッケージをインストールした結果を確認できることを意味します。
右側に沿って、他のいくつかのアイテムも見ることができます。 Stage を変更し、下の実行をクリックすると、他のジョブを表示できます。 実行によって生成されたアーティファクトを表示またはダウンロードすることもできます。
結論
このガイドでは、GitLab CIの継続的インテグレーションとデプロイ機能を紹介するために、GitLabインスタンスにデモプロジェクトを追加しました。 gitlab-ci.yml
ファイルでパイプラインを定義してアプリケーションを構築およびテストする方法と、ジョブをステージに割り当てて相互の関係を定義する方法について説明しました。 次に、プロジェクトのCIジョブを取得するためにGitLab CIランナーを設定し、個々のGitLabCI実行に関する情報を見つける方法を示しました。