wordpress案件 に docker を使ってみた件


## はじめに

 きょんにちょわ [UNIBA](http://uniba.jp) の monpy です。
 今回から気合の入った記事には会社名を入れることにしました。
 
 それはおいといて、弊社に `wordpress` 案件がきました。
 僕が入社してから `wordpress` やら `MT` の仕事はしない傾向にあったんですが、フロントエンドの自分としては一回やっておきたいなぁ、と思い飛びつきました。
 
###案件の概要
 
* wordpress を使った会員制のサイトをつくりたい
* 別途 rails を用いて会員の管理は行う

ということで、図に表すと

![test.jpg](https://qiita-image-store.s3.amazonaws.com/0/68729/cfcc0164-f2c4-fed0-e701-441df4ae227c.jpeg "test.jpg")

みたいな感じですね。

`PHP` と `Rails` の共演、さらに `css` と `javascript` は `Node` を使って作成しているのでフロントエンド冥利に尽きる構成となっております。

##アサインされた人

* フロントエンドエンジニア
	* 私
	* PHP 歴ほぼない
	* 昔 wordpress 2~3 系ぐらいのときに少し触った程度
	* mac
* バックエンドエンジニア
	* 私と同い年
	* rails とか node とかやっている
	* docker 導入は初めて
	* mac
* 他 フロントエンドアシスト、PM など

ということで、不安も抱えつつも案件に挑戦である

## docker 導入までの経緯

### wordpress テーマ構築が抱える不安

ここでいう不安というのは、個人的な所感です

* 実環境(Production)との誤差をなくす
* テーマファイルの同期
* DBの同期
* 手元の環境を汚さない
* 別案件との両立性

ぐらいでしょうか。とくに　`DBの同期`が重要なテーマだったと思います。
今回フロントは僕だけではなく、その彼も `wordpress` の開発にあまり明るくなかったのです。

### Wordpressテーマ構築における選択肢

ともあれ、他にも テーマ構築するためには他の選択肢がいくつもあります。

* MAMP
	* およそ個人で製作をやられている方はこれを使用している方が多いのでは
	* `DBの同期`,`実環境との誤差をなくす` らへんで選択肢から除外しました。あと、せっかくの機会に `MAMP` でやるのはもったいない気が、、、
* VCCW
	* dockerと同じく VM 上に `wordpress` 環境を構築してくれる。
	* 環境のカスタマイズが非常にやりずらいため選択肢から除外
* 手元(mac)で `wordpress` 環境 をつくる
	* 以外とこれが一番よかったのかもしれない(他の会社ではこれでも十分とのこと、、、くっそー)
	* `手元の環境を汚さない`という点でハナから選択肢に入ってなかったのですが、

ともあれ、これらの選択肢が除外されたことで `docker` による `wordpress` 環境構築が始まったわけです。


## docker について

![Kobito.6EpZlt.png](https://qiita-image-store.s3.amazonaws.com/0/68729/bcbf03c0-112a-13b3-4ee5-8d63b9bb4d45.png "Kobito.6EpZlt.png")

くじらさんが `docker` のシンボル。
`docker` の 技術概要については、私の説明よりもわかりやすいサイトがいくつもあるので割愛
ここから docker の良さと共に環境構築フローを記述します。

### ホスト環境の統一
いわゆる `docker-machine create` でつくられるマシン(ホストという言い方でよいのかな？) の環境をある程度指定します。
たとえば

```
docker-machine create --driver virtualbox --virtualbox-hostonly-cidr "192.168.123.1/24" $APP_NAME
```

とすれば、ホストの IP を `192.168.123.(初期は100)`で統一できます。
すると、自分の環境と他人の環境が同じになるので ローカル環境同士の `DBの同期` が楽ですね。

### インストールされる環境を統一

ホストを準備したところで コンテナをつくります　`docker` には　wordpress公式のイメージファイルが提供されています。
のでこれを実行するだけで環境が整います。最高ですね。

#### PHP の extention について

とはいえ、提供されたイメージファイルには `mb_string` などの関数が使えない状況です。
そういう場合は `docker fale` を用意して追記してあげましょう。
`docker` には `docker-php-ext-install` というイメージファイルも準備されているのでそれを利用します。

ということで一連の流れをシェルスクリプトに準備してあげます。

まずはフォルダ構成(他にもいろいろあるが最小構成単位として)

```
.
├── Makefile  // こいつに bin/bootstrap を叩く関数を用意してあげると初心者に優しい
│
├── bin
│   └── bootstrap // 環境構築の一連の処理を書く
│
├── docker-compose.yml // image ファイルの設定の準備
│
├── docker-images
│   └── wordpress_custom_php　// PHP extention　系の設定を書く
│		└──　Dockerfile
│
└── wp  //この中のフォルダが VM 上で読み込まれるファイル、この中をいじれば wordpress の表示が変わる
    
```

となっています。

#### bin/bootstrap

```
APP_NAME=hoge

docker-machine create --driver virtualbox --virtualbox-hostonly-cidr "192.168.123.1/24" $APP_NAME
docker-machine start $APP_NAME
eval "$(docker-machine env $APP_NAME)"
docker-compose up -d
open http://`docker-machine ip $APP_NAME`

```

ホストを作って　`docker-compose.yml` に書かれている処理を実行するという文章。
おまけで 最後に 見れるかどうかチェックします。
こんだけで　`wordpress` 環境ができます。最高

#### docker-compose.yml

```
wordpress:
  container_name: wordpress
  build: docker-images/wordpress_custom_php
  links:
    - db:mysql
  ports:
    - "80:80"
  volumes:
    - ./wp:/var/www/html

db:
  image: mysql
  container_name: db
  ports:
    - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: 'password'
```

これがVMにインストールされる環境です。
ほぼ、公式が用意してくれているファイルのままです(今回 php-extentionをインストールするので buidl プロパティがあります。)、詳しい設定は 元ファイルを読みましょう。
ちなみに　volumes には wp というフォルダを設定しますが、
ここに同名のフォルダがあるときは、上書きされないので、wpフォルダ をgitで共有しておけば 立ち上がり同時にほぼ全ての環境が同期できます(DB以外)

wordpress の設定に build という項目がありますが、これに `Dockerfile` のあるフォルダを指定すると、
そのスクリプトがビルド時に実行される具合です

#### docker-images/wordpress_custom_php/Dockerfile

```
FROM wordpress:4.3.1-apache
RUN docker-php-ext-install mbstring
```

これが、wordpressコンテナの中身です。
公式配布されている　wordpress の処理を実行したあとで、mbstring をインストールしてます。

#### Makefile
というのを

```
make bootstrap
```

で実行できるようにしてあげると良いのでは。

## DB の同期

さて、こちらについては僕の専門外なのですが、要するに VM の中の DB　からデータを `dump` して `restore` してあげれば ok です。

ここらへんは 先ほどの `docker-compose.yml` の db の項目に volumes を設定してあげたりして、データのやり取りを楽にすると便利ですね。

#### sed で置換する

よくあるお話が DB のドメインとか変えないと見えなくなる問題こういう感じで対処

```
sed -i '.tmp' -e "s|$0|$1|g" dump.sql
```

これを Makefile で考えずに使えるように準備

例えば、　preview -> dev(local), staging -> dev とかすれば楽ちん
合わせて、 dump 処理も 同時に行わせれば文句あるまい。

## ここまでのまとめとメリット・デメリット

さてこれで

* docker で　wp 環境を構築することができた
* Makefile に全ての処理をラップさせることで 導入障壁を限りなく低くした

というところでしょうか。

ではここで メリット と デメリットをまとめます

### メリット

* `git clone` して　`make bootstrap` で環境構築
* 何か大きな変更を加えた場合も一旦環境を捨てて再構築してもらえればok
* 手元も汚れない
* ソース読むと `shell script` の理解が進むよ

### デメリット

* 重い
	* VM で動かしているのでやっぱし重い。PCの機嫌にもよる
* 一人だと無理ぽ
	* もちろん一人ならこんな構成でやらないけどバックエンドを普段やっているひとが一人はいないと諸々辛くなりがち
* 学習コスト
	* こういう風にまとめたりしないと辛い
	* ともあれ、少しは `docker` の公式サイトとかを読まないといけないかな
	* あとは使用するイメージファイルを理解しないと怖いかも
* 謎のバグ
	* まだまだ `docker` は発展途上 `vertual box` のバージョンに左右されることもあるし、つらい


まぁそんなとこでしょうか。
wordpress の構築自体は特に触れずに今回は環境の話だけ。
よかった、悪かったといえば、、、
案件はうまくいったのでよかったのだが、そんな気合い入れた環境じゃなくてもよかったのかも、、、
と思ってしまいました。

ともあれ、同じような試みをしている方がいれば是非共有をば。

## 謝辞

ここまで読んでくださりありがとうございました！
`docker` はイカしている技術だと思ってはいるのですが、まだまだスペックや操作感を考えるとこれからが期待な感じですね。
フロントエンドとしてどうやったらうまく案件の状態をコントロールできるか、、、というところでこういうお話でした。

仕事ください。