概要
以前、Docker Toolboxを利用し、Webアプリのローカル開発環境(Apach+PHP, MySQL)を構築しました。
以前は最小限の構成だったため今回は追加設定を行います。
拡張したこと
Webアプリ(PHP)周り
- Webアプリケーションフレームワーク(CakePHP)の導入
DB(MySQL)周り
- DBの初期化
- DB(データ)の永続化
最終的なフォルダ・ファイル構成
./docker/
|-- docker-compose.yml
|-- web
| |-- Dockerfile
|-- db
| |-- Dockerfile
| |-- initdb.d
| | |-- init_db.sql
| |-- data
|-- html
|-- composer.json
|-- app
| |-- CakePHPプロジェクト
|-- vendor
| |-- composerインストールしたバンドル
フレームワークの導入
docker-compose.ymlの編集
docker-compose.ymlを編集し、コンテナをリビルド・(再)起動します。
まずは一度コンテナを停止・削除します。
$ docker-compose down
Stopping docker_web_1 ... done
Stopping docker_db_1 ... done
Removing docker_web_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
完了後、docker-compose.ymlを以下のように編集します。
$ cat docker-compose.yml
version: "2"
services:
web:
build: ./web
links:
- db
ports:
- "80:80"
volumes:
- ./html/:/var/www/html
working_dir: /var/www/html
# command: app/bin/cake server -H webhost -p 80
extra_hosts:
- "webhost:192.168.99.100"
hostname: webhost
db:
build: ./db
ports:
- "30000:3306"
environment:
MYSQL_ROOT_PASSWORD: password
前回からの追記内容は以下の通りです。
ファイル名 | 説明 |
---|---|
working_dir | webコンテナへログインしたときのホーム(作業)ディレクトリ |
command | デフォルトで実行するコマンド(この時点ではコメントアウト、後述します) |
extra_hosts | ホスト名とIPアドレスの関連付け(/etc/hostsに設定されます) |
hostname | ホスト名の割り当て(/etc/hostnameに設定されます) |
Dockerfileの編集
フレームワークの導入には、composer(パッケージ管理ツール)を利用します。
現状のWebコンテナには、composerはインストールされていないためCakePHPシステム要件を参考にDockerfileを以下のように編集します。
$ vim web/Dockerfile
FROM php:5.6.30-cli
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
RUN ["apt-get", "install", "-y", "git"]
RUN ["apt-get", "install", "-y", "unzip"]
RUN ["apt-get", "install", "-y", "libicu-dev"]
RUN docker-php-ext-install mbstring intl pdo_mysql
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
EXPOSE 80
今回、CakePHPのビルトインサーバーを利用し動作確認するためApacheの入っていないイメージを指定しています。
FROM php:5.6.30-cli
git、unzipもインストールします。
gitは、composerを利用してバンドル(フレームワークのパッケージ群)をダウンロードするとき、unzipはダウンロードしたバンドルの解凍に利用されます。
また、CakePHPの導入に必要なintlもPHPの拡張モジュールとして追加しました。なおlibicu-devはintlインストールに必要なモジュールです。
composerはダウンロード後、composer
コマンドとして利用するため環境パスを通しています。
composer.jsonの作成・編集
composerを利用し、CakePHPをPHPのWebアプリケーションフレームワークとして導入します。
導入するバンドルを以下のようにcomposer.jsonに定義します。
composer.jsonの定義内容はこちらCakePHPをご参考ください。
後述しますが、composer install
コマンドを実行すると、実行したディレクトリに存在するcomposer.jsonの定義をもとにフレームワークを導入します。
$ vim html/composer.json
{
"require": {
"cakephp/cakephp": "dev-master"
}
}
コンテナのリビルド・(再)起動
更新内容をコンテナに反映します。
コンテナをリビルドし、リビルド完了後、コンテナを起動します。
$ docker-compose build
.....
Successfully built
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_db_1
Creating docker_web_1
composerによるフレームワークのインストール
コンテナ起動後、composer install
コマンドを実行し、composer.jsonに定義したバンドルをインストールします。
$ docker-compose run web composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
.....
Generating autoload files
正常にフレームワークがインストールされると、'html/vendor/'以下にフレームワークのバンドルが確認できます。
CakePHPプロジェクトの作成
CakePHP公式ドキュメントを参考に、CakePHPのプロジェクトを作成します。
$ docker-compose run web composer create-project --prefer-dist -n cakephp/app
Installing cakephp/app (3.4.3)
- Installing cakephp/app (3.4.3): Downloading (100%)
Created project in app
.....
Updated Security.salt value in config/app.php
html/app
以下に、CakePHPのプロジェクトが作成できました。
ビルトインサーバーの起動
app/bin/cake server -H webhost -p 80
で、ホストとポートを指定して、ビルトインサーバーを起動します。
docker-compose.ymlのコメントアウトを外します。これで次回コンテナ起動時から、ビルトインサーバーが起動します。
command: app/bin/cake server -H webhost -p 80
webhost
は、webコンテナのホスト名(docker-compose.ymlに設定)です。
そして192.168.99.100
は、dockerマシンのIPです。
$ docker-machine ip
192.168.99.100
この後、コンテナを停止・削除->リビルド->起動します。
(コンテナは停止・削除しなくても大丈夫かと思いましたが、しなかった場合、正常にビルトインサーバーが起動しなかったため停止・削除しています。おそらくネットワークの問題?)
$ docker-compose down
Stopping docker_web_1 ... done
Stopping docker_db_1 ... done
Removing docker_web_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
$ docker-compose build
.....
Successfully built 62e7ad53eb28
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_db_1
Creating docker_web_1
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------
docker_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:30000->3306/tcp
docker_web_1 docker-php-entrypoint app/ ... Up 0.0.0.0:80->80/tcp
動作確認
ブラウザで、http://192.168.99.100/
にアクセスします。
CakePHPのデフォルト画面が表示されていれば動作確認の完了です。
DB(MySQL)周りの拡張設定
DBの初期化
前回、dbコンテナにログインし、手動でDB・テーブル・データを作成しました。
これをコンテナ作成時に自動で作成するよう設定を追加します。
$ vim db/Dockerfile
FROM mysql:5.7
COPY ./initdb.d/init_db.sql /docker-entrypoint-initdb.d/
/docker-entrypoint-initdb.d
ディレクトリに配置したシェルやSQLファイルはMySQLインスタンス起動時に実行されます。
./initdb.d
は、マウントするホスト側のディレクトリです。
以下のディレクトリ・SQLファイルを作成します。
$ mkdir db/initdb.d
$ vim db/initdb.d/init_db.sql
CREATE DATABASE IF NOT EXISTS sample;
CREATE TABLE IF NOT EXISTS sample.user (
`id` INT AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
INSERT INTO sample.user(id, name) VALUES(1, 'Test1'), (2, 'Test2');
コンテナを停止・削除後、リビルド・起動します。
$ docker-compose down
Stopping docker_web_1 ... done
Stopping docker_db_1 ... done
Removing docker_web_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
$ docker-compose build
.....
Successfully built 62e7ad53eb28
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_db_1
Creating docker_web_1
DBの初期化に成功できていることを確認します。
$ docker-compose run db mysql -h db --port 3306 --protocol tcp -u root -ppassword
mysql> SELECT * FROM sample.user;
+----+-------+
| id | name |
+----+-------+
| 1 | Test1 |
| 2 | Test2 |
+----+-------+
2 rows in set (0.01 sec)
DB(データ)の永続化
DB(データ)の永続化は2種類の方法があります。
- ホストのディレクトリをマウント
- ボリューム用のコンテナを作成
今回は、ホストのディレクトリをマウントすることでデータを永続化します。
まずはdocker-compose.ymlを編集します。
db:
build: ./db
ports:
- "30000:3306"
volumes:
- ./db/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
ホスト側のディレクトリは任意(./db/data
ディレクトリは作成してください)で、dbコンテナ側は/var/lib/mysql
をマウント指定します。詳細はこちらを参照ください。
コンテナを停止・削除後、リビルド・起動し、DBにデータを追加します。
$ docker-compose down
Stopping docker_web_1 ... done
Stopping docker_db_1 ... done
Removing docker_web_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
$ docker-compose build
.....
Successfully built 62e7ad53eb28
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_db_1
Creating docker_web_1
$ docker-compose run db mysql -h db --port 3306 --protocol tcp -u root -ppassword
mysql> INSERT INTO sample.user(id, name) VALUES(3, 'Test3');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM sample.user;
+----+-------+
| id | name |
+----+-------+
| 1 | Test1 |
| 2 | Test2 |
| 3 | Test3 |
+----+-------+
3 rows in set (0.00 sec)
そして、コンテナを停止・削除・起動します。
$ docker-compose down
Stopping docker_web_1 ... done
Stopping docker_db_1 ... done
Removing docker_db_run_1 ... done
Removing docker_web_1 ... done
Removing docker_db_1 ... done
Removing network docker_default
$ docker-compose up -d
Creating network "docker_default" with the default driver
Creating docker_db_1
Creating docker_web_1
永続化前は、コンテナを削除した時点でDBに追加したデータは消えてしまいます。
再度DBにアクセスし、さきほど登録されたデータが残っていることが確認できます。
$ docker-compose run db mysql -h db --port 3306 --protocol tcp -u root -ppassword
mysql> SELECT * FROM sample.user;
+----+-------+
| id | name |
+----+-------+
| 1 | Test1 |
| 2 | Test2 |
| 3 | Test3 |
+----+-------+
3 rows in set (0.00 sec)
追加したデータが確認できれば完了です。