Vagrant上のCentOS7にSymfony2.7をインストールし，ついでにアプリをデプロイする


業務でSymfony2.7での開発を行う機会があったので，作業ログを残しておきます．

# やりたいこと
Mac上からVagrantを用いてCentOSの仮想環境を立ち上げ，ゲストOSにSymfony2のサンプルアプリケーションをインストールして，アプリが起動できるようにする．
ついでにApache上にデプロイする．
PHPを扱うのは初めてで，知らないことが多いため，できるだけ簡単な方法を使いたい．

# 作業環境
ホストOS: Mac OS X 10.9
ゲストOS: CentOS 7.1.1503
PHP 5.6.9
Symfony 2.7.0
MySQL 5.6.19

# Symfony2.7を動かす

## Vagrantの導入

### Vagrantのインストール
[Vagrant セットアップ (Mac)](http://qiita.com/inouet/items/b36638adc2b5772db457)
こちらの記事に従う．

[Vagrant](http://www.vagrantup.com/)，[Virtual Box](https://www.virtualbox.org/)をインストールした上で，

Vagrant Boxes
http://www.vagrantbox.es/

から，

![スクリーンショット 2015-06-06 13.52.07.png](https://qiita-image-store.s3.amazonaws.com/0/46811/5a24668b-82f4-dc8d-ef1d-9aa1f31ead73.png "スクリーンショット 2015-06-06 13.52.07.png")

赤枠で示したボタンをクリックし，"CentOS 7 x64 (Minimal, Shrinked, Guest Additions 4.3.26) (Monthly updates)"のURLをコピー．

```bash:Host
$ vagrant box add centos7 https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box # さっきコピーしたURL
$ mkdir -p Vagrant/centos7
$ cd Vagrant/centos7
$ vagrant init centos7
```

### Vagrantの設定
```bash:Host
$ cd ~/Vagrant/centos7
$ emacs Vagrantfile
```

このファイルに，

```ruby:Vagrantfile
Vagrant.configure(2) do |config|

  # ...

  # 下記の行を追記
  config.vm.network "forwarded_port", guest: 8000, host: 8000
end
```

のように追記．
これにより，ホストOSの8000番ポートへのアクセスが，ゲストOSの8000番ポートへのアクセスに転送される．

### ゲストOSへのログイン

```bash:Host
$ vagrant up
$ vagrant ssh
```

## PHPのインストール

### PHP5.6のインストール

もちろん，普通に`yum install php`としてPHPをインストールすることは可能だが，そのままだと，古いバージョンのPHPがインストールされる．
今回，業務上の要請として，PHPのバージョンを5.6に指定されたので，それに従うこととする．

[CentOS7にPHP5.6をインストールする。](http://qiita.com/koichi_amami/items/e97bc70e82e95ab99f55)
こちらに従う．

```bash:Guest
$ sudo rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
$ sudo yum install --enablerepo=remi --enablerepo=remi-php56 php php-opcache php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof
```

```bash:Guest
$ php --version
PHP 5.6.9 (cli) (built: May 15 2015 09:31:38)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.3.2, Copyright (c) 2002-2015, by Derick Rethans
```
こうなってればたぶん問題ない．

### php-intlのインストール
Symfonyを動かすのに必要らしい（正直よくわかっていない）．

[CentOSでSymfony2をインストールする際、ICUライブラリのバージョンでつまづく](http://qiita.com/emegane/items/f8f66eeb6dbac95c662d)
こちらに従う．

```bash:Guest
$ wget http://download.icu-project.org/files/icu4c/51.2/icu4c-51_2-src.tgz
$ tar zxf icu4c-51_2-src.tgz 
$ cd icu/source/
$ ./configure
$ make
$ sudo make install
$ sudo pear install pecl/intl
$ echo "extension=intl.so" > /etc/php.d/intl.ini
```

### PHPのTimezone設定
これもSymfonyを動かすために必要．

```bash:Guest
$ sudo vi /etc/php.ini
```

ファイルの末尾に

```
[Date]
date.timezone = 'UTC'
```

を追記．


## Composerのインストール
Composerは，PHPのパッケージ管理ツール（PythonにおけるPIPのようなものだろうか）．
必須ではないが，ライブラリのアップデートなどに使うらしい．

[Installing Composer (The Symfony CookBook)](http://symfony.com/doc/current/cookbook/composer.html)

```bash:Guest
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
```

## Symfonyの導入

### Symfony2.7のインストール
[Installing and Configuring Symfony (The Symfony Book)](http://symfony.com/doc/current/book/installation.html)
こちらに従う．
[日本語版](http://docs.symfony.gr.jp/symfony2/book/installation.html)もあるが，少し内容が古い（基本的にSymfony2.3向けの説明である，Symfony Installerについての記述がないなど）ため，無理してでも英語版公式を読んだ方が良いと思う．

```bash:Guest
$ cd
$ sudo curl -LsS http://symfony.com/installer -o /usr/local/bin/symfony
$ sudo chmod a+x /usr/local/bin/symfony
$ symfony new sample
```

### 開発用コンソールを閲覧できるようにする
Symfonyには開発用コンソールがあり，インストールの要件などを確かめたり，サーバの設定ができたりする．

config.phpは，Symfonyが動作する状況かどうかを判断してくれるツール．
[http://localhost:8000/config.php](http://localhost:8000/config.php)にアクセスすることで診断してくれる．

実環境からのアクセスなら問題ないが，仮想環境上においたアプリへのアクセスの場合，"This script is only accessible from localhost."のようなエラーメッセージが出て閲覧できないことがある．

これをゲストOSから閲覧できるようにする

```bash:Guest
$ sudo vi ~/sample/web/config.php
```

```php:config.php
# ...
# ここから
if (!in=array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('This script is only accessible from localhost.');
}
# ここまでコメントアウト
# ...
```

上記の部分をコメントアウト/削除するとよい．

app_dev.phpは，Symfonyのdevelopment環境において，データベースなどの設定を自動的に行なってくれる（らしい）ツール．
これについても同様にする．

```bash:Guest
$ sudo vi ~/sample/web/app_dev.php
```

```php:app_dev.php
# ...
# ここから
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
# ここまでコメントアウト
# ...
```

上記の部分をコメントアウト/削除．


## アプリを試す
ビルトインのWebサーバを使ってアプリを試すことができる（RailsのWEBrickのようなもの？）．

[How to Use PHP's built-in Web Server (The Symfony CookBook)](http://symfony.com/doc/current/cookbook/web_server/built_in.html)

今回は，仮想環境上でサーバを動かしているため，ゲストOSにはGUIで動くブラウザがない．
そこで，一度ゲストOS上でcurlコマンドを使ってサーバが起動していそうかを試し，その上でホストOSから接続できるようにした．

```bash:Guest
$ cd ~/sample
$ php app/console server:start
$ curl http://localhost:8000/config.php
# HTMLが出力される
```

出力されるHTMLの中に，

```bash:Guest
Your configuration looks good to run Symfony.
```

のような記述があれば問題ない．

余談だが，

```bash:Guest
$ php app/check.php
```

とすることで，コマンドライン上からでも設定がきちんと出来ているか確かめることができる．

ここからが，ホストOSのブラウザ上でアプリを動かすための設定．
上記の記事の"Using the built-in Web Server from inside a Virtual Machine"の項にも書かれているように，サーバ起動コマンドの引数に"0.0.0.0:8000"を設定して，8000番ポートから来るHTTP接続をすべて受け付けるようにしている．
これにより，ホストOSのブラウザからの入力を受け付けるようにしている．
もちろん，本番サーバでこんなことをしてはいけない．

```bash:Guest
$ php app/console server:stop
$ php app/console server:start 0.0.0.0:8000
```

サーバを起動した後，ホストOSのブラウザから[http://localhost:8000/app/example](http://localhost:8000/app/example)にアクセスし，ブラウザ上に"Homepage."が出力されればOK．

## データベースへの接続

### MySQLのインストール

[CentOS7にMySQLをインストール](http://sawara.me/mysql/2094/)

RPMを使う方法を試したが，よく考えたらyumでやった方が簡単だしアップデートもしやすそうだった．

```bash:Guest
$ wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-5.6.19-1.linux_glibc2.5.x86_64.rpm-bundle.tar
$ tar xvf MySQL-5.6.19-1.linux_glibc2.5.x86_64.rpm-bundle.tar
$ sudo rpm -ivh MySQL-shared-compat-5.6.19-1.linux_glibc2.5.x86_64.rpm
$ sudo rpm -ivh MySQL-shared-5.6.19-1.linux_glibc2.5.x86_64.rpm
$ sudo rpm -ivh MySQL-devel-5.6.19-1.linux_glibc2.5.x86_64.rpm
$ sudo rpm -ivh MySQL-client-5.6.19-1.linux_glibc2.5.x86_64.rpm
$ sudo rpm -ivh MySQL-server-5.6.19-1.linux_glibc2.5.x86_64.rpm
$ sudo rpm -ivh MySQL-embedded-5.6.19-1.linux_glibc2.5.x86_64.rpm 
$ sudo cat /root/.mysql_secret
# The random password set for the root user at Sat Jun  6 06:22:43 2015 (local time): xxxxxxxxxx
# 初期パスワードが与えられる
$ sudo systemctl start mysql
$ mysql -r root -p
# パスワード: xxxxxxxxxxを入力
mysql> SET PASSWORD FOR root@localhost=PASSWORD('');
Query OK, 0 rows affected (0.02 sec)
$ /usr/bin/mysql_secure_installation
```

インストールできたので，ついでに文字コードをUTF-8に設定．

```bash:Guest
$ sudo vi /usr/my.cnf
```

```
[mysqld]

# ここから下を追加
collation-server     = utf8mb4_general_ci
character-set-server = utf8mb4
```

my.cnfの場所は環境によって違うかも．

```bash:Guest
$ sudo systemctl restart mysql
```

### データベースの作成

```bash:Guest
$ cd ~/sample
$ php app/console doctrine:database:create
```

これで，MySQL上に"symfony"という名前のデータベースができるはず．

ここまでできれば，development環境での開発としては十分できる．
以降の部分は，個人的に気になったのでやったおまけ．

# Apache上にアプリをデプロイする

## Vagrantfileの再設定
一度ホストOSに戻り，ホストOSからゲストOSの80番ポートにアクセスできるように，Vagrantfileのフォワーディング設定を変更する．

```bash:Host
$ emacs ~/Vagrant/centos7/Vagrantfile
```

```ruby
config.vm.network "forwarded_port", guest: 8000, host: 8000
```

の所を，

```ruby
config.vm.network "forwarded_port", guest: 80, host: 8000
```

のように変更．

その後，仮想マシンを再起動し，再度ログイン．

```bash:Host
$ vagrant reload
$ vagrant ssh
```

## Apache2のインストール
[CentOS7最小インストールからHTTP接続が接続できるまで](http://qiita.com/tamamius/items/448c350ca34e4db9f6f5)

CentOSが7にバージョンアップされた際に，管理系のコマンドが大きく変わったらしい．
結構混乱した．

[CentOS7でサービスの管理方法が変わった！](http://qiita.com/haisaihiroki/items/c38cb3c0a331db9b6f69)

```bash:Guest
$ sudo yum -y install httpd
$ sudo systemctl start httpd.service
$ sudo systemctl status httpd.service
```

`systemctl status httpd.service`で，httpd.serviceがactiveになっているか確認する．
/var/www/html/index.htmlがcurlなどで見られるか確認

## ファイアウォールを無効にする
ファイアウォールについても，以前のiptablesはあまり使わない方がよく，代わりに，firewalldと呼ばれる新たなフロントエンドを用いるとよいらしい．
今回は仮想環境上でのデプロイのため，とりあえず無効にしておく．
もちろん，本番サーバでこんなこt(ry

```bash:Guest
$ sudo systemctl stop firewalld
$ systemctl status firewalld

# サーバ起動と同時にapacheを起動するようにする
$ sudo systemctl enable httpd.service
$ sudo systemctl list-unit-files | grep httpd

# サーバ起動と同時にfirewalldを無効にするようにする
$ sudo systemctl disable firewalld.service
$ sudo systemctl list-unit-files | grep firewall
```

## Apacheの設定
[Configuring a Web Server (The Symfony CookBook) ](http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html)
ご丁寧にApache（とNginx）でのデプロイの仕方まで書いてある．
今回はとにかく動かすことを目標に，デフォルトの設定を流用する．

```bash:Guest
$ sudo vi /etc/httpd/conf/httpd.conf
```

```
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

    DocumentRoot /var/www/project/web
    <Directory /var/www/project/web>
        AllowOverride All
        Order Allow,Deny
        Allow from All
    </Directory>

    # uncomment the following lines if you install assets as symlinks
    # or run into problems when compiling LESS/Sass/CoffeScript assets
    # <Directory /var/www/project>
    #     Options FollowSymlinks
    # </Directory>
    
    # ErrorLog /var/log/apache2/project_error.log
    # CustomLog /var/log/apache2/project_access.log
combined
</VirtualHost>
```

Log出力用のディレクトリは環境に合わせたものを設定するべきなのでコメントアウトしておく．

## リリース用のアプリのアジャストメント

これもよくわからないのだが，Apache上にデプロイする際には，app/cacheとapp/logsという2つのディレクトリに対して書き込み権限が必要らしい．

[Installing and Configuring Symfony (The Symfony Book)](http://symfony.com/doc/current/book/installation.html)
の，"Setting up Permissions"の項の"3"を参照．
これにより，Apacheのユーザと開発者のユーザの両方に書き込み権限を付与することができるらしい．

```bash:Guest
$ HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1`
$ sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX app/cache app/logs
$ sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX app/cache app/logs
```

## 実際にアクセス
ホストOSのブラウザから，[http://localhost/app/example](http://localhost/app/example)にアクセス
ブラウザ上で"Homepage."が出力されればOK