カオスだったお(^ω^
でもそんなに難しいことじゃないので、一応読めばできると思う。だけど逃げ出したくなるめんどくささ。
普通のエンジニアにはAWSをポチってJenkinsにリモートでシェルを叩いてもらいましょう。それでもこのカオスな環境を作りたい人はメモを読んでね。
やりたいこと
GM◯ iClustaのサーバにJenkinsを使ってCakePHPを自動デプロイしたい
構成
社内環境
- gitlab
- jenkins
本番サーバ
GM◯ iClusta
本番のディレクトリ
/root_dir/document_root/workspace/script/ # script格納用ディレクトリ /root_dir/document_root/workspace/tmp_release/ # リリース前のコピー元ディレクトリ /root_dir/document_root/production/ # 本番ディレクトリ
今回のデプロイ先の通信はFTPオンリーのため、Jenkinsの「リモートでシェルを実行」が使えない。ただ、sshが使えないだけで、サーバはLinuxサーバなので、内部でのshellは実行することができる。なのでちょっとだけ工夫する必要がある。
今回はShellはPHPから実行するようにした。また、外部から実行する必要があるためscript格納用ディレクトリはDocumentRoot
の中に配置してあげないといけない。ただ、セキュリティ上問題だろうなと思うので、処理が終了したらscript
ディレクトリごと削除するような処理を書いたほうがいいかも。
gitlab -> jenkinsの連携
リリース用のリポジトリ作成
gitlabで新規リポジトリを作成すればおkです。手順は割愛。
jenkinsでデプロイのjob作成
3つ作成しました。
- switch-trigger ・・・ 特定のブランチにpushされた時に、デプロイのjobを叩く
- upload ・・・ gitリポジトリからリリース用のブランチを取得して、サーバへアップロード
- exec-deploy ・・・ アップロードされたデータを本番ディレクトリへデプロイするためのコマンドを実行するShellを叩くjob(長い)
上から順にjobをつなげてリリースしようと思います。
必要なplugin
- build pipeline ・・・ 他jobがビルドされたら自分のjobを叩くみたいなことができる
- GIT plugin ・・・ Gitを使うために必要
- Publish Over FTP ・・・ サーバへのアップロードはFTPのみなので、これで対応しました(´・ω・`)
- Fiexible publish ・・・ ビルド後に条件を用意して通ったら別jobを叩くみたいなことができます。
設定の詳細
switch-trigger
こいつの役割は上に書いたとおりですが、もう少し詳しく書くと、gitlabのhookでこのjobを叩く用に設定します。pushでhookしてあげてください。
で、そのpushのhookはどのブランチがpushされてもこのjobが叩かれる用になります。これはちょっと面倒です。だってリリースしたいブランチが更新されたときだけデプロイしたいから。
なので、このjobでリリースのブランチがpushされたかどうかを確認しないといけません。
- リリースしたいブランチがpushされた => upload jobを叩く
- リリースしたいブランチ以外のブランチがpushされた => 何もしない
ってな感じです。
それでは設定のお話。
switch-trigger
の設定から下記設定を行います。
ソースコード管理
知っている人は多いと思いますので詳しくは割愛です。gitlabのurlを登録して上げましょう。
1点だけ。あとから「ビルド後の処理」でリリースしたいブランチがpushされたかチェックするって処理を書きますが、それを対応するためにはすべてのブランチを落としてこないといけないっぽいです。
ちゃんと検証したわけじゃないので、これが正解かわかりませんが、とりあえずBranches to build
-> Branch Specifier (blank for 'any')
を**
で登録してください。
ビルド後の処理
ここで、Fiexible publish
を選択し、Run?
の項目をExecute Shell
で下記ソースコードを実行するようにします。
#!/bin/sh PUSHED_BRANCH=`git branch -r --contains ${GIT_COMMIT}` # *master* の箇所を任意に変更 # リリースしたいブランチ名をここに記載します if [[ ${PUSHED_BRANCH} == *master* ]]; then exit 0 fi exit 1
んで、Action
のほうは他のプロジェクトをビルド
を選択して、upload
のjobを選択してあげましょう。
これでおk
ここまでの参考
upload
こっちもswitch-trigger
と同様、gitの設定を行います。違うのはリリース対象のだけのブランチ名を指定してあげること。
んで、ビルド後の処理
にPublish Over FTP
の設定を登録してください。
これでアップロードのjobの用意はおk。
exec-deploy
3つ目はアプリケーションアップロード後、シェルを叩くためのjobになります。
エンジニアの皆さんは通常はリモートでシェルを叩けばいいと思いますが、私は強制縛りプレイなのでシェルを叩くPHPをサーバへ配置してそいつをアクセスするシェルを叩くようにします。
その前に、build pipeline
でupload
のjobが終了したらexec-deploy
のjobを実行するようにします。
ビルド・トリガ
ここから他プロジェクトの後にビルド
にチェックをいれて対象プロジェクト
をupload
で登録します。これでupload
のjobが安全に終了したらexec-deploy
のjobが起動するようになります。
ビルド
ここで目的のPHPを叩くシェルを登録します。
シェルの実行
を選択して、下記コマンドを登録。
curl -s 'http://hogehoge.com/script/shell_exec.php'
これでおk
ここまでがJenkinsの設定になります。
テストしてみた。
試しにexec-deploy
以外を叩きテストしてみたところ「response 421 received」(°ω°
ファイル数が多い -> アップロード時間が長くなる -> 切られる
・・・
さすが安定のGM◯ですね!
ということで、今回デプロイ対象のアプリケーションはCakePHPだったので、/lib/
ディレクトリは初回のアップだけにして、次回から変更するまではアップしないでおこうと思います。/app/
だけアップします。
scriptの話
叩くシェルスクリプトはいくつか用意しました。下記が(大雑把な)内容になります。
- shell_exec.php 下2つのシェルを叩くphpファイル
- release.sh バックアップ取得 => アップロードしたディレクトリから本番のディレクトリに
rsync
を実行します - reset.sh 下記に参考URLがありますが、あれを全くコピペしたファイルです
詳しくはまたいつかあげようかなと思います。(今内部情報がいっぱい記載されているのでリファクタが必要なので)
参考
これからやること
とりあえずここまでできれば、アップロードの作業は自動化することができます。ただ、これじゃまだまだなところが何個かあります。
今後対応完了したら追記していこうかなと思います。
テスト
リリース前にテストが組み込めていません。が、どちらかといえば、リリース用のブランチにマージする前に行うことだと思いますのでこれはまた別のフェーズな気がします。
DB Migration
これがいまいち理解できていなくて頭を悩ましています。
一応マイグレーションファイルを作成するなどのチュートリアルは一通り理解していますが・・・
- リリースで動作しているデータはどうなるの?
- DBの構造を大きく変えた場合、前のバージョンデータをどう移行するのか?
などなどがうまく理解出来ていません。個人的な考えとしては、本番のデータを一旦開発環境に落としそれを組み替えてから本番に適応する。ってのが一番現実的ななのかな。って思いました。
が、リアルタイムでリリースしたいのに結局準備しないといけないってのはどうなの? ひとつのサーバで運用するからダメなのかね? やっぱりまだよくわからん(´・ω・`)
ロールバックについて
これはテストをしっかり行えばそもそも行わなくて良いフェーズだと思いますが、万が一なにか発生した場合も考慮しないといけないのかなと思います。
一応今回作ったスクリプトではrsync
前に、前のアプリケーションファイルを指定のディレクトリにバックアップ。んでsql dumpを行う。って流れにしています。
もし戻したい場合は別jobとscriptの用意が必要かな。
雑な感想
工数にして約6h...かかり過ぎやで。
でも前向きな考えで。これから手動で行ってた作業が自動化されるのでいいかなと思う。元は余裕でとれるはず。
しかし、そもそもサーバが遅いのがアレなので、VPSとかクラウドサービスにしてほしいなと本気で感じた1日でもありました。
だって、アップロードの処理をこんな分割せずとも、jenkinsのLinuxホストから本番にrsync
で一発だもんね。泣きたい。