LoginSignup
8
11

More than 5 years have passed since last update.

GitLab Runner+Capistranoで継続的デプロイ

Last updated at Posted at 2016-11-28

GitLab Runner の使い勝手がなかなか良くなったそうなので、Capistrano3 と組み合わせたデプロイ環境を作成しました。

実現したいこと

  • staging または master ブランチへの push イベントをトリガーとして GitLab 上の Pipeline を回す。
  • Pipeline ではテスト ジョブとデプロイ ジョブを実行するが、デプロイ ジョブの実行は手動とする(GitLab の Web UI 上でジョブを実行させて結果の成功/失敗を確認したいため)。
  • デプロイ ジョブでは Capistrano のタスクを実行し、リモート環境(ステージング または プロダクション環境)にコードをデプロイする。
  • Capistrano では SSH エージェント転送を有効にして、タスク実行元に保管された秘密鍵をデプロイ先サーバーに転送し、この鍵を使って GitLab に SSH 接続を行いコードを取得する。
  • デプロイしたコードに問題があった場合に備え、ロールバック ジョブも用意する(ロールバックも手動実行とする)。

各種バージョン

※以降、gitlab-ci-multi-runner をインストールするサーバーを Runner サーバーと呼ぶこととします。

各アカウントおよびドメイン名

サーバー種別 ドメイン名(※) タスク or デプロイ実行アカウント名
Runner サーバー runner-svr.example.com gitlab-runner
ステージング サーバー staging.examle.com deploy-user
プロダクション サーバー production.examle.com deploy-user

※実際のドメイン名ではなく、説明するための例として記載します。

処理フロー イメージ

runner-environment-image.png

環境構築手順

SSH 公開鍵認証用の設定

秘密鍵/公開鍵の生成

GitLab から Runner に対し処理実行を命じるとき、自動的に Runner サーバー上に gitlab-runner アカウントが追加されます。
今回 Runner + Capistrano + SSH エージェント転送を実現するに当たって、gitlab-runner アカウントが利用可能な秘密鍵を用意する必要があるため、あらかじめ gitlab-runner アカウントを Runner サーバー上に追加し、この gitlab-runner のホームディレクトリ以下に秘密鍵と公開鍵を保管しておきます。

$ hostname
runner-svr
$ sudo -s
# adduser gitlab-runner
// gitlab-runner アカウント情報を入力
# su - gitlab-runner
$ ssh-keygen -t rsa -N "" -C "gitlab-runner@runner-svr.example.com"

デプロイ先サーバーへの公開鍵配布

Capistrano スクリプト実行時、SSH 公開鍵認証でステージングまたはプロダクション環境にログインさせるため、作成した公開鍵(/home/gitlab-runner/.ssh/id_rsa.pub)を、ssh-copy-id で各サーバー上の(デプロイ用アカウントのホームディレクトリ)/.ssh/authorized_keys に登録します。

$ hostname
runner-svr
$ whoami
gitlab-runner
// リモートのステージングおよびプロダクション サーバーに公開鍵を登録する
$ ssh-copy-id -i /home/gitlab-runner/.ssh/id_rsa.pub deploy-user@staging.example.com
$ ssh-copy-id -i /home/gitlab-runner/.ssh/id_rsa.pub deploy-user@production.example.com

GitLab にデプロイ キーを登録する

生成した公開鍵を使って GitLab からソースコードを取得してデプロイするため、この鍵をデプロイ専用の鍵として GitLab に登録します。
登録は GitLab Web UI 上のプロジェクト > "設定" ドロップダウンリスト > Deploy Keys から行います。

もしプロジェクト共通のデプロイ キーとして登録したい場合は、管理者権限を持つユーザーで Web UI にログインし、"Admin Area" > "設定" ドロップダウンリスト > Deploy Keys から登録してプロジェクトの Deploy Keys ページで対象キーを「Enable」にします。

Capistrano のインストール & 設定

インストール

Runner サーバー上に gem を利用して Capistrano をインストールします。

$ hostname
runner-svr
$ sudo -s
# apt-get update && apt-get install ruby -y
# gem install bundler net-ssh capistrano

Capistrano スクリプト実行環境の作成

gitlab-runner アカウントで Runner サーバーにログインし、任意のディレクトリを作成します。
このディレクトリ内に Gemfile を保管して bundle install と cap install コマンドを実行します。

$ hostname
runner-svr
$ whoami
gitlab-runner
$ mkdir ~/capistrano
$ cd ~/capistrano

// capistrano ディレクトリの中に Gemfile を作成またはコピーする

$ ls -l
-rw-rw-r-- 1 gitlab-runner gitlab-runner  125 Nov  7 18:06 Gemfile

$ bundle install --path vendor/bundle
$ cap install
(必要なファイル、ディレクトリのひな形が自動生成される)

capistrano ディレクトリ構成イメージ

/home/gitlab-runner/capistrano
├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
├── Gemfile
├── Gemfile.lock
├── log
├── vendor
└── lib
    └── capistrano
            └── tasks

設定ファイルの編集

deploy.rb ファイル

cap コマンドでデプロイを実行するとき、コマンド オプションでデプロイするブランチを指定できるようにするため、次の設定を追加します。

deploy.rb
# もし環境変数 BRANCH に値がセットされていなかった場合、ブランチ名の確認プロンプトが表示されます
set :branch, ask('Branch: ', nil) unless ENV['BRANCH']

※注意
後述する .gitlab-ci.yml のジョブ内で環境変数 BRANCH にブランチ名をセットしますが、もし BRANCH に値がセットされていなかった場合でも Runner のジョブの実行結果は "Build succeeded" と表示されます。しかしデプロイ自体はなされません(Capistrano の以降のタスクがスキップされます)。

staging.rb と production.rb ファイル

デプロイ時に SSH 公開鍵を使ってデプロイ先サーバーにログインし、また SSH エージェント転送を有効にするため以下のオプションを追加します。

staging.rb/production.rb
set :ssh_options, {
  user: 'deploy-user',
  keys: %w(/home/gitlab-runner/.ssh/id_rsa),
  forward_agent: true,
  auth_methods: %w{publickey}
}

その他の Capistrano 設定項目については、公式ドキュメントを参照し設定します。

デプロイ テスト

Capistrano スクリプトが成功するか一旦テストします。

$ hostname
runner-svr
$ whoami
gitlab-runner
$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa

$ cd ~/capistrano
$ BRANCH=staging bundle exec cap production deploy

エラーが出ず、成功した場合は Capistrano の準備は完了です。

gitlab-ci-multi-runner のインストール

Runner サーバーに gitlab-ci-multi-runner をインストールします。
手順は公式マニュアルの通りに実行するだけです。

$ hostname
runner-svr
$ sudo -s
# curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
# apt-get install gitlab-ci-multi-runner

Runner の登録

Runner を登録します。

# hostname
runner-svr
# gitlab-ci-multi-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):

https://(使用している GitLab のドメイン名)/ci ---- (1)

Please enter the gitlab-ci token for this runner:
(GitLab 上で表示されるトークン) ---- (2)

Please enter the gitlab-ci description for this runner:
myrunner ---- (3)

Please enter the gitlab-ci tags for this runner (comma separated):
myproject ---- (4)

Registering runner... succeeded                     runner=xxxxxxxx
Please enter the executor: shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, ssh:
shell ---- (5)

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Register オプション

  • (1) gitlab-ci coordinator URL
    GitLab Web UI 上で何らかのプロジェクト > "設定" ドロップダウンリスト > Runner ページを開くと、"Specific Runners" に Runner 設定用の値が記載されています。
    その内の "Specify the following URL during the Runner setup: " で示された URL を指定します(現状 GitLab の URL + /ci で規定されているようです)。
  • (2) gitlab-ci token
    同じくプロジェクトの Runner ページに表示されたトークンを指定します。
    Shared Runner (プロジェクト共通で利用可能な Runner)を登録する場合は、GitLab に管理者権限のあるユーザーでログインし、Admin Area > Overview > Runners ページに表示されたトークンを指定します。
  • (3) gitlab-ci description for this runner
    Runner の表示名を指定します。ここで指定した名称は GitLab Web UI 上にも表示されます。
  • (4) gitlab-ci tags for this runner
    ジョブと Runner を紐付けるためのタグを指定します。カンマ区切りで複数タグが指定できます。
    指定しなくても構いませんが、タグを付けることでジョブの管理がしやすくなります。
  • (5) executor
    プロジェクト ビルド環境を指定します。たとえば、docker を選択すると Docker コンテナ上で各ジョブが実行されることとなります。
    docker+machine を選択すると更にコンテナの auto scale もできるそうですが、今回は shell を指定し Runner サーバー上でスクリプトを実行させることとします。 executor についての詳しい説明は、こちらのページを参照ください。

GitLab Web UI 上で Runner の状態を確認する

Runner の登録が成功すると、GitLab Web UI のプロジェクト > "設定" ドロップダウンリスト > Runner ページに、有効な Runner として表示されるようになります。
このとき、「Enable for this project」ボタンをクリックしないと Runner が有効化されないため必ずクリックしておきます。

active_runner.png

.gitlab-ci.yml の作成

Runner を動かすための設定ファイルとして、.gitlab-ci.yml をプロジェクト リポジトリのルート直下に作成します。
最新の GitLab CE では、Web UI のプロジェクト トップページにある「Set Up CI」ボタンをクリックすると .gitlab-ci.yml の作成 & 編集をブラウザからできるようになっているので、こちらを利用するのが手っ取り早いです。

setup-ci-button.png

.gitlab-ci.yml 記述例

.gitlab-ci.yml
stages:
  - test
  - deploy
  - rollback

test_job:
  stage: test
  script:
    - (テスト スクリプト実行コマンド)
  tags:
    - myproject

deploy_to_staging_job:
  stage: deploy
  script:
    - eval `ssh-agent`
    - ssh-add /home/gitlab-runner/.ssh/id_rsa
    - cd /home/gitlab-runner/capistrano
    - BRANCH=staging bundle exec cap staging deploy
  only:
    - staging
  tags:
    - myproject
  when: manual

deploy_to_production_job:
  stage: deploy
  script:
    - eval `ssh-agent`
    - ssh-add /home/gitlab-runner/.ssh/id_rsa
    - cd /home/gitlab-runner/capistrano
    - BRANCH=master bundle exec cap production deploy
  only:
    - master
  tags:
    - myproject
  when: manual

rollback_staging_job:
  stage: rollback
  script:
    - eval `ssh-agent`
    - ssh-add /home/gitlab-runner/.ssh/id_rsa
    - cd /home/gitlab-runner/capistrano
    - BRANCH=staging bundle exec cap staging deploy:rollback
  only:
    - staging
  tags:
    - myproject
  when: manual

rollback_production_job:
  stage: rollback
  script:
    - eval `ssh-agent`
    - ssh-add /home/gitlab-runner/.ssh/id_rsa
    - cd /home/gitlab-runner/capistrano
    - BRANCH=staging bundle exec cap production deploy:rollback
  only:
    - master
  tags:
    - myproject
  when: manual

.gitlab-ci.yml の各パラメーターについて

  • stages
    テスト、ビルドまたはデプロイなど各ジョブのステージを登録します。ステージ名("deploy" など)は任意に指定できます。 ステージの進め方(Pipeline の回り方)は基本的に書いてある順で進んで行き、前のジョブが成功したら次のステージのジョブが実行されます。
  • script
    処理したいコマンドを記述します。
  • only
    git ref の内容によって、ジョブを実行するかどうか判定します。今回は "staging" または "master" ブランチに push されたときのみにジョブが実行されるように、ブランチ名を指定しました。
  • tags
    Runner 登録時に設定したタグを追加します。タグを追加することで、複数の Runner が登録されていてもジョブの実行先 Runner を明示的に指定することができます。
  • when
    ジョブの実行タイミングを指定します。ここではデプロイとロールバックジョブは手動実行にしたかったため "manual" と記述しましたが、指定が無い場合は自動実行となります。

※test_job や deploy_to_staging_job などのジョブ名は適当につけています。ジョブ名は任意に指定できるので、ジョブの内容に合わせて適宜変更します。
※パラメーターのより詳しい説明はGitLab のドキュメントを参照してください。

デプロイ実行

準備が整ったのでいよいよ Pipeline を回します。
staging ブランチを push し、Web UI 上で対象プロジェクトの Pipelines ページから最新の Pipeline の Status をクリックします。

pipeline_success.png

Deploy ジョブは「skipped」になっているため、実行ボタンをクリックしジョブを開始させます。

manual_start_deploy.png

処理が開始されるとコンソール画面が表示され、最後に "Build succeeded" と出力されると成功です。

deploy-success.png

もしコードをロールバックしたい場合は、同じく Rollback ジョブを Web UI 上から実行します。

※補足

  1. git push の度に新しい Pipeline が追加されて行きますが、数代前の Pipeline の、未実行の manual ジョブを任意のタイミングで実行することもできます。
    今回は「常に staging または master ブランチの最新ソースをデプロイする」ように Capistrano 設定を書いていますので、ジョブの古さに関わらずジョブを実行した時点での最新ソースがデプロイされます。
  2. GitLab 8.14 から Pipeline の結果がメールで送信されるようになりました。自動実行ジョブが失敗したときのリカバリがしやすくなりますね。 Better Pipeline emails

参考サイト

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11