社内の開発環境とローカルの開発環境の連携方法

どんな時に便利か?

全てのサービスをローカル環境として構築できれば良いのですが
それがあまり現実的ではなく、基本は外部のアプリを利用して
一部アプリだけローカルのアプリを利用したいとい時に便利です。

ローカル環境構成図

PAC(Proxy Access-Control)ファイルを利用して
まずは、ローカルとそれ以外へのアクセスを振り分けています。


ローカルでは、nginxがアクセスを集約しています。
これは、80番や443番ポートを複数のアプリで利用するためで
ホスト名によって各アプリへリクエストの振り分けをしています。


PACファイル

開発環境用に社内プロキシが無い場合は、設定不要です。
JavaScriptの文法で、proxyの設定が書けるファイルです。


Firefoxだと、下記の場所からから設定できます。
オプション > ネットワーク > 接続設定 > 自動プロキシ設定スクリプト URL


proxyを通さない場合(今回はローカル環境)は、"DIRECT"という文字列を返しておきます。
ドメイン名に"hatena.ne.jp"が入る場合は、開発環境用のproxyを通したい。という場合は、
組み込みのshExpMatch関数を使い、host名とマッチングをかけ、PROXYのIPとポートを返します。
セミコロンでproxyもしくは、"DIRECT"をつなげると、順番に接続を試みてくれます。

function FindProxyForURL(url, host) {
  if (isInNet(host, "127.0.0.1", "255.255.255.255")) {
    return "DIRECT";
  } else if (isDevHost(host)) {
    // dev.proxy:9999
    return "PROXY 172.16.0.2:9999";
  }

  // default.proxy:9999
  return "PROXY 172.16.0.3:9999; DIRECT";
}

function isDevHost(host) {
  return shExpMatch(host, "*.hatena.ne.jp");
}

hostsの設定

isInNet(host, "127.0.0.1", "255.255.255.255")でローカル環境として判定をさせるために
/etc/hosts で、ローカルアプリのドメインのIPを、127.0.0.1として登録しておきます。

# local env
127.0.0.1          d.hatena.ne.jp


これで、http://d.hatena.ne.jp/とアクセスした場合は、127.0.0.1:80へのアクセスに
それ以外のはてなドメインは、172.16.0.2:9999のproxy経由でのアクセスが可能になりました。

nginxの設定

ほぼ、デフォルトの設定のままですが、肝はinclude文です。
これで、各アプリに振り分けるようの設定を読み込んでいます。

error_log  /usr/local/var/logs/nginx/error.log;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       params/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /usr/local/var/logs/nginx/access.log  main;

    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;

    keepalive_timeout  65;
    sendfile on;
    gzip on;

    include    /usr/local/var/nginx/conf/extra/backends/*.conf;
}
/usr/local/var/nginx/conf/extra/backends/d-hatena-ne-jp.confの場合

d.hatena.ne.jp用のtomcatアプリが、8080ポートで動いている場合は
以下のような設定になります。

server {
    listen      80;
    server_name d.hatena.ne.jp;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}


アプリを増やしたい場合は、hostsファイルへの追記とconfファイルの新規作成で簡単に行えます。

1文字シリーズ

毎日、毎日タイプするコマンドならば、タイプ数を減らすに限るよね。
抜けてるところには、何を入れよう?

1文字alias

alias a="sudo aptitude"
alias b=""
alias c="cat"
alias d="diff"
alias e="echo"
alias f="find . -type f -name"
alias g="grep"
alias h="head"
alias i="/sbin/ifconfig"
alias j=""
alias k=""
alias l="ls -ltrah"
alias m=""
alias n="node -e"
alias o=""
alias p="perl -wnl -e"
alias q=""
alias r="reset"
alias s="sqlplus user_name/password@host[:port][/service_name]"
alias t="tail -f"
alias u=""
alias v="view"
alias x="xargs"
alias y=""
alias z=""

1文字変数

aliasよりさらにネタが無いな

export a="access_`date +%Y%m%d`.log"
export b=""
export c=""
export d="`date +%d`"
export e="error_`date +%Y%m%d`.log"
export f=""
export g=""
export h=""
export i=""
export j=""
export k=""
export l=""
export m="`date +%m`"
export n=""
export o=""
export p=""
export q=""
export r=""
export s=""
export t=""
export u=""
export v=""
export w=""
export x=""
export y="`date +%Y`"
export z=""

Vimana使ってみた、、い

vim

Vim script manager「Vimana」が便利すぎる。
を見てインストールしてみました。

# git clone git://github.com/c9s/Vimana
# cd Vimana
# perl Makefile.PL
# make

で、makeファイルねーよと言われてしまった。
id:mattn さんからのアドバイスで、incディレクトリを消したら、Module::AutoInstallが無いと怒られてしまった。

id:TakiTake incディレクトリを消してperl Makefile.PLすると行けたりもします。

git cloneからやり直そうとしたら、現在(2010/02/04 12:10) github落ちてるみたい。


CPANからのインストールを試みるも失敗。
こっちも、makeファイル無いってエラーなのか?

# cpan Vimana
CPAN: Storable loaded ok (v2.21)
Going to read '/root/.cpan/Metadata'
  Database was generated on Wed, 03 Feb 2010 22:45:58 GMT
CPAN: YAML loaded ok (v0.71)
Going to read 120 yaml files from /root/.cpan/build/
CPAN: Time::HiRes loaded ok (v1.9719)
......DONE
Restored the state of 1 (in 5.8001 secs)
Running install for module 'Vimana'
Running make for C/CO/CORNELIUS/Vimana-2010.03419.tar.gz
Prepending /root/.cpan/build/App-Context-0.967-85imJq/blib/arch /root/.cpan/build/App-Context-0.967-85imJq/blib/lib to PERL5LIB for 'get'
  Has already been unwrapped into directory /root/.cpan/build/Vimana-2010.03419-cfAjBm
Prepending /root/.cpan/build/App-Context-0.967-85imJq/blib/arch /root/.cpan/build/App-Context-0.967-85imJq/blib/lib to PERL5LIB for 'make'
  Has already been made
Prepending /root/.cpan/build/App-Context-0.967-85imJq/blib/arch /root/.cpan/build/App-Context-0.967-85imJq/blib/lib to PERL5LIB for 'test'
Running make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'blib/lib', 'blib/arch')" t/00-commands.t t/00-install.t t/00-load.t t/00-path.t t/00-update.t t/01-package.t t/01-record.t t/accessor.t t/installer-makefile-2.t t/installer-makefile-3.t t/installer-makefile.t
t/00-commands.t ........... ok
t/00-install.t ............ ok
t/00-load.t ............... 1/6 # Testing Vimana 2010.03419, Perl 5.010000, /usr/bin/perl
t/00-load.t ............... ok
t/00-path.t ............... ok
t/00-update.t ............. ok
t/01-package.t ............ 1/9 # basic
# directory detection
t/01-package.t ............ 6/9 # makefile
# metafile
t/01-package.t ............ ok
t/01-record.t ............. ok
t/accessor.t .............. ok
t/installer-makefile-2.t .. 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.

#   Failed test at t/installer-makefile-2.t line 22.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile-2.t line 24
# Looks like you failed 1 test of 2.
t/installer-makefile-2.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests
t/installer-makefile-3.t .. 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile-3.t line 24
t/installer-makefile-3.t .. ok
t/installer-makefile.t .... 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.

#   Failed test at t/installer-makefile.t line 20.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile.t line 22
# Looks like you failed 1 test of 2.
t/installer-makefile.t .... Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests

Test Summary Report
-------------------
t/installer-makefile-2.t (Wstat: 256 Tests: 2 Failed: 1)
  Failed test:  2
  Non-zero exit status: 1
t/installer-makefile.t  (Wstat: 256 Tests: 2 Failed: 1)
  Failed test:  2
  Non-zero exit status: 1
Files=11, Tests=70,  7 wallclock secs ( 0.23 usr  0.08 sys +  3.12 cusr  1.27 csys =  4.70 CPU)
Result: FAIL
Failed 2/11 test programs. 2/70 subtests failed.
make: *** [test_dynamic] エラー 1
  CORNELIUS/Vimana-2010.03419.tar.gz
  /usr/bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
  reports CORNELIUS/Vimana-2010.03419.tar.gz
Running make install
  make test had returned bad status, won't install without force


インストール手前で停滞中です。
誰か原因分かりますか?

追記

足りないモジュールをインストールして、incディレクトリを削除したら

# perl Makefile.PL
include /root/repos/Vimana/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Scripts.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/Include.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/AutoInstall.pm
*** Module::AutoInstall version 1.03
*** Checking for Perl dependencies...
[Core Features]
- App::CLI       ...loaded. (0.08 >= 0.08)
- Archive::Any   ...loaded. (0.0932)
- DateTime       ...loaded. (0.53)
- Exporter::Lite ...loaded. (0.02)
- File::Path     ...loaded. (2.08 >= 2.07)
- File::Spec     ...loaded. (3.31)
- File::Type     ...loaded. (0.22)
- Getopt::Long   ...loaded. (2.38)
- LWP::Simple    ...loaded. (5.827)
- LWP::UserAgent ...loaded. (5.834)
- Test::More     ...loaded. (0.94)
- URI            ...loaded. (1.52 >= 1.37)
- YAML           ...loaded. (0.71)
- Digest::MD5    ...loaded. (2.39)
- JSON           ...loaded. (2.17)
*** Module::AutoInstall configuration finished.
Vim found:
----------
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Mar 27 2009 08:42:32)
適用済パッチ: 1-148
Modified by <bugzilla@redhat.com>
----------
include inc/Module/Install/WriteAll.pm
include inc/Module/Install/Win32.pm
include inc/Module/Install/Can.pm
include inc/Module/Install/Fetch.pm
Checking if your kit is complete...
Warning: the following files are missing in your kit:
        META.yml
Please inform the author.
Writing Makefile for Vimana
Writing META.yml

無事Makefileが作成されました。


makeも成功して、意気揚々とmake testしたら、

PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'blib/lib', 'blib/arch')" t/00-commands.t t/00-install.t t/00-load.t t/00-path.t t/00-update.t t/01-package.t t/01-record.t t/accessor.t t/installer-makefile-2.t t/installer-makefile-3.t t/installer-makefile.t t/text.t
t/00-commands.t ........... ok
t/00-install.t ............ ok
t/00-load.t ............... 3/6 # Testing Vimana 2010.03419, Perl 5.010000, /usr/bin/perl
t/00-load.t ............... ok
t/00-path.t ............... ok
t/00-update.t ............. ok
t/01-package.t ............ 1/9 # basic
# directory detection
t/01-package.t ............ 6/9 # makefile
# metafile
t/01-package.t ............ ok
t/01-record.t ............. ok
t/accessor.t .............. ok
t/installer-makefile-2.t .. 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.

#   Failed test at t/installer-makefile-2.t line 22.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile-2.t line 24
# Looks like you failed 1 test of 2.
t/installer-makefile-2.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests
t/installer-makefile-3.t .. 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile-3.t line 24
t/installer-makefile-3.t .. ok
t/installer-makefile.t .... 1/2 make[1]: *** ターゲット `install' を make するルールがありません.  中止.

#   Failed test at t/installer-makefile.t line 20.
cannot remove path when cwd is /tmp/test for /tmp/test:  at t/installer-makefile.t line 22
# Looks like you failed 1 test of 2.
t/installer-makefile.t .... Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests
t/text.t .................. ok

Test Summary Report
-------------------
t/installer-makefile-2.t (Wstat: 256 Tests: 2 Failed: 1)
  Failed test:  2
  Non-zero exit status: 1
t/installer-makefile.t  (Wstat: 256 Tests: 2 Failed: 1)
  Failed test:  2
  Non-zero exit status: 1
Files=12, Tests=72,  9 wallclock secs ( 0.49 usr  0.00 sys +  4.49 cusr  1.28 csys =  6.26 CPU)
Result: FAIL
Failed 2/12 test programs. 2/72 subtests failed.
make: *** [test_dynamic] エラー 255

OTL

さらに追記

id:mattn さん製のブランチのソースコードをコンパイルすることで、無事Vimanaを利用できる所まで漕ぎ着けました。
mattn++

Symfonyで環境の違いを考慮した設定方法

symfonyのインストールディレクトリが違う

三項演算子なりswich文なりで、パスを動的に書き換える。
ヒットする可能性が高い順に調べることで、比較回数を減らすよう考慮すべし。

web/index.php
<?php
$path = is_file('/usr/local/share/pear/symfony/autoload/sfCoreAutoload.class.php')
  ? '/usr/local/share/pear/symfony/autoload/sfCoreAutoload.class.php'
  : '/usr/share/pear/symfony/autoload/sfCoreAutoload.class.php';

require_once $path;

sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // for compatibility / remove and enable only the plugins you want
    $this->enableAllPluginsExcept(array('sfPropelPlugin', 'sfCompat10Plugin'));
  }
}

cookieのパス

factories.ymlで設定可能ですが、factries.yml読み込み時にはRequestオブジェクトがまだ作成されていないので正規表現で動的に作成しました。正規表現は sfWebRequest.class.php の getRelativeUrlRoot メソッドから拝借。

apps/frontend/config/factories.yml
all:
  storage:
    class: sfSessionStorage
    param:
      session_name: symfony
      session_cookie_path: <?php echo preg_replace('#/[^/]+\.php5?$#', '', $_SERVER['SCRIPT_NAME']).'/' ?>

その他

databases.yml や .htaccess は変更なしで使えるようテスト環境、本番環境で揃えた方が楽。無理な場合は、バージョン管理やrsync対象から外す。その代わり、databases.yml.sample .htaccess.sample というファイルを用意しておき、リネーム(.sample削る)して環境に応じて編集するようにすれば1から記述する手間が多少減る。

.gitignore

Git用にこんな設定にしてます。

*.swp
cache/
data/
log/
config/databases.yml
web/.htaccess

init.sh

.gitignoreの対になるシェルスクリプトとしてこんなの作りました。

#!/bin/sh
mkdir -p cache data/fixtures data/sql log
chmod 777 cache log
cp config/databases.yml.sample config/databases.yml
cp web/.htaccess.sample web/.htaccess

git clone してきた後に

$ ./init.sh

することで、必要なディレクトリを生成します。