Ubuntu 16.04でGitLab CIを使った継続的インテグレーションパイプラインの設定方法
紹介
GitLab Community Editionは、プロジェクト管理やソフトウェア開発を支援する追加機能を備えた自己ホスティングのGitリポジトリプロバイダーです。GitLabが提供する最も貴重な機能の1つは、GitLab CIと呼ばれる組み込みの継続的インテグレーションおよびデリバリーツールです。
このガイドでは、GitLab CIを設定してリポジトリの変更を監視し、新しいコードを検証するための自動テストを実行する方法を示します。最初に、基本的なNode.jsアプリケーションのサンプルリポジトリをコピーする稼働中のGitLabインストールから始めます。CIプロセスを構成した後、新しいコミットがリポジトリにプッシュされると、GitLabはCIランナーを使用して、分離されたDockerコンテナ内のコードに対してテストスイートを実行します。
前提条件
始める前に、初期環境を設定する必要があります。コードを保存し、CI/CDプロセスを管理するために、安全なGitLabサーバーを設定する必要があります。さらに、自動テストを実行する場所も必要です。これは、GitLabがインストールされているサーバーと同じサーバーであるか、別のホストである可能性があります。以下のセクションでは、要件についてより詳しく説明します。
SSLで保護されたGitLabサーバー
ソースコードを保存し、CI/CDタスクを設定するために、Ubuntu 16.04サーバーにGitLabインスタンスをインストールする必要があります。GitLabは現在、少なくとも2 CPUコアと4GBのRAMを持つサーバーを推奨しています。コードが露出したり改ざんされたりしないように、GitLabインスタンスはLet’s Encryptを使用してSSLで保護されます。この手順を完了するためには、サーバーにドメイン名またはそれに関連付けられたサブドメインが必要です。
次のチュートリアルを使用して、これらの要件を完了できます:
- Ubuntu 16.04での初期サーバーセットアップ:
sudoユーザーを作成し、基本的なファイアウォールを設定する - Ubuntu 16.04にGitLabをインストールして設定する方法:サーバーにGitLabをインストールし、Let's EncryptのTLS/SSL証明書で保護する
私たちは、プロジェクト間でCI/CDランナー(自動テストを実行するコンポーネント)を共有する方法と、それらを特定のプロジェクトにロックする方法を示します。プロジェクト間でCIランナーを共有したい場合は、公共のサインアップを制限または無効にすることを強くお勧めします。インストール中に設定を変更していない場合は、GitLabインストール記事のオプションのステップに戻り、外部からの悪用を防ぐためにサインアップを制限または無効にする方法に従ってください。
GitLab CIランナーとして使用する1台以上のサーバー
GitLab CIランナーは、コードをチェックアウトし、新しい変更を検証するために自動テストを実行するサーバーです。テスト環境を隔離するために、すべての自動テストをDockerコンテナ内で実行します。これを行うには、テストを実行するサーバーにDockerをインストールする必要があります。
このステップは、GitLabサーバーまたは別のUbuntu 16.04サーバーで完了でき、追加の隔離を提供し、リソースの競合を回避できます。以下のチュートリアルでは、テストを実行するために使用したいホストにDockerをインストールします。
- 初期サーバーセットアップ(Ubuntu 16.04):
sudoユーザーを作成し、基本的なファイアウォールを設定します(GitLabサーバーでCIランナーを設定する場合、これを再度完了する必要はありません) - Ubuntu 16.04にDockerをインストールして使用する方法: サーバーにDockerをインストールするにはステップ1と2に従ってください
準備ができたら、このガイドを続けてください。
GitHubから例のリポジトリをコピーする
まず、例のNode.jsアプリケーションを含む新しいプロジェクトをGitLabに作成します。手動でアップロードする必要がないように、元のリポジトリをGitHubから直接インポートします。
GitLabにログインし、右上隅のプラスアイコンをクリックして新しいプロジェクトを選択し、新しいプロジェクトを追加します。
新しいプロジェクトページで、プロジェクトをインポートタブをクリックしてください:
次に、URLによるリポジトリボタンをクリックします。GitHubインポートオプションはありますが、個人アクセストークンが必要で、リポジトリや追加情報をインポートするために使用されます。私たちはコードとGitの履歴にのみ関心があるので、URLによるインポートの方が簡単です。
GitリポジトリURLフィールドに、次のGitHubリポジトリのURLを入力してください。
https://github.com/do-community/hello_hapi.git
このように見えるべきです:
これはデモンストレーションなので、リポジトリをプライベートとしてマークしておくのが良いでしょう。 完了したら、プロジェクトを作成をクリックしてください。
新しいプロジェクトは、GitHubからインポートされたリポジトリに基づいて作成されます。
.gitlab-ci.yml ファイルの理解
GitLab CIは、各リポジトリ内にある.gitlab-ci.ymlというファイルを探して、コードのテスト方法を決定します。インポートしたリポジトリには、プロジェクトのためにすでに設定されたgitlab-ci.ymlファイルがあります。形式について詳しく学ぶには、.gitlab-ci.ymlのリファレンスドキュメントをお読みください。
.gitlab-ci.yml ファイルを、私たちが作成したプロジェクトの GitLab インターフェースでクリックしてください。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構成構文を使用して、実行すべきアクション、実行する順序、実行すべき条件、および各タスクを完了するために必要なリソースを定義しています。 自分のGitLab CIファイルを書くときは、GitLabインスタンスの/ci/lintにアクセスすることでシンタックスリンターを訪れ、ファイルが正しくフォーマットされているかを検証できます。
設定ファイルは、テストスイートを実行するために使用する必要があるDocker imageを宣言することから始まります。HapiはNode.jsフレームワークなので、最新のNode.jsイメージを使用しています。
image: node:latest
次に、実行されるさまざまな継続的インテグレーションステージを明示的に定義します:
stages:
- build
- test
ここで選択する名前は任意ですが、順序がその後のステップの実行順序を決定します。ステージは、個々のジョブに適用できるタグです。 GitLabは同じステージのジョブを並行して実行し、現在のステージのすべてのジョブが完了するまで次のステージの実行を待ちます。 ステージが定義されていない場合、GitLabはbuild、test、およびdeployという3つのステージを使用し、すべてのジョブをデフォルトでtestステージに割り当てます。
段階を定義した後、構成にはcacheの定義が含まれます:
cache:
paths:
- node_modules/
これは、実行間または段階間でキャッシュ(後で使用するために保存)できるファイルやディレクトリを指定します。これにより、実行間で変更されない可能性のあるリソースに依存するジョブを実行するのにかかる時間を短縮できます。ここでは、npmがダウンロードする依存関係をインストールするnode_modulesディレクトリをキャッシュしています。
私たちの最初の仕事は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 に置き換えてください。
最後に、2番目のジョブ test_with_lab は、実際にテストスイートを実行するコマンドを宣言します。
test_with_lab:
stage: test
script: npm test
これをtestステージに置きます。これは後のステージなので、私たちの場合、プロジェクトの依存関係であるbuildステージによって生成されたアーティファクトにアクセスできます。ここでは、scriptセクションが、単一のアイテムがある場合に使用できる単一行のYAML構文を示しています。前のジョブでも同じ構文を使用できましたが、指定されたコマンドは1つだけでした。
これで、.gitlab-ci.ymlファイルがCI/CDタスクをどのように定義するかの基本的なアイデアが得られたので、テストプランを実行できる1つ以上のランナーを定義できます。
継続的インテグレーションの実行をトリガーする
私たちのリポジトリには .gitlab-ci.yml ファイルが含まれているため、新しいコミットがあると新しいCI実行がトリガーされます。ランナーが利用できない場合、CI実行は「保留中」に設定されます。ランナーを定義する前に、保留中の状態でジョブがどのように見えるかを確認するために、CI実行をトリガーしてみましょう。ランナーが利用可能になると、すぐに保留中の実行を引き継ぎます。
hello_hapi GitLabプロジェクトリポジトリビューに戻り、ブランチとプロジェクト名の隣にあるプラスサインをクリックして、メニューから新しいファイルを選択してください:
次のページで、ファイル名フィールドにdummy_fileを入力し、メイン編集ウィンドウにいくつかのテキストを入力してください:
作業が完了したら、下部の変更をコミットをクリックしてください。
さて、メインプロジェクトページに戻ります。最新のコミットには、小さな一時停止アイコンが付いています。このアイコンにマウスカーソルを合わせると、「コミット:保留中」と表示されます。
これは、コードの変更を検証するテストがまだ実行されていないことを意味します。
より多くの情報を得るには、ページのトップに移動し、Pipelinesをクリックしてください。パイプラインの概要ページに移動し、CIランが保留中としてマークされ、「スタック」とラベル付けされていることがわかります。
注意: 右側にはCI Lintツールのボタンがあります。ここでは、作成した任意のgitlab-ci.ymlファイルの構文をチェックできます。
ここから、保留中のステータスをクリックして、実行の詳細を確認できます。このビューでは、私たちの実行の異なる段階と、各段階に関連する個々のジョブが表示されます:
最後に、install_dependenciesジョブをクリックします。これにより、実行を遅らせている具体的な詳細が表示されます:
ここでは、ジョブがランナーの不足のために停止していることを示すメッセージがあります。これは、まだランナーを設定していないため予想されることです。ランナーが利用可能になると、この同じインターフェースを使用して出力を確認できます。また、ここはビルド中に生成されたアーティファクトをダウンロードできる場所でもあります。
保留中のジョブがどのようなものかがわかったので、保留中のジョブを実行するためにCIランナーをプロジェクトに割り当てることができます。
GitLab CIランナーサービスのインストール
私たちは現在、GitLab CIランナーをセットアップする準備が整いました。これを行うには、システムにGitLab CIランナーパッケージをインストールし、GitLabランナーサービスを開始する必要があります。このサービスは、異なるプロジェクトのために複数のランナーインスタンスを実行できます。
前提条件で述べたように、GitLab インスタンスをホストしているサーバーと同じサーバー上で、またはリソース競合を避けたい場合は別のサーバー上でこれらの手順を完了できます。選択したホストに関係なく、私たちが使用する設定のためには Docker をインストールする必要があることを忘れないでください。
GitLab CIランナーサービスをインストールするプロセスは、GitLab自体をインストールするプロセスと似ています。私たちは、GitLabリポジトリをaptのソースリストに追加するためのスクリプトをダウンロードします。そのスクリプトを実行した後、ランナーパッケージをダウンロードします。その後、GitLabインスタンスにサービスを提供するように設定できます。
まず、最新のGitLab CIランナーリポジトリ設定スクリプトを/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に表示される登録トークンをコピーしてください。
このプロジェクトのアクティブな共有ランナーを無効にしたい場合は、右側の共有ランナーを無効にするボタンをクリックすることでできます。これは任意です。
準備ができたら、このページから収集した情報を使ってランナーを登録する方法を学ぶために先に進んでください。
共有ランナーを登録するための情報を収集しています
共有ランナーを登録するために必要な情報を見つけるには、管理者アカウントでログインしている必要があります。
管理エリアにアクセスするには、まず上部のナビゲーションバーにあるスパナのアイコンをクリックします。その後、左側のメニューの概要セクションで、ランナーをクリックして、共有ランナーの設定ページにアクセスします:
ページの上部に表示されている登録トークンをコピーしてください:
このトークンを使用して、プロジェクトのためにGitLab CIランナーを登録します。
GitLabサーバーにGitLab CIランナーを登録する
トークンを取得したので、GitLab CIランナーサービスがインストールされているサーバーに戻ってください。
新しいランナーを登録するには、次のコマンドを入力してください:
- sudo gitlab-runner register
ランナーを設定するために一連の質問が出されます:
GitLab CI コーディネーターの URL を入力してください(例: https://gitlab.com/)
GitLabサーバーのドメイン名を入力してください。https://を使用してSSLを指定します。オプションで、ドメインの末尾に/ciを追加することもできますが、最近のバージョンでは自動的にリダイレクトされます。
このランナーのためのgitlab-ciトークンを入力してください
前のセクションでコピーしたトークン。
このランナーのgitlab-ciの説明を入力してください
この特定のランナーの名前です。これは、コマンドラインおよびGitLabインターフェースのランナーサービスのランナーリストに表示されます。
このランナーのためにgitlab-ciタグを入力してください(カンマ区切り)
これらは、ランナーに割り当てることができるタグです。GitLabジョブは、これらのタグを用いて要求を表現することができ、正しい依存関係を持つホストで実行されることを確認します。
この場合、これを空白にしておいても構いません。
現在のプロジェクトにRunnerをロックするかどうか [真/偽]
ランナーを特定のプロジェクトに割り当てます。他のプロジェクトでは使用できません。
ここで「偽」を選択してください。
実行者を入力してください
ランナーが仕事を完了するために使用する方法。
ここで「docker」を選択してください。
デフォルトのDockerイメージを入力してください(例:ruby:2.1)
.gitlab-ci.yml ファイルにイメージの仕様が含まれていない場合にジョブを実行するために使用されるデフォルトのイメージです。ここでは一般的なイメージを指定し、私たちが行ったように、.gitlab-ci.yml ファイルでより具体的なイメージを定義するのが最善です。
ここでは、小さく安全なデフォルトとして「alpine:latest」を入力します。
プロンプトに回答後、新しいランナーが作成され、あなたのプロジェクトのCI/CDタスクを実行できるようになります。
現在利用可能なGitLab CIランナーサービスのランナーを見るには、次のように入力します:
- sudo gitlab-runner list
Listing configured runners ConfigFile=/etc/gitlab-runner/config.toml
example-runner Executor=docker Token=e746250e282d197baa83c67eda2c0b URL=https://example.com
ランナーが利用可能になったので、GitLabのプロジェクトに戻ることができます。
GitLabでCI/CD実行を表示する
ウェブブラウザに戻り、GitLabのプロジェクトにアクセスしてください。ランナーを登録してからどれくらい時間が経過したかによって、ランナーが現在実行中である可能性があります:
あるいは、すでに完了しているかもしれません。
状態に関係なく、現在のCI実行の状態を表示するには、実行中または合格アイコンをクリックしてください(問題が発生した場合は失敗)。上部のパイプラインメニューをクリックすると、同様のビューを取得できます。
あなたはGitLab CIの実行状況を確認できるパイプラインの概要ページに移動します:
ステージの見出しの下には、実行中の各ステージの状態を示す円があります。ステージをクリックすると、そのステージに関連付けられた個々のジョブを表示できます:
buildステージ内のinstall_dependenciesジョブをクリックしてください。これでジョブ概要ページに移動します:
今、利用可能なランナーがいないというメッセージを表示する代わりに、ジョブの出力が表示されます。この場合、npmが各パッケージをインストールしている結果を見ることができることを意味します。
右側には他のアイテムもいくつか見えます。ステージを変更して、下の実行をクリックすることで他のジョブを見ることができます。また、実行によって生成されたアーティファクトを表示またはダウンロードすることもできます。
結論
このガイドでは、GitLab CIの継続的インテグレーションおよびデプロイメント機能を示すために、GitLabインスタンスにデモプロジェクトを追加しました。私たちは、アプリケーションを構築してテストするためにgitlab-ci.ymlファイルでパイプラインを定義する方法と、ジョブをステージに割り当てて互いの関係を定義する方法について説明しました。その後、プロジェクトのCIジョブを処理するためにGitLab CIランナーを設定し、個々のGitLab CI実行に関する情報を見つける方法をデモしました。














