gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

開発手順草案

開発手順の草案とか考えてみました。
色んな手順あるかと思うのですが、一度、自分の手順を色々と「揉んでみたい」なぁ、って思ったので。

目的

ある程度低コストで、かつ「複数のエンジニア&デザイナ」が存在していることを前提に。
運用が楽で、且つある程度の安全性が保てるような「開発手順」について、それを定めることを目的とする。

注意

マニュアルっぽく書こうと思ったのでなんか断定的な書き方がありますが、基本的にこれは「草案」です。
検討して議論してもむための「素体にする」ため、程度のものなので、色々とご注意ください。

事前準備

サーバは、物理的には2台用意する(仮想マシン2台でもOK)。これがミニマム。
論理的には、以下の役割がそれぞれ存在する。

  • gitサーバ(ないし、適切なバージョン管理用サーバ):redmineなどを合わせて載せても良い
  • 個人用開発Webサーバ(個人毎なので複数)
  • 個人用開発DBサーバ(「開発用DB」で1つ作り、これをみんなで使う。あと、必要に応じて「個人専用」を、臨機応変に)
  • ステージング用Webサーバ
  • 本番用Webサーバ
  • 本番用DBサーバ

ミニマムで進める場合、「gitサーバ+個人用+ステージング」で1台、「本番用」で1台とする。

ざっくりした開発の流れ。

  • 開発者は、git pullしてから適宜個人開発環境で開発/デバッグ
  • 個人開発環境で問題が無ければ、gitのbare/masterに対してpush
  • ステージングにて、bare/masterからpull
  • ステージングに持ち上げてDBを「開発用DBサーバ」に向けてテスト
  • ステージングに持ち上げてDBを「本番用DBサーバ」に向けてテスト
  • 本番化判定を行う(どっちかというと政治的行為)
  • 「ステージングのファイルをrsyncする事で」本番化

前提

環境に依存する設定ファイルは「シンボリックリンクで解決する」ものである、とします。簡単な説明は http://d.hatena.ne.jp/gallu/20120724/p1 をご覧ください。
別に環境変数とif文でもいいのですが、シンボリックリンクのほうが「1ファイルのサイズが肥大化しない」ので、色々と気が楽です。
これは「強制」ではなく「推奨」なので、状況その他的に「どうしても環境変数が良い」という場合、それを「何が何でも禁止する」ものではありません。

詳細:前準備

ドメインを用意する
本番、ステージング、各個人用のドメインをそれぞれ用意しておきます。

・サーバを用意する
本番、ステージング、各個人用のサーバをそれぞれ用意しておきます。DBは、本番と開発用DBと、各個人用とをそれぞれ。個人開発環境(と、多分ステージング)は、httpd.confでvirtual_hostの設定とかがいると思われますので、適宜。
バージョン管理はgitを想定。SVNでも多少の修正で行けると思うけど。
バグ管理システムはあった方がよいと思う。別にredmineである必要はないにしても(でもメジャーだよねぇ)。
ポイントは「本番とステージングは、絶対パスまでを全部クリソツ*1にしておく」事。圧倒的に面倒が減るから。


・gitの準備
とりあえず適当なところに1つ、bareなレポジトリを作成。ここを「絶対主」とします。
個人環境でもとりあえず各自 git init なんぞを。ステージングも git initしておきまふ。


・configの準備(これは初手じゃなくて、開発が始まってからになるかも)
シンボリックリンクを「環境毎に」適切に張っておきます。

詳細:開発本番

開発する

・開発内容を確認
・何はともあれ git pull で、お手持ちを最新にする
・お好みでブランチを切ってもいいし、このタイミングではとりあえず切らなくてもいいし
・開発する。もし「DBにcreate tableとかalter tableとか」する場合、memoって置くと楽。configに追加修正するときもmemoっておこう。「DBの修正」が入る場合、開発環境のDB接続用configを「開発用DB」から「自分専用DB」に切り替えておきましょう。
 >まずテストコード書くとよいよ
 >「これが通ったら完了」なシナリオを先に準備しよう
 >まずは「日本語プログラミング」で、プログラムの流れを整理整頓
 >実装!!
 >「予定されたシナリオ」クリアチェック!!
デバッグまで含めて「いい感じに実装が終わったら」git pull & git pushする。もしgit pullでなんかmergeされたら、pushするまえにちゃんとテストし直すんだよ?
・さっきのDB修正とかconfig修正とかのmemoを周囲に連絡。configあたりは自分で修正して「修正したからpullっといて〜」ってのもあり。DBの場合、開発用DBには(周りに声をかけた上で)速やかに修正。本番用DBはPM等との相談になるけど、基本「とっととやっといたほうが」安全な事が多い。
・DBの設定が「個人用」になってたら、「開発用DB」にスイッチ切り直し。このタイミングで念のためにもう一度テストしておくと丁寧。
redmineとかで管理してるなら、チケットを「おわた〜」的statusに変更。


で、終了。

ステージングに持ち上げて確認する

・BEGIN(トランザクション的な意味で)。本番化が近々行われる場合だけ、注意。「ステージングのチェック中に本番化が平行で行われる」とまずいので、そこはちゃんとスケジューリングを。
・ステージングのディレクトリで、まずはgit pull
・DBを「開発用DB」用にスイッチ
・テスト。ここでこけたら速やかに開発者に突っ返して修正してもらう
・DBを「本番環境」用にスイッチ。
・もう一回テスト。DBの修正漏れとか、ここで見つかる。100%とは言わないけど、テーブル追加とかカラム追加とか、大抵「現在の本番には影響が出ない」事がおおいから、先にやってとっととこの辺で見つけとくほうが楽なんだよね
・もし「ステージング会議」的なものがある場合、ここで「会議に差し出す」準備が出来た感じ。無ければ「本番化」を、タイミング見繕って開始する!!


政治的問題がなければここで「本番化準備」完了。
政治的問題がある場合、ここから「稟議の場」に意向して「リリースOK」の判子をもらいに行きます。

本番化への道のり

・大丈夫なはずだけど、一応「ステージングでソースコードチェック中」なら本番化中止。
・エンジニア&運用さんに待機してもらう(多分10分くらい)
rsyncコマンド(あらかじめファイルに用意しておこう)で、本番化。具体的には以下の通り。
 >※「シンボリックリンク」はちゃんと --exclude つかって「除外」しておくこと!
 >rsyncで「本番マシンのコードを」「ステージング環境のバックアップディレクトリに」一通りcopy
 >rsyncで「ステージング環境のコードを」「本番マシンに」copy
・待機しているエンジニア&運用さんが、本番サイトをチェック
 >万が一「やべぇ」な場合、急ぎ「ステージング環境のバックアップディレクトリ」を「本番マシンに」copyして、なかったことにする。でも出来れば、情報は少しでも得ておきたいところ。


問題なければ「本番化終了」。
お疲れ様でした!!

開発中に「緊急バグ修正」とか入ったら?

・gitのブランチを切る
・ブランチ先で「バグ修正」をやる
・ブランチをbareレポジトリのmasterにpushしてステージングチェックまでをやる
・localのブランチ(緊急バグ修正)とlocalのmaster(開発中のブツ)をmergeする
・一応バグ修正が消えてない&エンバグしてない事を確認する
・開発を続ける

疑問点

・gitのレポジトリ管理どする?
http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html
とかが元ネタ。
メインブランチ+サポートブランチのやり方とか、綺麗だと思うしできれば載せたいんだけど…上述の開発の流れで実際に「じゃぁどこに載せよう?」って時に、悩みっぱなし。
分散型だからってのもあるんだけど。「localのmasterで開発して、問題なければremoteのmasterにpushする」で事足りちゃうような気がしてならない。
いやまぁもちろん「メインタスク着手時に緊急タスクが来たら」ってのはあるんだけど、その場合、そのタイミングで適宜、localにブランチを切り直してそっちで作業すればよいかなぁと思うので。まぁ個人が「あらかじめ手元に持ち込むときはブランチ切っておく」事について、否定するつもりは0.1mmたりとてないのですが。
「origin/master は、製品として出荷可能な状態を常に反映する、ソースコードの HEAD のありかであるメインブランチ」「origin/develop は、次のリリースのための最新の開発作業の変更を常に反映する、ソースコードの HEAD のありかであるメインブランチ」だとすると。
多分おいちゃんの開発手順では「"ステージングにあるソース"がorigin/master相当で」「origin/masterがorigin/develop」なんだよなぁ、っと。
この辺大分と色々懐疑的なので、突っ込み大歓迎いたします。
できれば、少し突っ込んで議論したいところなので(苦笑
# それこそ、場合によっては「別ブランチ」で議論したいw

*1:…言い方古い?