[ Gitlab Runner ] CI / CD パイプラインを構築する➁(CD編)
はじめに
gitlab上でCDを実行するために行った設定手順を解説する。
設定ファイルのソース
概要
当プロジェクトに導入しているCI/CDパイプラインについて当記事にて解説を行う。
設定手順
リポジトリに追加する設定ファイルについて
以下の設定ファイルを追加する。
image: original/image:latest
cache:
key: one-key-to-rule-them-all
paths:
- vendor/
- node_modules/
before_script:
- chmod 700 ~/.ssh
- echo "$SSH_KEY" >> ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent)"
- ssh-add ~/.ssh/id_rsa
- ssh-add -l
- echo "$SSH_CONFIG" >> ~/.ssh/config
- ssh://git@255.255.255.255:65535/web/sample_project.git
- git remote -v
- git remote update
- git config --global user.name gitlab_runner
- git config --global user.email gitlab.runner@cimx-initiative.com
stages:
- build
- formatter
- deploy
formatter:
stage: formatter
script:
- npm install
- ssh -t -t web_app_db -f -N
- lsof -i
- composer install
- cp .env.example .env
- echo "$ENV_FILE" >> .env
- php artisan key:generate
- vendor/bin/phpunit tests/Feature/api_test.php
- vendor/bin/phpunit tests/Feature/Api
- SYNTAX_CHECK=0
- for FILE in `git diff --name-only origin/master | grep -E '*php'` ; do
- echo $FILE
- ./vendor/bin/php-cs-fixer fix $FILE
- echo 'PHPMDで未使用変数などのチェック'
- if ! ./vendor/bin/phpmd $FILE text ruleset.xml; then
- SYNTAX_CHECK=1
- fi
- done
- IS_ERROR=0
- for FILE in `git diff --name-only origin/master | grep -E '*js'` ; do
- if [ $FILE = '.eslintrc.json' ]; then
- echo $FILE
- echo "skip check"
- continue
- fi
- if [ $FILE = 'composer.json' ]; then
- echo $FILE
- echo "skip check"
- continue
- fi
- if [ $FILE = 'package-lock.json' ]; then
- echo $FILE
- echo "skip check"
- continue
- fi
- if [ $FILE = 'package.json' ]; then
- echo $FILE
- echo "skip check"
- continue
- fi
- if [ $FILE = WebGL_Release.framework.js ]; then
- echo $FILE
- echo "skip check"
- continue
- fi
- if [[ -n `./node_modules/.bin/eslint --fix $FILE` ]]; then
- ./node_modules/.bin/eslint --fix $FILE
- IS_ERROR=1
- fi
- done
- git add -A
- git status
- if [[ -n "`git status --porcelain`" ]];then
- git commit -m '[ci skip]Push by GitLab runner'
- git push origin $CI_COMMIT_REF_NAME
- fi
- IS_ERROR_LOG_REMAIN_ERROR=0
- for FILE in `git diff --name-only origin/master | grep -E '*php'`; do
- echo $FILE
- if [[ -n `git grep error_log -- $FILE` ]]; then
- echo -e "\e[31;43m デバッグコードが残っている可能性があります。'\n'削除してください \e[m"
- IS_ERROR_LOG_REMAIN_ERROR=1
- else
- IS_ERROR_LOG_REMAIN_ERROR=0
- fi
- done
- if [ $SYNTAX_CHECK -eq 0 -a $IS_ERROR_LOG_REMAIN_ERROR -eq 0 ]; then
- exit 0
- else
- echo -e "\e[31;43m 修正を行った上で再度コミットしてください \e[m"
- exit 1
- fi
except:
- master
deploy_production:
stage: deploy
script:
- echo "$SSH_CONFIG_ENVOY" >> ~/.ssh/config
- git pull origin master
- composer global require laravel/envoy
- ~/.composer/vendor/bin/envoy run deploy_production --server=prd --branch=master
only:
- master
deploy_staging:
stage: deploy
script:
- echo "$SSH_CONFIG_ENVOY" >> ~/.ssh/config
- git pull origin master
- composer global require laravel/envoy
- ~/.composer/vendor/bin/envoy run deploy_staging --server=stg --branch=develop
only:
- develop
@servers(['prd' => '-A web-prd', 'stg' => '-A web-stg'])
@setup
$repository = 'ssh://git@255.255.255.255:65535/sample_project.git';
if($server === "prd"){
$releases_dir = '/var/www/html/sample_project_prd/releases';
$app_dir = '/var/www/html/sample_project_prd';
}elseif ($server === "stg") {
$releases_dir = '/var/www/html/sample_project_stg/releases';
$app_dir = '/var/www/html/sample_project_stg';
}
$releases_dir = '/var/www/html/sample_project/releases';
$app_dir = '/var/www/html/sample_project';
$release = 'web_'.date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
@endsetup
@story('deploy_production', ['on' => 'prd'])
clone_repository
run_composer
copy_unity_build_dir
copy_setting_file
update_symlinks
clean_old_releases
@endstory
@story('deploy_staging', ['on' => 'stg'])
clone_repository
run_composer
copy_unity_build_dir
copy_setting_file
update_symlinks
clean_old_releases
@endstory
@task('clone_repository')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
@if ($branch)
git clone -b {{ $branch }} {{ $repository }} {{ $new_release_dir }}
@endif
cd {{ $new_release_dir }}
git reset --hard {{ $commit }}
@endtask
@task('run_composer')
echo "Starting deployment ({{ $release }})"
cd {{ $new_release_dir }}
composer install --no-dev
@endtask
@task('update_symlinks')
echo "Linking storage directory"
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage
echo 'Linking .env file'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env
echo 'Linking current release'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask
プロジェクト専用のGitLab Runnerを登録する。
-
リポジトリのソースを参照できるページのサイドバーにて
[Setting] → [CI/CD] で CI/CD専用の設定ページにアクセスする。
「Runners」を選択した後に出てくる、「Specific runners」の項目の部分にて、「Register the runner with this URL:」(A) と「And this registration token:」(B) が記載されているので、こちらの2つを控える。 -
GitLab Runner 専用のCIサーバーにログインする。
-
以下の様にGitlab Runnerの新規登録を行う。
[root@gitlab-runner ~]# gitlab-runner register
Runtime platform arch=amd64 os=linux pid=18464 revision=775dd39d version=13.8.0
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.com/
Enter the registration token:
aaaaaaaaaaaaaaaaaaaaaaaaaaa
Enter a description for the runner:
[gitlab-runner]:
Enter tags for the runner (comma-separated):
Registering runner... succeeded runner=fGaG43tQ
Enter an executor: docker-ssh, parallels, docker+machine, docker-ssh+machine, custom, docker, shell, ssh, virtualbox, kubernetes:
docker
Enter the default Docker image (for example, ruby:2.6):
php:7.4-fpm
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
-
Enter the GitLab instance URL
上記 1 の手順で控えた (A) のURLを入力する。 -
Enter the registration token:
上記 1 の手順で控えた (B) のトークンを入力する。 -
Enter a description for the runner:
特に記載内容がなければ、空欄のままEnter
-
Enter tags for the runner (comma-separated):
空欄のままEnter
-
Enter an executor:
docker
と入力する。
- 上記設定後、以下コマンドでrestartを行う。
gitlab-runner restart
環境変数の設定
Setting] → [CI/CD] で CI/CD専用の設定ページにアクセスする。
「Variables」を選択した後に出てくる設定項目から設定を行う。「Add Variables」を押した後に各環境変数の設定を個別で行えるようになっている。
SSH_CONFIG_ENVOY
host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Host web-prd-step
HostName 165.76.149.78
User deployer
ForwardAgent yes
Host web-prd
HostName 192.168.1.2
User root
ProxyCommand ssh -W %h:%p web-prd-step
ForwardAgent yes
Host web-stg
HostName 192.168.1.1
User root
ProxyCommand ssh -W %h:%p web-prd-step
ForwardAgent yes
SSH_KEY
こちらには GitLab専用の秘密鍵をコピーして保存する。
authorized_keys について
自動デプロイの対象となるサーバーにて以下の設定を行う。
デプロイ対象となるサーバーに公開鍵を配置する。
vi ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Webサーバーのディレクトリについて
自動デプロイ対象のwebサーバーにて以下のディレクトリを作成する必要がある。
- あらかじめ作成しておく必要があるディレクトリ及びwebアプリの設定ファイル
web
├── config-user.xml
├── config.php
├── config.xml
└── releases
- CI/CDの運用が開始されると以下の様なディレクトリ構成になる
web
├── config-user.xml
├── config.php
├── config.xml
├── current ※シンボリックリンクを張った際に自動的に作成される。
└── releases
├── web_20220225_135238
├── web_20220301_011932
└── web_20220228_093111
Webサーバーの設定
nginxのconfファイルを以下の内容に編集する。
server {
listen 11000 ;
root /var/www/html/web/current/public;
server_name www.example.jp;
access_log /var/log/nginx/web_access.log main;
error_log /var/log/nginx/web_error.log warn;
location / {
root /var/www/html/web/current/public;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php,index.html;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
nginxの再起動を実行。
systemctl restart nginx
設定完了
参考資料
Discussion