Mac OSX上のsymfonyプロジェクトをDockerコンテナで動かす

## 目的

Macbookを新調した際にMax(OSX)上のsymfonyプロジェクト毎に環境を構築するのが面倒だったため、各プロジェクトをDockerコンテナで動作するようにしたい

## 環境

- OS X El Capitan
- [Docker](https://docs.docker.com/engine/installation/mac/)

## 手順

### Dockerをインストールする

DockerはLinux上で動作するコンテナのため、OSX上でDockerコンテナを作成・実行したい場合には別途仮装マシン(linux)を立ち上げてその中で行う必要がある

Docker for OSXをインストールすると仮装マシンに[VirtualBox](https://www.virtualbox.org/)を使用した環境が用意され、OSX上から直接dockerコマンドを実行できる環境も用意されるため仮装マシンのことを意識することなくDockerを使える

### mysqlのコンテナ化

Dockerコンテナ内のファイルシステムの変更はコンテナ起動時だけ有効なためコンテナを停止すると失われる。データベースのデータは毎回初期化されると困るので、このデータは永続化されるようにしたい。コンテナ内のデータの永続化について[Data volumes](https://docs.docker.com/engine/userguide/containers/dockervolumes/)と言う設定が用意されていて容易に対応が可能であるが、OSX上にこの永続化データを持たせるためにはちょっとした工夫が必要だった

OSXとVirtualBoxの間ではファイルシステムが共有される仕組みが用意されている。VirtualBoxを立ち上げると、OSX上の/UsersディレクトリがVirtualBox上の/Usersにマウントされていることが分かる。この仕組みを利用してDockerコンテナ内にプロジェクト内の適当なフォルダをマウントしてそこにmysqlのデータを保存すれば良い

しかしこれを行うには問題があった。virtualbox内では/Users配下が全てdockerユーザ権限となっており、この権限を変更できず、これをそのままDockerコンテナ内のmysqlデータ(/var/lib/mysql)に使おうとするとmysqlユーザ権限では書き込めない

この問題は[ここの投稿](https://github.com/docker-library/mysql/issues/99)でも議論されており、２つの対応方法があるようだ

一つはVirtualBoxがホスト(OSX)のファイルシステムをマウントする方法を変える仕組み。ただなんかこれはちょっと怖い

もう一つの方法はコンテナ内のmysqlをdockerユーザ権限で動かすという方法。こっちの方が安全なようだし、対応も簡単

### apacheのコンテナ化

apacheに関してはデータの永続化が必要となる箇所はなかったが、書き込み権限についてmysqlと同様な問題が発生した

symfonyのcache, logsディレクトリについて対応が必要だった。これに関しては、プロジェクトのレポジトリからディレクトリ毎削除してしまって、これらのディレクトリはコンテナ内で用意するように修正した

最後にコンテナ内からapacheユーザ権限でphp(symfony)コマンドを実行できるようにapacheユーザのログインシェルを有効にしています。nologin→bashに変更

### docker-compose化

dockerコマンドで-vを使いそれぞれのコンテナにData volumeを割り当てて立ち上げるのを簡潔にするためにdocker-composeでまとめる

## 実行方法

これらのファイルをまとめたファイルを[こちらのレポジトリ](https://github.com/hc100/osx-symfony-docker)にて公開しました

ベースはCentOS6、apache-2.2、php-5.5、mysql-5.5です。

実行手順としては下記のような形になります

```
% cd someproject
% rm -rf var/cache var/logs
% mkdir var/db
% git clone https://github.com/hc100/osx-symfony-docker.git docker
% cd docker
% eval "$(docker-machine env default)"
% docker-compse build
% docker-compse up
```

http://docker-machine-ip/ でsymfonyプロジェクトが反映されている事が確認できます

プロジェクトの編集は直接Mac上のファイルシステムで修正を行えます
symfonyのbin/consoleコマンドの実行や、データベースへのデータ反映などでコンテナ内にアクセスする必要がある場合は下記のようにコンテナ内のシェルを立ち上げて行えます

```
% docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED      ...
6fac41c48b42        docker_mysql        "/localdb-run.sh"    7 minutes ago
cdb249a788b8        docker_webserver    "httpd-foreground"   7 minutes ago

% docker exec -ti cdb249a788b8 /bin/bash
[root@cdb249a788b8 www]# cd /var/www/
[root@cdb249a788b8 www]# su -l apache -c 'php bin/console doctrine:schema:update --force'
```

cdb249a788b8はdocker psより取得したwebserverのコンテナIDになります

同様に6fac41c48b42を指定してmysqlのコンテナにシェルを立ち上げて直接mysqlを操作できます

プロジェクト編集前にmysql上で適切な権限設定をする必要があります

```
[root@6fac41c48b42 www]# mysql
mysql> GRANT ALL ON *.* TO 'foobar'@'%';
```

symfonyのapp/config/parameters.yml内のdatabase_hostにはdocker-machineのIPアドレスを指定します

```
% docker-machine env default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/k-ozaki/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
```

```app/config/parameters.yml
parameters:
    database_driver: pdo_mysql
    database_host: 192.168.99.100
```

コンテナ内でsymfonyコマンドを実行する際にはapacheユーザで実行するように注意が必要です

```
[root@cdb249a788b8 www]# su -l apache -c 'php bin/console cache:clear --env=prod'
```

これによりcache、logs内のファイルの権限変更を防ぎます
su - apacheしてしまうのがいいかもしれません