Hatena::ブログ(Diary)

miauの避難所

2009-09-25

本番サーバにチェックアウトしちゃダメですか?

この記事。まず訳がちょっと違うかな?という箇所があるのでそこを補っておくと。

しかしコードが実動サーバに乗る段階ではそれはローカルな作業用コピーではなく、エキスポートされた完成品だから、この問題が起こる。

こう訳されてる箇所があるけど、

When code is rolled to a live server from a repository, it is supposed to be done as an export rather than as a local working copy, and hence this problem.

実働サーバにコードを載せる場合は、ローカルな作業用コピーとして取得するのではなくエクスポートするべきだ。(だが今回はローカルな作業用コピーを本番に置いているので)問題になっている。

みたいな意味合いじゃないかなーと。(書いてて自信なくなってきた・・・。)

で、「svn export は違うだろ」と思ったので、とりあえず思うところを書いてみます。適宜ツッコミお願いします。


運用上良いと思う順に書いてみます。

案1: 本番環境をワーキングコピーにする

本番環境からリポジトリに直接アクセスして、svn checkout する運用です。もちろん .svnApache 側の設定でアクセス不可にしておきます。

こうすることの利点はいろいろあるんですが・・・。

  • 運用負荷が低い
    • svn update だけで更新できる
    • svn:executables を指定していれば、チェックアウト時に実行権限が付加されるので chmod する必要もない
  • 無駄が少ない
    • 必要なファイルだけ更新される
  • 削除ファイルを適切に管理できる
    • 最新モジュールを取得して上書きする運用では、いちいち削除する必要がある

といったところです。

インフラ周りの事情で別のソリューションを導入しているケースも多いでしょうけど、通常構成では svn update での運用がベストだと思いますよ。

この運用を行う場合の注意点

svn checkout した際に衝突が発生すると、元のファイルがマージされたものに置き換わってしまいます。もし衝突の可能性がある(=本番サーバ上で更新しているファイルがある)場合は、あらかじめ

svn merge --dry-run -r BASE:HEAD .

とやって、衝突が発生しないことを確認してから svn update すれば、いくらか安心です。(シビアな環境では HEAD じゃなくてリビジョン固定にしたほうがいいですが。)

より確実に更新するためには、本番リリース用のブランチを作っておいて、衝突が発生しない形にしたほうがいいかもしれません。

案2: Trac で差分モジュールを取得してアップロードする

ということで、本番サーバ上で svn を使うのがベストだとは思うんですが、これが難しい環境というのもあるでしょう。本番環境からリポジトリアクセスできなかったり、.svn ファイルがあると困る環境だったり。その場合は svn export するよりもまず、Trac 等の利用を考えたほうがいいと思います。

具体的には以下のような運用になります。

  1. Trac でリリース用のチケットを切っておく
  2. Subversion でリリース用のタグを切る
    • タグは必須ではないですが、作っておいたほうが diff する際にリビジョン指定が要らないので楽です。
    • たとえばこんな感じです。
      • 2009-09-17 リリースぶん: /tags/20090917(前回リリースしたもの)
      • 2009-09-25 リリースぶん: /tags/20090925(今回リリースしたいもの)
  3. 上記のチケットに diff のリンクを貼る
    • TracWiki 記法なら「diff:tags/20090917//tags/20090925」
    • URL でいうと「http://(Tracのパス)/changeset?new_path=tags/20090925&old_path=tags/20090917」みたいな
  4. 上記の diff ページの最下部「Zip アーカイブ」をクリック
    • この .zip には、変更されたファイルだけが含まれています
    • tags の位置を変えている場合は、trac.ini の downloadable_paths を適切に編集しておきましょう
  5. リリース
  6. チケットをクローズ

本番機へのリリースがそれほど頻繁でない環境に限られるかもしれませんが、この運用でうまくいっていたような気がします。

案1 と違って

等は必要になるのでお気をつけください。

また、この方法では「本番上で設定ファイルを書き換えておく」といった運用は行えません。

案3: svn export

全ファイルを取得する必要があるので、大規模サイトではやりたくないですが・・・全ファイルクリーンな状態で欲しい場合もあると思いますので、その場合は svn export でもいいと思います。

svn update で .svn を除外指定してアップロード、みたいなことをやってもいいと思いますけど。ケースバイケースでしょうね。

まとめ

今回の問題はあくまでも「本番に .svn が置かれる運用だったのに、.svn が除外指定されていなかったこと」なので、「svn update じゃなくて svn export しろ」という意見はちょっと乱暴すぎる気がする。セキュリティ屋さんはたまに運用効率とか無視したアドバイスとかしちゃうけど、これを元に変な運用ルールとかできちゃうと迷惑なのでやめてほしいなー。

ついでに

細かい疑問とか補足とか。

ドットファイルアクセス制限

Most web servers are configured by default to disallow access to directories that begin with a period (the traditional prefix for a hidden file or folder in UNIX)

Webサーバデフォルトの構成では、名前がドットで始まるディレクトリUNIXでは伝統的に隠れファイルや隠れディレクトリ)をアクセス不可にすることが多い。

とあるけど、XAMPP デフォルトの httpd.conf だと

<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
</FilesMatch>

となっていて、ドットファイルすべてを弾く形にはなってないんですけど。XAMPP だからですかね?

DirectoryIndex?

〔*訳注: まあ、‘ディレクトリリスティングを返さない’という構成にするのがふつうでしょう。〕

とあるけど、DirectoryIndex の指定とドットファイルを拒否する設定は別じゃないかなと。

(追記)

ma さんのコメントにあるように、DirectoryIndex じゃなくて Options -Indexes のほうですね。失礼しました。

Subversion 以外では・・・

分散リポジトリであれば本番機からリポジトリに直接アクセスできない場合も、うまく運用できたりします。mercurial での運用でよければ、以下の本に環境に応じたさまざまな使い方が載っています。

入門Mercurial Linux/Windows対応

入門Mercurial Linux/Windows対応

仕事で mercurial 使ったことがないので、本当にうまくいくのかはわからないのですが・・・とりあえずオススメです。

mama 2009/09/25 14:52 私は svn update します。
やっぱり .ht のみアクセス不可みたいですね。
ディレクトリスティングを無効にするには Options -Indexes とかじゃないですかね。 DirectoryIndex でも指定した index ファイルが存在するディレクトリでは同じ効果はあるとは思いますけど。

miaumiau 2009/09/25 15:16 すばやいツッコミありがとうございます。
ディレクトリリスティングの箇所に追記しておきました。

iwataniiwatani 2009/09/27 09:28 コメントありがとうございます。
返事が遅れて申し訳ありません。

> エクスポートするべきだ。
it is supposed to be done as an export
は、「それは(ふつう)exportとして為されることになっている」という意味です。デベロッパ用の隠れディレクトリと本番サーバの現用ディレクトリが同内容になってしまうので、前者から盗んだコード==本番アプリのコード、という問題が起こる。

...という意味ではないですか?
(私にも完全な自信はありません。subversionに関しては無知&未経験ですので。)

miaumiau 2009/09/27 12:17 わざわざありがとうございます。

もし export=「デベロッパ用の隠れディレクトリと本番サーバの現用ディレクトリが同内容になってしまう」とお考えであれば、それは違います。

ここでは「an export」と「a local working copy」の対比がされていますが、前者はリポジトリ上の最新ファイルのみを取得した状態のことで、後者はこれに .svn というメタデータのディレクトリが含まれている状態を指します。

上記はご認識済みかもしれませんが、訳を読む限りでは「しかしコードが実動サーバに乗る段階では(中略)エキスポートされた完成品だから、この問題が起こる。」というように「本番サーバにエクスポートしているのが問題だ」という意味に捉えられる文章だったので。それはちょっと違うかなと思ったのでした。

ついでに軽く補足させていただくと、問題は .svn にリポジトリ中のファイルが置かれる点だけでなく、拡張子も変わってしまっている点なんですよね。たとえば index.php というファイルがあった場合、メタデータのディレクトリには .svn\text-base\index.php.svn-base という名称でリポジトリから取得した時点での同ファイルが保持されます。これは拡張子が .php になっていないので、PHP スクリプトとして実行されずにソースが読めてしまう、という話です。

flying-foozyflying-foozy 2009/10/25 00:59 「入門Mercurial」を執筆致しました藤原です。
ご紹介頂きありがとうございます。
ご意見・ご要望等ありましたなら、
下記エントリへのコメントで結構ですので
お知らせ頂ければ幸いです。

http://d.hatena.ne.jp/flying-foozy/20140125/1233753098

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証