XAMPP/MAMPの代わりにDocker ToolboxでLAMP環境を構築する（Docker入門ハンズオン）

# このハンズオンの概要と目的
[XAMPP](https://www.apachefriends.org/jp/index.html)や[MAMP](https://www.mamp.info/en/)を使えば、手元のPCにLinux, Apache, MySQL, PHP (LAMP) の環境を手軽に構築できます。

[Docker Toolbox](https://www.docker.com/products/docker-toolbox)を使えば、XAMPP/LAMPと同じことが、それら以上に柔軟に可能です。
Dockerの入門ハンズオンとして、Docker ToolboxでLAMP環境を構築してみましょう。



# 検証環境
- Windows 7 Professional Service Pack 1 (64-bit)
- Docker version 1.9.1, build a34a1d5
- docker-compose version: 1.5.1
- docker-machine version 0.5.1 (7e8e38e)

基本的な操作だけなので、バージョンは厳密に揃えなくて構いません。
私は未検証ですが、Windows 8や10でも大丈夫なはず[^wantcomment]です。

[^wantcomment]: この記事の手順でうまくいった！という方はコメントをくださると非常に嬉しいです。

Mac OS Xでも可能です（こちらは検証しました[^macos]）。
手順の中のコマンドがほんの一部変わるだけですので、トライしてみてください。

[^macos]: OS X El Capitan (10.11.3) にて確認


# ハンズオン手順（基礎）
大まかな流れは次の通りです：

1. ツールをインストール：  
    Docker Toolboxをインストールし、Docker Quickstart Terminalを起動します。
2. 設定ファイルを用意：  
    LAMP環境を設定するファイルと、PHPの動作確認のための簡単なスクリプトを用意します。
3. 起動と動作確認：  
    Docker Composeを使ってLAMP環境を起動し、ブラウザーから動作を確認します。
4. 立ち下げと後片付け
    環境を「使い捨て」してみます。

ツールのインストールに時間がかかるため（インストーラーが170 MB以上あります）、ダウンロードを待つ間に設定ファイルを用意するとよいです。


## Docker ToolboxのインストールとDocker Quickstart Terminalの起動
公式サイトを参照してDocker Toolboxをインストールします：
https://www.docker.com/products/docker-toolbox

Oracle VirtualBox（VMミドルウェア、必須）[^virtualbox]と、Docker Quick Terminal、Kitematic（任意ですが、ここではインストールを選びます）が同時にインストールされます。

[^virtualbox]: VirtualBoxを起動するには、ハードウェア仮想化を有効にする必要があります。Docker Toolboxインストールの手順（英語ですが）に書いてあるので、確認してください。

インストールが完了したら、Docker Quickstart Terminalを起動します。
以下のようなクジラのコンソールが現れれば成功です：

```bash

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/

docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com


kazuma@PC MINGW64 ~
$
```


## LAMP環境の設定ファイルと、PHPスクリプトの準備
**ユーザーフォルダー配下**の任意の場所（たとえば_C:\Users\kazuma\work\2016\mar28_）に、以下のファイルを用意します：

- docker-compose.yml
- src/phpinfo.php

```yaml:docker-compose.yml
mysql:
    image: mysql:5.7.11
    environment:
        - MYSQL_ROOT_PASSWORD=root
apache-php:
    image: php:5.6.19-apache
    ports:
        - "80:80"
    volumes:
        - ./src:/var/www/html
    links:
        - mysql:db
phpmyadmin:
    image: phpmyadmin/phpmyadmin:4.5.3.1-1
    ports:
        - "8080:8080"
    links:
        - mysql:db
```

```php:src/phpinfo.php
<?php
phpinfo();
```


## Docker ComposeでLAMP環境を起動し、動作確認
### `docker-compose up -d`
docker-compose.ymlに定義したLAMP環境を起動します。
初回はイメージファイルをダウンロードする時間がかかります：

```bash
kazuma@PC MINGW64 ~
$ cd ~/work/2016/mar28/

kazuma@PC MINGW64 ~/work/2016/mar28
$ pwd
/c/Users/kazuma/work/2016/mar28

kazuma@PC MINGW64 ~/work/2016/mar28
$ ls -Ap1R
.:
docker-compose.yml
src/

./src:
phpinfo.php

kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose up -d
# ...
# ダウンロードの進捗...
# ...
Creating mar28_mysql_1
Creating mar28_apache-php_1
Creating mar28_phpmyadmin_1
```

### `docker-compose ps`
起動したことを確認します。
Stateが"Up"になっていれば成功です：

```bash
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose ps
       Name                 Command          State           Ports
---------------------------------------------------------------------------
mar28_apache-php_1   apache2-foreground      Up      0.0.0.0:80->80/tcp
mar28_mysql_1        /entrypoint.sh mysqld   Up      3306/tcp
mar28_phpmyadmin_1   /run.sh                 Up      0.0.0.0:8080->8080/tcp
```

### `docker-machine ip default`
ApacheとphpMyAdminに接続します。
`docker-compose ps`の結果を見ると、Apacheはポート80、phpMyAdminはポート8080で待ち受けているようです。
IPは**localhostではない**ので、以下のコマンドで確認します：

```bash
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-machine ip default
192.168.99.100
```

このIPアドレスをブラウザーに打ち込むか、以下のようなコマンドでブラウザーを起動します：

```bash
kazuma@PC MINGW64 ~/work/2016/mar28
$ start http://$(docker-machine ip default)/phpinfo.php

kazuma@PC MINGW64 ~/work/2016/mar28
$ start http://$(docker-machine ip default):8080/
```

以下のように、phpinfo()の画面と「phpMyAdminへようこそ」の画面が、それぞれ表示されれば成功です！

![160328 phpinfo small.png](https://qiita-image-store.s3.amazonaws.com/0/118759/e20452b3-8aa4-61f8-c222-93a3e64e5137.png)

![160328 phpMyAdmin small.png](https://qiita-image-store.s3.amazonaws.com/0/118759/391e7e0b-c6fe-07a4-c909-06265f7c8628.png)


## 立ち下げと後片付け
Dockerの持つ柔軟性のひとつに、環境を「使い捨て」できるというものがあります。
サーバーを停止し、実行中に生じた変更（ログファイル生成や、今回はしていませんがコンフィグの変更など）を破棄します。

### `docker-compose stop`
サーバーを停止します。

```bash
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose ps
       Name                 Command          State           Ports
---------------------------------------------------------------------------
mar28_apache-php_1   apache2-foreground      Up      0.0.0.0:80->80/tcp
mar28_mysql_1        /entrypoint.sh mysqld   Up      3306/tcp
mar28_phpmyadmin_1   /run.sh                 Up      0.0.0.0:8080->8080/tcp

kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose stop
Stopping mar28_phpmyadmin_1 ...
Stopping mar28_apache-php_1 ...
Stopping mar28_mysql_1 ...
[3Bping mar28_phpmyadmin_1 ... done
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose ps
       Name                 Command           State     Ports
-------------------------------------------------------------
mar28_apache-php_1   apache2-foreground      Exit 0
mar28_mysql_1        /entrypoint.sh mysqld   Exit 0
mar28_phpmyadmin_1   /run.sh                 Exit 137
```

Stateが"Exit"に変わりました。
先ほどのブラウザー画面を更新してみれば、サーバーが止まったことを実感できます。

### `docker-compose rm`
環境を捨てます。
`y`を入力して処理をすすめるか、はじめから`docker-compose rm -f`として強制削除します。

```bash
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose rm
Going to remove mar28_phpmyadmin_1, mar28_apache-php_1, mar28_mysql_1
Are you sure? [yN] y
Removing mar28_phpmyadmin_1 ...
Removing mar28_apache-php_1 ...
Removing mar28_mysql_1 ...
[2Bving mar28_apache-php_1 ... done
kazuma@PC MINGW64 ~/work/2016/mar28
$ docker-compose ps
Name   Command   State   Ports
------------------------------

kazuma@PC MINGW64 ~/work/2016/mar28
$
```

サーバー実行中に生じた変更は全て破棄されましたが、`docker-compose up -d`コマンドで同じ環境を再現できるので大丈夫です。
次の実行時は、イメージファイルをキャッシュしてあるので、初回より短時間で起動するはずです。


# ハンズオン手順（応用）
TBD: LAMP環境を複数立ち上げる


# まとめ
「XAMPP/MAMP以上の柔軟性」について説明できていないので、あと少し解説とエクストラの手順を追記する予定です。

また、この記事とは別で、Dockerfileを使ったMySQL、Apacheのカスタマイズと、WordPressのインストールを説明する予定です。



# リンク
[Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築 - Qiita](http://qiita.com/naga3/items/be1a062075db9339762d)
[Docker Composeを使ってLAMP環境を立ち上げる - Qiita](http://qiita.com/naga3/items/d1a6e8bbd0799159042e)