Vagrant best practice

Vagrant best practice. 小規模WEB開発におけるVagrantのBest practiceを見つけました。 vagrant-berkshelf pluginconfig.vm.provision :shellを併用して構築すると、VagrantfileとBerksfileの2ファイルだけの管理で済み、融通もつけやすい状態にすることが出来ました。


ちょっとした一例ですが、Nginx+PHP+PhalconなCentOS環境を構築する例です。

Berksfile

site :opscode

cookbook "nginx"
cookbook "php"
cookbook "php-phalcon", git: "https://github.com/k-kinzal/chef-php-phalcon.git"
cookbook "iptables"

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "Berkshelf-CentOS-6.3-x86_64-minimal"
  config.vm.box_url = "https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box"

  config.vm.network :public_network

  config.vm.synced_folder "./", "/opt/my-service"

  config.berkshelf.enabled = true
  config.vm.provision :chef_solo do |chef|
    chef.json = {
      :nginx => {
        :default_site_enabled => false
      },
      :php => {
        :conf_dir => "/etc",
        :ext_conf_dir => "/etc/php.d",
        :fpm_user => "nobody",
        :fpm_group => "nobody",
        :package => ["php", "php-devel", "php-common", "php-mbstring", "php-fpm"]
      }
    }

    chef.run_list = [
        "recipe[nginx]",
        "recipe[php]",
        "recipe[php-phalcon]",
        "recipe[iptables::disabled]"
    ]
  end

  config.vm.provision :shell, :inline => <<-EOS
    echo '
      server {
          listen 80;
          server_name localhost;

          root /opt/my-service/public;
          index index.html index.htm index.php;

          location / {
            if (!-e $request_filename) {
              rewrite ^/(.*)$ /index.php?_url=/$1 last;
            }
          }

          location ~ ^(.+\.php)(/.*)?$ {
            fastcgi_split_path_info ^(.+\.php)(/.*)?$;

            set $script_filename $document_root$fastcgi_script_name;

            if (!-e $script_filename) {
              return 404;
            }

            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;

            fastcgi_param   APPLICATION_ENV development;
            fastcgi_param   SCRIPT_FILENAME $script_filename;
            fastcgi_param   SCRIPT_NAME $fastcgi_script_name;
            fastcgi_param   PATH_INFO $fastcgi_path_info;
          }

          location ~ /\.ht {
            deny  all;
          }
      }
    ' | sudo tee /etc/nginx/sites-enabled/my-service.conf
    sudo service nginx restart
    sudo service php-fpm restart
    sudo chkconfig php-fpm on
  EOS
end

ここで重要になるのが、汎用的に扱えそうなものはレシピ化して管理すること、アプリケーションの設定など依存性の高いものはshellで直接書いてしまうという2点になります。 開発環境のVagrantと本番環境で同一のchefで管理をする場合はshellで書くというのは良くありませんが、開発用と割り切るのなら融通を効かせやすいという点で良いです。


あとはchefでバージョンの固定化をどうするかが課題ですね。 受託開発などで第1フェーズの開発と第2フェーズの開発で間が開いた際に、パッケージのバージョンが変わったり、レシピが消えるという問題にどう対応するかは考え中です。

  1. パッケージはRPMをS3に保持して、そこからインストール
  2. レシピはgitのremoteの接続先を変更して別リポジトリにフォーク

なんてことを妄想していますが、管理する手間が大きそうです。 このあたり、ベストといえなくてもベターといえる手法を知りたいですね。