2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vagrant up 一発で立ち上がるウェブアプリケーション開発環境作り 第五回:DBサーバー編

Posted at

VagrantとDocker(とDocker Compose)を使って開発環境を一発で立ち上げられるようすることを目標とした連載、第四回です。

第一回:Vagrant編
第二回:Docker編
第三回:プロキシサーバー編
第四回:アプリケーションサーバー編

第二回で記事にしたdocker-compose.ymlのこの部分について、詳しく見ていきます。

docker-compose.yml
version: "2"
services:
  # mysql
  mysql:
    image: mysql:latest
    volumes:
      - /vagrant/docker/mysql/volume/sql:/docker-entrypoint-initdb.d:rw
      - /vagrant/docker/mysql/volume/conf:/etc/mysql/conf.d:rw
      - /vagrant/docker/mysql/volume/data:/var/lib/mysql:rw
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
  # php
  app:
    build: app/
    volumes:
      - /vagrant/docker/app/volume/web-root:/var/www/html:rw
    environment:
      XDEBUG_CONFIG: remote_host=10.0.2.2
    links: # 追加
      - mysql:mysql

今回使用する部分のディレクトリ構成はこうです。

<vagrant-root>
├── docker
│   ├── docker-compose.yml
│   ├── app # アプリコンテナ関連
│   │   ├── Dockerfile
│   │   └── volume
│   │       └── web-root
│   │           ├── index.php
│   │           └── show-hoge.php
│   └── mysql # DBコンテナ関連
│       └── volume
│           ├── conf
│           │   └── my.conf
│           └── sql
│               ├── create_database.sql
│               ├── create_table.sql
│               └── insert_test.sql
├── package.box
├── provision.sh #第一回参照
└── Vagrantfile

MySQLが動いているコンテナを用意する

ここまでくれば慣れたものだと信じて、イメージのビルドと起動についてはあまり触れません。Docker Hubの公式イメージをそのまま使っています。

MySQLの設定を変更する

やっていることは第三回の「設定をカスタマイズする」と同じです。

初期データを投入する

/docker-entrypoint-initdb.d/
にある、.sqlと.shファイルを辞書順に実行してくれます。
とりあえず検証用に簡単なデータベース、テーブル作成、データ投入を行います。
例によってvolumes:でsqlファイルが配置されるように設定します。

create_database.sql
CREATE DATABASE test;
create_table.sql
CREATE TABLE test.hoge (
  id int not null primary key auto_increment,
  name varchar(64) not null
);
insert_test.sql
insert into test.hoge (name) values
   ('abc'),
   ('def'),
   ('hij');

ホスト(Windows)から接続してみる

docker execでmysqlコンテナに入ってコマンドラインからDBの操作することも可能ですが、開発をする上では不便なので、ホストのツール(MySQL Workbenchなど)から接続できるようにします。

  • docker-compose.ymlのports:で、Vagrantの3306ポートからmysqlコンテナの3306ポートにフォワーディングする設定。
  • ユーザーはroot(ユーザーを作成したい場合は、DockerfileのRUNや、/docker-entrypoint-initdb.d/*.sqlで設定しましょう)
  • パスワードは環境変数"MYSQL_ROOT_PASSWORD"(今回は"password")

接続情報:
Host:192.168.33.10
User:root
Password:password
Default Schema(任意):test

接続に成功したら

select * from test;

を実行してみましょう。データが3件入っていれば成功です。

アプリケーションサーバーから接続してみる

第四回で作成したコンテナから接続して、PHPで中身を表示できるようにします。

PDOをインストール

appコンテナのDockerfileに以下を追記して、イメージをビルド時にPDOをインストールするようにします。

RUN docker-php-ext-install pdo_mysql mysqli mbstring

docker-php-ext-installとは、公式のイメージに入っているPHPの拡張機能をインストールするためのユーティリティです。
他にもdocker-php-ext-enable、docker-php-ext-configureなどが用意されています。
公式ドキュメント

何がインストールできるか手っ取り早く知りたければ、docker-php-ext-install --helpを実行すればわかります。

vagrant@vagrant-ubuntu-trusty-64 /vagrant/docker (compose-web *)
$ docker exec -it docker_app_1 bash
root@fd0d74f1337f:/var/www/html# docker-php-ext-install --help
usage: /usr/local/bin/docker-php-ext-install [-jN] ext-name [ext-name ...]
   ie: /usr/local/bin/docker-php-ext-install gd mysqli
       /usr/local/bin/docker-php-ext-install pdo pdo_mysql
       /usr/local/bin/docker-php-ext-install -j5 gd mbstring mysqli pdo pdo_mysql shmop

if custom ./configure arguments are necessary, see docker-php-ext-configure

Possible values for ext-name:
bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mcrypt mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zip

DBの中身を表示するプログラムを作る

appサーバーのweb-root直下に、以下の2ファイルを作成して、DBの中身を表示してみます。

db-config.php
<?php
ini_set('display_errors', true);
define('DB_DSN', 'mysql:host=mysql;dbname=test');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'password');
define('DB_CHARACSET', 'utf8');
show-hoge.php
<?php
include 'db-config.php';

$db = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES '" . DB_CHARACSET . "';"));
$stmt = $db->prepare('select * from hoge');
$stmt->execute();

while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  echo $row[id] . ' : ' . $row[name] . '<br />';
}

docker-compose.ymlのlinksで設定しているので、appコンテナから
mysqlのコンテナは"mysql"で参照できます。(db-config.phpの3行目)

以上が完了したら、 http://192.168.33.10/show-hoge.php にブラウザからアクセスして、投入したデータが表示されたら成功です。
image

データの永続化について

初期投入した以外のデータは、コンテナの削除で消えます。
(正確には初期投入したデータも消えるのですが、再作成の時にまた投入されるので)

操作 データ消える?
コンテナ停止(docker stop) 消えない
コンテナ削除(docker rm) 消える
コンテナのホストシャットダウン(vagrant halt) 消えない
ホストマシン(Windows)のシャットダウン 消えない

データが消えるのが不安であれば、コンテナの/var/lib/mysqlをホストのどこかにマウントすると、データがホスト側に残ります。
Data Volume Containerパターンを思いっきり無視していますが、勉強中です。(いつか書くかも)

結び

長くなりましたが、これでvagrant up一発で、DBの中身まで参照できる環境が完成しました。一旦連載は終了です。
全コンテナに最低限の設定しかしておらず、実際にプロダクトを作ろうとなるとまだまだ問題があるとは思いますが、参考にしていただけると幸いです。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?