[保存版] CircleCI 2.0による自動デプロイの導入手順まとめ
こんにちは、たつきちです。
自動デプロイのためのCircleCIの導入手順が端的にまとまっている情報が意外とググっても見つけにくいなと思ったので、自分用のメモ書きを清書して記事にしておきます👌
CIの導入はプロジェクトの開始時に一度しかやらない作業なので、僕も毎回やり方を忘れてます。わざわざ覚えておく必要なんて全然ないと思いますので、プロジェクトの開始時に毎回この記事を見に来てもらえたらいいかなと思います。
今回はPHP製のデプロイツール「deployer」を使って物理サーバーにデプロイするケースを例に、具体的な手順を説明していきます。
ちなみに、自動デプロイの概念自体がまだよく分かっていないという方には、僕が以前にSchoo(スクー)さんで行った講義 が参考になると思いますので、ぜひご覧ください。
1. CircleCI上にプロジェクトを追加
まず、ダッシュボードの PROJECTS で、目的のGitHubリポジトリを選択してプロジェクトを追加します。
2. デプロイキーを登録
次に、CircleCIからデプロイ先サーバーにssh接続できるようにするために、デプロイキーを登録します。
具体的には、ローカルでキーペアを作って、秘密鍵のほうをCircleCIに、公開鍵のほうをデプロイ先サーバーに登録します。
2-1. CircleCIに秘密鍵を登録
以下のように ssh-keygen
コマンドでキーペアを作ります。
$ ssh-keygen -t rsa -f id_rsa.tmp -C "CircleCI / プロジェクト名" -N "" -m PEM
パラメータの意味は以下のとおりです。
-
-t rsa
RSA方式を指定 -
-f id_rsa.tmp
カレントディレクトリにid_rsa.tmp
というファイル名でキーペアを生成 -
-C "CircleCI / プロジェクト名"
公開鍵の末尾に記載されるコメントを指定(あとで見分けやすいように) -
-N ""
パスフレーズなしを指定 -
-m PEM
macOS Mojave以降だとデフォルトでOpenSSH形式の鍵が生成されてしまい、CircleCIが対応していないので、PEM形式を指定
秘密鍵のほうをクリップボードにコピーします。
# macOSの場合
$ pbcopy < id_rsa.tmp
# それ以外の場合
$ cat id_rsa.tmp
# 出力された内容を手でコピー
ダッシュボードのビルド一覧画面の各行の右端の ...
から Project Settings
を開いてプロジェクトの設定画面を開きます。 以下のようなURLの画面です。
https://app.circleci.com/settings/project/github/<user>/<repo>
メニューにある SSH Keys
を開いて、 Add SSH Key
から秘密鍵を登録します。
Hostname
は空のままで、 Private Key
に先ほどコピーしておいた秘密鍵を貼り付けて送信すればOKです。
登録すると、SSHキーのfingerprintが表示されます。これは後で使いますので、どこかにコピーしておいてください。
2-2. デプロイ先サーバーに公開鍵を登録
続けて、公開鍵をデプロイ先のサーバーの ~/.ssh/authorized_keys
に追記します。
# macOSの場合
$ pbcopy < id_rsa.tmp.pub
# それ以外の場合
$ cat id_rsa.tmp.pub
# 出力された内容を手でコピー
$ ssh [ターゲットユーザー]@[ターゲットサーバー]
% vi ~/.ssh/authorized_keys # 末尾にクリップボードの内容をペースト
% exit
$ rm id_rsa.tmp* # もう要らないので削除
あるいは、 ssh-copy-id
コマンドがインストールされている場合であれば(Mac なら brew install ssh-copy-id
で入れられます)、以下のような方法でもっと簡単に追記することもできます。
$ ssh-copy-id -i id_rsa.tmp.pub [ターゲットユーザー]@[ターゲットサーバー]
$ rm id_rsa.tmp* # もう要らないので削除
3. プロジェクトの環境変数にDockerHubの認証情報を追加
2020/11/1より、DockerHubにおいてイメージのpullに 回数制限 が設けられました。
この制限を少しでも緩和するため、イメージをpullする際にDockerHubユーザーでログインすることが推奨されています。
ちなみに、認証なしだと6時間あたり100回、無料ユーザーは6時間あたり200回がpullの上限となっています。有料ユーザーは無制限です。(参考)
具体的には、公式ドキュメント に書かれているとおり、後述の設定ファイルにDockerHubの認証情報を書き足せばよいのですが、認証情報を直接書きたくないので、プロジェクトの環境変数に格納しておいて、それを参照するようにします。
プロジェクト設定画面の Environment Variables
を開いて、 Add Variable
から環境変数を登録します。
Name |
Value |
---|---|
DOCKERHUB_USERNAME |
{DockerHubのログインユーザー名} |
DOCKERHUB_PASSWORD |
{DockerHubのログインパスワード} |
上記のように2つ環境変数を登録しておきましょう。
4. プロジェクトのコードベースにCircleCIの設定ファイルを追加
/.circleci/config.yml
というファイルパスでCircleCIの設定ファイルを設置します。
最初にCircleCIにプロジェクトを追加したときに雛形が表示されたと思うので、それを元に改変するのがよいでしょう。
設定ファイルのDSLの詳細は 公式リファレンス に細かく記載されています。
PHPプロジェクトであれば この辺 も参考になります。
ただし、これらの雛形にはビルドジョブの設定しかなく、自動デプロイまでは想定されていないため、そこは自力で書く必要があります。
例えばPHPプロジェクトの場合ならおおよそ以下のような内容になるかと思います。
.circleci/config.yml
の例
version: 2
jobs:
test:
docker:
- image: circleci/php:7.2-cli-node-browsers
auth:
username: $DOCKERHUB_USERNAME
password: $DOCKERHUB_PASSWORD
working_directory: ~/wd
steps:
- checkout
- run: sudo composer self-update
- restore_cache:
keys:
- composer-v1-{{ checksum "composer.json" }}
- restore_cache:
keys:
- node-v1-{{ checksum "package.json" }}
- run: composer install -n --prefer-dist
- save_cache:
key: composer-v1-{{ checksum "composer.json" }}
paths:
- vendor
- save_cache:
key: node-v1-{{ checksum "package.json" }}
paths:
- node_modules
# test
- run: vendor/bin/phpunit
deploy:
docker:
- image: composer
auth:
username: $DOCKERHUB_USERNAME
password: $DOCKERHUB_PASSWORD
working_directory: ~/wd
steps:
- checkout
- add_ssh_keys:
fingerprints:
- xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
- run:
name: install deployer
command: |
composer global require deployer/deployer
echo 'export PATH=/tmp/vendor/bin:$PATH' >> $BASH_ENV
- deploy:
name: dep deploy
command: |
dep deploy production -vvv
workflows:
version: 2
test_and_deploy:
jobs:
- test
- deploy
- deploy:
requires:
- test
filters:
branches:
only: master
以下のあたりがポイントです。
-
deploy
ジョブからデプロイ先サーバーにssh接続させるために、add_ssh_keys
ディレクティブ を使って、先ほど登録したSSHキーのfingerprintを指定している - Dockerイメージを使用する際に、先ほど登録した環境変数
$DOCKERHUB_USERNAME
$DOCKERHUB_PASSWORD
を使ってDockerHubにログインしている - デプロイを実行するための環境として、ここでは composer Dockerイメージを使っており、deployerをインストールしたパスを
PATH
環境変数に追加するために$BASH_ENV
環境変数 を利用している
5. プロジェクトのコードベースにdeployerの設定ファイルを追加
/deploy.php
というファイルパスで deployer の設定ファイルを設置します。
deployerをインストール して、プロジェクトルートで
$ dep init
を実行すれば雛形を作成することができます。
一例として、シンプルなPHPプロジェクトであれば以下のような内容になるかなと思います。
deploy.php
の例
<?php
namespace Deployer;
require 'recipe/common.php';
// Configs
set('repository', 'git@github.com:<user>/<repo>.git');
set('git_tty', true);
set('shared_files', ['.env']);
set('shared_dirs', []);
set('writable_dirs', []);
// Hosts
host('production')
->hostname('<hostname>')
->user('<user>')
->addSshOption('StrictHostKeyChecking', 'no')
->set('deploy_path', '/path/to/target');
// Tasks
task('deploy', [
'deploy:info',
'deploy:prepare',
'deploy:lock',
'deploy:release',
'deploy:update_code',
'deploy:shared',
'deploy:writable',
'deploy:vendors',
'deploy:clear_paths',
'deploy:symlink',
'deploy:unlock',
'cleanup',
'success'
]);
after('deploy:failed', 'deploy:unlock');
6. その他
以上で自動デプロイの設定は完了ですが、ついでにSlack通知の設定方法と、READMEにCircleCIのステータスバッジを埋め込む方法についてもメモ書き程度に書いておきます。
6-1. CircleCIから結果をSlackに通知する
プロジェクト設定画面のメニュー Chat Notifications
から設定できます。
SlackでCircleCI連携を設定した上で、発行されたWebhook URLを上記の画面に入力するだけでOKです。
6-2. READMEにCircleCIのステータスバッジを埋め込む
プロジェクト設定画面のメニュー Status Badges
で、ステータスバッジを表示するためのMarkdownスニペットが取得できるので、それを README.md
に貼り付けるだけです。
ただし、プライベートリポジトリの場合は先に以下の手順でAPIトークンを作っておく必要があるので要注意です。
プロジェクト設定画面のメニュー API Permissions
で Create Token
をクリックし、
- スコープは
Status
のまま -
Token label
は何でもいいけどto-get-build-status
など分かりやすい名前を適当に付ける
上記のような内容でトークンを作成します。
この状態で Status Badges
の画面を開くと、 API Token
という欄で先ほどの to-get-build-status
が選択できるので、それを指定してあげればOKです。
Discussion