目的
Macbookを新調した際にMax(OSX)上のsymfonyプロジェクト毎に環境を構築するのが面倒だったため、各プロジェクトをDockerコンテナで動作するようにしたい
環境
- OS X El Capitan
- Docker
手順
Dockerをインストールする
DockerはLinux上で動作するコンテナのため、OSX上でDockerコンテナを作成・実行したい場合には別途仮装マシン(linux)を立ち上げてその中で行う必要がある
Docker for OSXをインストールすると仮装マシンにVirtualBoxを使用した環境が用意され、OSX上から直接dockerコマンドを実行できる環境も用意されるため仮装マシンのことを意識することなくDockerを使える
mysqlのコンテナ化
Dockerコンテナ内のファイルシステムの変更はコンテナ起動時だけ有効なためコンテナを停止すると失われる。データベースのデータは毎回初期化されると困るので、このデータは永続化されるようにしたい。コンテナ内のデータの永続化についてData volumesと言う設定が用意されていて容易に対応が可能であるが、OSX上にこの永続化データを持たせるためにはちょっとした工夫が必要だった
OSXとVirtualBoxの間ではファイルシステムが共有される仕組みが用意されている。VirtualBoxを立ち上げると、OSX上の/UsersディレクトリがVirtualBox上の/Usersにマウントされていることが分かる。この仕組みを利用してDockerコンテナ内にプロジェクト内の適当なフォルダをマウントしてそこにmysqlのデータを保存すれば良い
しかしこれを行うには問題があった。virtualbox内では/Users配下が全てdockerユーザ権限となっており、この権限を変更できず、これをそのままDockerコンテナ内のmysqlデータ(/var/lib/mysql)に使おうとするとmysqlユーザ権限では書き込めない
この問題はここの投稿でも議論されており、2つの対応方法があるようだ
一つはVirtualBoxがホスト(OSX)のファイルシステムをマウントする方法を変える仕組み。ただなんかこれはちょっと怖い
もう一つの方法はコンテナ内のmysqlをdockerユーザ権限で動かすという方法。こっちの方が安全なようだし、対応も簡単
apacheのコンテナ化
apacheに関してはデータの永続化が必要となる箇所はなかったが、書き込み権限についてmysqlと同様な問題が発生した
symfonyのcache, logsディレクトリについて対応が必要だった。これに関しては、プロジェクトのレポジトリからディレクトリ毎削除してしまって、これらのディレクトリはコンテナ内で用意するように修正した
最後にコンテナ内からapacheユーザ権限でphp(symfony)コマンドを実行できるようにapacheユーザのログインシェルを有効にしています。nologin→bashに変更
docker-compose化
dockerコマンドで-vを使いそれぞれのコンテナにData volumeを割り当てて立ち上げるのを簡潔にするためにdocker-composeでまとめる
実行方法
これらのファイルをまとめたファイルをこちらのレポジトリにて公開しました
ベースは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"
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してしまうのがいいかもしれません