Dockerで作るWordPressテーマローカル開発環境

# 動機

・VagrantBoxがローカルマシーンのストレージを圧迫してにっちもさっちもいかない状況に
・`vagrant up`に時間がかかる → cssちょっと直すだけなのにコンビニに行けちゃう
・Windows ⇔ Mac 開発環境での不具合

![docker-compose.png](https://qiita-image-store.s3.amazonaws.com/0/26285/ac140edb-f3b9-ab9c-473b-669b4e00cd5c.png)

phpのこの設定をいじりたい！（そうしたらこの大きな画像もアップロードできるのに...）
って方のためにコンテナ内の`php.ini`を置き換える設定も入れています。


# 背景

VCCW → Docker

VCCWはwp-cliもwordmoveもmailcheckerもあるので、本当に感謝しています。
簡単にWordPressのテーマ開発を始めたいならまずVCCWで始めることをおすすめします。

[VCCW](http://vccw.cc/)

# Dockerコンテナ構成

・Docker Hubに上がっている公式イメージを使用
・Docker ComposeでPHPサーバーとデータベースの設定を1ファイルで管理

DockerはHubにイメージとしてコンテナが保存されていて、そこからコンテナをダウンロードしてきます。一度ダウンロードしたコンテナは次回からはローカルに保存されるので、初回以降はキャッシュから実行されます。

設定ファイルの詳細は例として、最後に乗せておきます。

# Dockerコンテナの操作

vagrantでsshで入ってサーバー操作するのはよくあることかと思います。
Dockerではdockerコマンドでコンテナ内に入ってコマンドを実行したり、logを見たりします。


## Dockerの立ち上げ

Macの場合、`docker-compose.yml` があるディレクトリで、
ターミナルから下記のコマンドを実行します。

オプションの `-d` はデーモンつまり、停止コマンドを打たない限り実行し続けます。
`d` オプションを付けない場合は、ログが表示されつづけて Ctrol + C で停止します。

```
$ docker-compose up -d
```

## 走っているDockerコンテナを確認

走っているDockerコンテナを確認するときは任意のディレクトリで、
ターミナルから下記コマンドを実行します。


```
$ docker ps
```

実行結果の例はこんな感じです。

```
CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS              PORTS                  NAMES
8b1cc6ed73dc        wordpress:latest    "docker-entrypoint.s…"   Less than a second ago   Up 12 seconds       0.0.0.0:8802->80/tcp   example-web
89c4e6ae3878        mysql:latest        "docker-entrypoint.s…"   Less than a second ago   Up 15 seconds       3306/tcp                example-db
```

Wordpressのコンテナが走っているポートにブラウザでアクセスすれば、
ページが表示されるはずです。
http://localhost:8802

## Dockerコンテナを停止する

docker-composeで起動したDockerコンテンナを停止するコマンドは以下です。

```
$ docker-compose down
```

データベースやコンテナと共有したボリュームを消去する場合は `—volumes` オプションを付けます。

```
$ docker-compose down --volumes
```

## Dockerコンテナ上でコマンドを実行

DockerコンテナはIDを取得して表示するのでちょっと厄介です。

vagrant SSHみたいにコンテナ上でコマンドを実行したいとき

```
$ docker exec -it $(docker-compose --project-name example ps -q wordpress) /bin/bash
```

ContainerIDを取得しつつコマンドを実行しています
`—project-name` で指定している `example` は `docker-compose.yml` が置いてあるディレクトリ名 `wordpress` は `docker-compose.yml`  内で指定しているサービス名になります。

（※ローカルディレクトリは、/home/xxx/xxx/example/docker-compose.yml という設定）

もちろん、`Container ID` を `docker ps` で取得してからの実行もできます。
コマンド暗記でやるならこちらのほうが早いですね。

```
$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS              PORTS                  NAMES
8b1cc6ed73dc        wordpress:latest    "docker-entrypoint.s…"   Less than a second ago   Up 12 seconds       0.0.0.0:8802->80/tcp   example-web
89c4e6ae3878        mysql:latest        "docker-entrypoint.s…"   Less than a second ago   Up 15 seconds       3306/tcp                example-db

$ docker exec -it 8b1cc6ed73dc /bin/bash

#  (←コンテナにログインした)
```

## Dockerコンテナにコマンドを流し込み

コンテナにログインせずに直接コマンドを流し込みたい場合

```
$ docker exec -it $(docker-compose --project-name example ps -q wordpress) sh -c 'ANY COMMAND'
```

こちらも`Container ID`指定でも大丈夫

```
$ docker exec -it 8b1cc6ed73dc sh -c 'ANY COMMAND'
```

## Dockerのログを見る

Dockerコンテナに流れているログを見ます。
こちらはCONTAINER_IDでもCONTAINER_NAMEでもいけます。

```
$ docker logs -f example-web
$ docker logs -f 8b1cc6ed73dc 
```

`-f` オプションはfollowの略、ブラウザでアクセスしながらログを流し見るのに便利です。
`-t` オプションはタイムスタンプ、ログの取得日時が記されます。

オプション無しでも、オプションを両方つける `-ft` のでも利用できます。

## ローカルDBのバックアップを取れるように

Dockerデータベースの設定で、`Volumes`を定義しておけば、
特定のディレクトリに入ったSQLを実行してくれるという便利な機能があります。

つまり、mysqlで取ったダンプファイルをそのディレクトリに入れておけば、
Dockerを停止したり動かしたりしても、同じデータベースの環境を再現できます。

Dockerコマンドでとってもいいのですが、
`backup-db.sh` というシェルを用意しておいて、シェルの実行のみでバックアップが作られるようにします。

```sh:backup-db.sh
#!/bin/sh
DIR=`echo $(pwd) | awk -F "/" '{ print $NF }'`
docker exec -it $(docker-compose --project-name ${DIR} ps -q db) sh -c 'mysqldump -u wordpress -p wordpress  2> /dev/null > /docker-entrypoint-initdb.d/wordpress.sql'
```

ディレクトリ名を取得して、DBコンテナ（mysql）にmysqldumpコマンドを実行
ダンプファイルをコンテナとVolume共有したディレクトリに保存しています。

```
/bin/sh backup-db.sh
```

DBのパスワードを入力して保存（ローカルだと`db-data`、コンテナだと`docker-entrypoint-initdb.d`に`wordpress.sql`というダンプファイルが保存されます）


## ディレクトリ構成

```text:Dir構成
backup-db.sh
config  - php.ini
db-data - wordpress.sql
docker-compose.yml
public (Wordpressディレクトリ)
```

## docker-compose.yml

こちらがローカルで使っていたDockerComposeの設定
アップロード制限があったので、`php.ini` も書き換えていました。

`db-data` 以下(コンテナでは`docker-entrypoint-initdb.d`以下)のSQLはコンテナ `build` 時に実行されます。

```yml:docker-compose.yml
version: '3'

# Services
# -----------------------------------------------------------------------------
services:

   # Database
   # -----------------------------------------
   db:
     image: mysql:latest
     container_name: example-db
     volumes:
       - db_data:/var/lib/mysql
       - ./db-data:/docker-entrypoint-initdb.d
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   # WordPress
   # -----------------------------------------
   wordpress:
     image: wordpress:latest
     container_name: example-web
     volumes:
      - ./public:/var/www/html
      - ./config/php.ini:/usr/local/etc/php/conf.d/php.ini
     depends_on:
       - db
     ports:
       - "8802:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
     domainname: percent.test

volumes:
   db_data:
    driver: local
```

```ini:config/php.ini
post_max_size=50M
```

### wp-content以下だけ編集する場合

`Volumes` の設定を wp-content 以下にすればOK

```yml:docker-compose.yml
   wordpress:
     image: wordpress:latest
     container_name: example-web
     volumes:
      - ./public/wp-content:/var/www/html/wp-content
```

### 複数サービスを実行するときはportを変えて対応しています（暫定）

他のプログラムとportがかぶってなければ動くので、8000番台を適当に設定していっている状況です。
本当はドメインとか振りたいけど、DockerコンテナでサービスごとにDNS立ち上げたりとか泥沼っぽいのでいまのところ保留。

```yml:docker-compose.yml
     ports:
       - "8080:80"
```
この場合は、
http://localhost:8080/

# 展望

+ `Kubernetes` を利用したオーケストレーション＆デプロイ（したい）
+ SSL（HTTPS）対応

# Dockerのインストールなどはこちらから(Mac)

[今更だけどDockerでWordPress環境を用意してみたら超簡単だった](https://qiita.com/maimax/items/5090fd37f9832fe3c5fd)

# とにかくいますぐ開発を始めたいとき

[Docker+Gulpでいい感じにWordPressのテーマ開発を始められるスタートアップキットをつくってみました]
(https://qiita.com/KoichiSugimoto/items/3656a10025266ad90dcf)

# 最近書いた記事
[Gulp + Webpack + Babel + Vue.js で作るWordPressテーマ開発環境](https://qiita.com/KoichiSugimoto/items/d8a5563f197682dea0f4)
[Gulp + Webpack(+Babel)でシンプルJQuery構成](https://qiita.com/KoichiSugimoto/items/283d967169546c3f2dce)
[Gulp + yarn シンプルJQuery構成](https://qiita.com/KoichiSugimoto/items/2136dfb1e9679868abba)