vagrant で CentOS7.1 + php7 + mariadb10 の開発環境を作る


php7(と、symfony) + mariadb10 を使うアプリケーション開発のための環境をvagrantで作る方法。

CentOS7.1のデフォルトyumリポジトリだとphp5.4がインストールされるし、remiリポジトリを追加して云々といろいろ面倒なのでchefにインストールさせるようにする。

また、開発時にはapacheとかnginxを使わずphpのビルトインサーバーで良いので、ブラウザ確認用のポート(8000)を開けておくのと、symfonyコマンド、composerコマンドをいちいちロードしたくないのであらかじめインストールしておく。

環境等

  • ここではWindows10 + ChefDK + Vagrant + VirtualBoxを使用している。
  • Vagrantファイルの置き場所は c:/vagrant/sample を想定している

基本的な流れ

  • Vagrantfileを準備する
  • chef cookbook repository 準備
  • berkshelf でコミュニティレシピを取り込む
  • php7 をインストールするレシピを作成する
  • firewalldを設定するレシピを作成する
  • vagrant VMに対するjsonファイルを作成する
  • VM起動
  • 動作確認

Vagrantfileを準備する

vagrant init コマンドを実行して初期Vagrantfileを作成する。

PS > cd c:\vagrant\sample
PS > vagrant init

c:/vagrant/sample/Vagrantfile を以下のように編集する

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.1"
  config.vm.network "private_network", ip: "192.168.33.101"
  config.omnibus.chef_version = :latest

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "1024"
  end

  config.vm.provision "chef_zero" do |chef|
    chef.cookbooks_path = ["chef-repo/cookbooks", "chef-repo/site-cookbooks"]
    chef.nodes_path = ["chef-repo/nodes"]
    chef.node_name = "sample"
  end
end

chef cookbook repository 準備

chef generate コマンドでcookbook リポジトリを作成する

PS > cd c:\vagrant\sample
PS > chef generate repo chef-repo

berkshelf でコミュニティレシピを取り込む

chef-repo/BerksFileを以下の内容で作成する

source "https://supermarket.chef.io"

cookbook 'yum'
cookbook 'yum-remi'
cookbook 'yum-epel'
cookbook 'mariadb'

コミュニティレシピをダウンロードする。

PS > cd chef-repo
PS > berks vendor cookbooks

php7 をインストールするレシピを作成する

knife cookbook コマンドでphpをインストールするレシピを作成する

PS >  knife cookbook create php -o site-cookbooks

chef-repo/site-cookbooks/php/recipe/default.rbを以下のように編集する

include_recipe 'yum::default'
include_recipe 'yum-remi::default'

%w[
  gd-last
  t1lib
].each do |pkg|
    package "#{pkg}" do
        action [ :install ]
        options "--enablerepo=remi"
    end
end

%w[
  php
  php-cli
  php-common
  php-gd
  php-xml
  php-pdo
  php-mbstring
  php-mysqlnd
  php-opcache
].each do |pkg|
  package "#{pkg}" do
    action :install
    options '--enablerepo=remi-php70'
  end
end

execute "composer-install" do
  command "curl -sS https://getcomposer.org/installer | php ;mv composer.phar /usr/local/bin/composer"
  not_if { ::File.exists?("/usr/local/bin/composer")}
end

execute "symfony-install" do
  command "curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony;chmod a+x /usr/local/bin/symfony"
  not_if { ::File.exists?("/usr/local/bin/symfony")}
end

php-gd を使うのに gd-last, t1libが必要なのであらかじめ remiリポジトリからインストールするようにしてある。

インストールする拡張モジュールは適宜調整。

また、symfonyコマンドとcomposerコマンドはあとからコマンドラインをたたいてインストールするのではなく、この時点でインストールするようにする。

コミュニティレシピのyum,yum-remiを使うので chef-repo/site-cookbooks/php/metadata.rb に依存レシピを記述する。

depends 'yum'
depends 'yum-remi'

firewalldを設定するレシピを作成する

apacheのエイリアス設定とかディレクトリ設定とかやらなくていいのでphpビルトインサーバーを使う。このためにビルトインサーバーが使うポートを開けるようにする。

knife cookbook コマンドでfirewalldを設定するレシピを作成する

PS >  knife cookbook create init -o site-cookbooks

chef-repo/site-cookbooks/init/recipe/default.rbを以下のように編集する

service "firewalld" do
    supports [ :restart, :reload ]
    action [ :enable, :start ]
end

execute "allow port 8000" do
    command "firewall-cmd --add-port=8000/tcp --zone=public --permanent"
    notifies :restart, "service[firewalld]"
end

firewall-cmd を使って ポート8000 を開けるようにする。

レシピの名前が "firewalld" でなく "init" なのはロケールとかタイムゾーンとかの初期設定も含めるようにするためでたいして意味はないけど、その辺はレシピ作成ポリシー次第。

vagrant VMに対するjsonファイルを作成する

以下の内容で chef-repo/nodes/sample.jsonファイルを作成する。

{
  "name": "sample",
  "chef_type": "node",
  "json_class": "Chef::Node",
  "normal":{
    "mariadb": {
      "use_default_repository": true,
      "allow_root_pass_change": true,
      "server_root_password": "test",
      "install": {
        "type": "package",
        "version": "10.1.13",
        "prefer_os_package": false
      },
      "mysqld": {
        "options":{
          "collation-server" : "utf8_unicode_ci",
          "init-connect" : "'SET NAMES utf8'",
          "character-set-server" : "utf8"
        }
      },
      "innodb": {
          "log_file_size": "",
          "bps_percentage_memory": false,
          "buffer_pool_size": "256M",
          "log_buffer_size": "8M",
          "file_per_table": "1",
          "open_files": "400",
          "io_capacity": "400",
          "flush_method": "O_DIRECT",
          "options": {

          }
      }     
    },
    "yum": {
      "remi-php70": {
        "repositoryid": "remi-php70",
        "baseurl": "http://rpms.famillecollet.com/enterprise/7/php70/x86_64/",
        "description": "Les RPM de remi de PHP 7 pour Enterprise Linux 7 - $basearch",
        "mirrorlist": "http://rpms.famillecollet.com/enterprise/7/php70/mirror"
      }
    },
    "yum-remi": {
      "repositories": [
        "remi",
        "remi-php70"
      ]
    }
  },  
  "run_list": [
    "recipe[yum]",
    "recipe[yum-epel]",
    "recipe[mariadb::server]",
    "recipe[mariadb::client]",
    "recipe[php]",
    "recipe[init]"

  ]
}

mariadbのattributesはここで指定する。rootパスワードはdatabag等で書くべきかもしれない。

よくあるvagrantの解説では Vagrantfileに属性とか実行レシピとかを chef.runlist =[] とか chef.json={}とか記述しているけれども最終的には記述したレシピと設定をvagrantではなく実環境に適用したくなるのでnodes/jsonに記述するようにする。

VM起動

準備ができたらVMを起動する。

PS > cd c:\vagrant\sample
PS > vagrant up

動作確認

適当なディレクトリにphpファイルを作って php ビルトインサーバーを起動し、ホストからアクセスする。

/vagrant/check/info.php

<?php
phpinfo();

ビルトインサーバー起動

$> php -S 0.0.0.0:8000

ホストから http://192.168.33.101/info.php に アクセス

その他

  • "レシピは上から順に実行されない"という話なので、php-gdのインストールとかがうまくいかないかもしれない。
  • nodes|environments|data_bagsの使い分け、優先順位が今一わからない。
  • ちょっと古い解説だと boxファイルを http://www.vagrantbox.es/ から入手するように書いてあるが、現在(バージョン1.8.1)ではhttps://atlas.hashicorp.com/boxes/search から探したほうが良い。
  • もしかしたら CentOS 7 にPHP7をインストールするコミュニティレシピがあるのかも。
  • vagrant up 後に chef-repo/nodes/sample.json が書き換えられてしまう。何故だかわからないので情報募集。
  • 上で作ったVagrantfileとレシピ等は https://github.com/okadabasso/vagrant-centos-php7 にあります。