EC2インスタンスにおけるGITLAB RUNNERとNODEJSを使ったCI/CD作成方法

紹介
CI/CDとは
CIとは、Continuous Integrationの略で、継続的インテグレーションと呼ばれ、ソースコードがバージョンアップ管理システムのGITに変更される度に自動化されたビルドとテストを実行する手法をいいます。開発者のソースコード変更が『良い』状態となり、コードベースでの開発により適しています。
CDとは、Continuous Deliveryの略で、継続的デリバリーと呼ばれ、継続的インテグレーションを拡張した手法であり、ソースコードがGITに変更される度に自動化されたビルドとテストを実行するだけでなく、アプリがいつも安定してデプロイが実施されるが、本番環境へのデプロイは手動で行うというものです。
CDとは、Continuous Deploymentの略でもあり、継続的デプロイメントと呼ばれ、継続的デリバリーと同様に、継続的インテグレーションを拡張した手法をいいます。ただし、継続的デリバリーと異なり本番環境へのデプロイを手動で行う代わりに、自動的に実施しユーザーが最新のものをすぐに利用することができます。
GitLab Runnerとは
GitLab Runnerはビルドやテストやデプロイ等のジョブを実行し、そのジョブの結果をGitLabへ返却するといったことに使われるオープンソースプロジェクトです。Runnerは仮想マシンであり、VPSでもあり、Dockerコンテナーでもあり、そして、各Dockerコンテナーのグループです。GitLabとオープンソースとを連携した 仕組みであるGitLab CI/CDと共に使って各ジョブを実行します。GitLabとRunnerはAPIを通してコミュニケーションします。
Runnersの種類
- Shared Runners:GitLabによって提供されたもの
- Specific Runners:単一のGitLabのプロジェクトに使われる、ユーザーによって自作されたもの
- Group Runners:複数のGitLabのプロジェクトに使われる、ユーザーによって自作されたもの
Executor選択
GitLab Runnerには様々な目的に応じて適切な、ジョブの実行方式であるExecutorを選択することができます。GitLab Runnerが提供するExecutorの種類は以下の通りとなります。
- SSH
- Shell
- Parallels
- VirtualBox
- Docker
- Docker Machine (auto-scaling)
- Kubernetes
- Custom
然し、この記事では以下の2つのExecutorについてお話しします。
- ・Docker Executor:『テスト』ジョブに使われます。サーバーのリソースを節約するため、GitLabによって提供されたShared Runnersを『テスト』ジョブに使われます。
- ・Shell Executor:『デプロイ』ジョブに使われます。このExecutorを用いてサーバーにてコマンドを直接実行します。
他のExecutor及びその使い方について、以下のURLを参照してください。
https://docs.gitlab.com/runner/executors/README.html
構成図

GitLabは、GitLabのDevelopブランチへソースコードをプッシュした時、テストとデプロイのステージを含むパイプラインを生成します。ここでNodeJSアプリケーションを開発するので、この二つのステージのみ要りますが、Typescriptアプリケーションならば、それらの他に『ビルド』ステージも必要です。

『テスト』ステージには『テスト』ジョブが含まれます。ここで、前述の如くサーバーのリソースを節約するため、GitLabによって提供されたGitLab Shared Runner(Executor Docker利用)を使います。「テスト」ジョブの実行がエラーなく成功したら、『デプロイ』という次のステージへ遷移します。
『デプロイ』ステージには『デプロイ』ジョブが含まれます。ここで、EC2インスタンスに、Webサーバーと共にインストールされたGitLab Runner(Executor Shell利用)を使います。 Runnerのタスクとして、ソースコードの変更を検出し、その差分をプロジェクトフォルダーにコピー&ペーストしてから、NodeJSサービスを再起動します。
ステージとジョブをコンフィグするには .gitlab-ci.ymlファイルを作成して、GitLabへソースコードと共にプッシュする必要があります。
注:ファイルを各ステージで交換するために、 対象ファイルをGitLabの共有ストレージに保存することができます。通常は、libraries /node_modulesをキャッシュに保存します。ただし、Typescriptならば、『.ts』から『.js』にビルドした時に生成されるファイル をArtifactsに保存します。ここで、NodeJSを使っているので、Artifactsが不要になります。
実現手順
サーバー設定
まず、Amazon Linux AMIを実行するEC2インスタンスを新たに作成します。ブラウザーからNodeJSサーバーへアクセスするためのポート3000を開放しておきます。その後、PuTTYを用いてサーバーへアクセスします。
下記のコマンドで、GitLab Runnerをインストールします。
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash $ sudo yum install gitlab-runner
下記のコマンドで、NodeJSをインストールします。
$ sudo yum install -y gcc-c++ make $ curl -sL https://rpm.nodesource.com/setup_14.x | sudo -E bash – $ sudo yum install -y nodejs
下記のコマンドで、NodeJSプロジェクトをバックグラウンドで実行するためのforever packageをインストールします。
$ sudo npm install forever -g
下記のコマンドで、プロジェクトのディレクトリを作成します。
$ sudo mkdir -p /var/www/project-ci
下記のコマンドで、プロジェクトディレクトリへ読取、書込み、実行をGitLab Runnerが行なえるような権限を与えます。
$ sudo setfacl -m user:gitlab-runner:rwx /var/www/project-ci
GitLabリポジトリおよびNodeJSデモプロジェクトの作成
GitLabのリポジトリを作成してローカルにクローンします。
以下の3つのファイルをクローンしたフォルダーに追加しておきます。
package.json
{
"name": "project-ci",
"version": "1.0.0",
"description": "project to research Gitlab Runner",
"main": "index.js",
"scripts": {
"test": "echo \"Test OK\" && exit 0",
"start": "node index.js"
},
"keywords": [],
"author": "nghia.nt",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
}
}
index.js
const express = require('express');
const app = express();
const port = process.env.NODE_PORT || 3000;
app.get('/', function (req, res) {
res.send('Hello World From Briswell Vietnam!');
});
app.listen(port, function () {
console.log('Listening on port ' + port);
});
.gitignore
node_modules/ iisnode/ npm-debug.log* .vscode/ .idea/ .env* **/*.log dist/
その後、それらのファイルをGitLabのDevelopブランチへプッシュします。
GitLabでのGitLab Runner登録
対象プロジェクトのGitLabにアクセスして、Settings→CI/CDに辿ってから、Runners項目の『Set up a specific Runner manually』にあるURLとトークンをメモしておいてください。

PuTTYに戻り、下記のコマンドを実行することでGitLab Runnerを登録します。
$ sudo gitlab-runner register
上記のコマンドを実行したのち、ウィザードからは上記に取得したURLとトークンの入力を求めます。
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): https://gitlab.com/ Please enter the gitlab-ci token for this runner: k753PaGiosBxxxxxxx Please enter the gitlab-ci description for this runner: my-shell-runner Please enter the gitlab-ci tags for this runner (comma separated): my-shell-runner Registering runner... succeeded runner=ajgHxcNz Please enter the executor: virtualbox, docker+machine, kubernetes, docker, shell, ssh, docker-ssh+machine, docker-ssh, parallels: shell Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
登録が終わったら、GitLabの設定画面へアクセスして確認しましょう。以下の画像のように情報が表示されるのであれば、登録に成功したということです。

GitLabのプロジェクトのステージ及びジョブのコンフィグ
プロジェクトのソースコードに以下の情報を含める.gitlab-ci.ymlファイルを新たに作ります。
# We have 2 stage Test and Deploy
stages:
- test
- deploy
# Config cache
cache:
paths:
- node_modules/
# Test job
test:
# Docker image
image: node:latest
# Attach Test job to Test stage
stage: test
# Config to use GitLab Shared Runner with Executor Docker
tags:
- docker
script:
- npm install
- npm run test
# Defines the names of branches and tags the job runs for
only:
- develop
# Deploy job
deploy:
type: deploy
# Attach Deploy job to Deploy stage
stage: deploy
# Config to use our Runner with Executor Shell
tags:
- my-shell-runner
script:
# Only copy changed files to project folder
- cp -r -u * $PROJECT_DIR
- cd $PROJECT_DIR
- npm install
# Restart NodeJS service
- forever stop index.js || true
- forever start index.js
only:
- develop
その後、このファイルをGitLabのDevelopブランチへプッシュします。
次に、環境変数を設定しましょう。GitLab画面にてSettings→CI/CD→Variablesに辿ってから、『Protect variable』項目にチェックを外して『Add Variable』ボタンを押下してください。

GitLab画面にてCI/CD→Pipelinesにアクセスして確認しましょう。

あと、ブラウザーからサーバーへポート3000でアクセスできます。

このように、GitLab Runnerを使ってNodeJSプロジェクトを、CI/CDと連携したEC2インスタンスへデプロイすることに成功しました。
参照元
https://opensource.com/article/18/8/what-cicd
Vietnamese
English