DockerでPHP+MySQLの入門作ってみた

仕事関連コードのサーバCIをdockerで環境構築したので
自分なりに入門を作りました

# 簡単な専門用語の説明
### コンテナ
・ホストマシンから隔離された環境
・コンテナイメージから作成される
・docker-compose.ymlにコンテナ詳細と依存関係が記載
・docker-compose upでコンテナ構築＋起動
・docker psでコンテナ一覧表示
・docker start/stop/restartでコンテナの起動終了再起動

### コンテナイメージ
・コンテナを作成する元
・Dockerfileに内容を記載
・docker buildで構築
・docker imagesで一覧表示
・docker rmiで削除
・docker hubで検索するといい感じのやつがある

# 文字列を表示する簡単な鯖を構築する
バージョンを指定せず構築するなら簡単です
PHP+Apacheのコンテナイメージからコンテナを起動しましょう

#### docker-compose.yml
```yaml
services:
  sample_app:
    image: php:5.5-apache
    volumes:
      - ./html:/var/www/html
    ports:
      - 8000:80
    container_name: sample_app
```

#### html/index.php
```php5
<?php
echo "HelloWolrd!";
```

`php:5.5-apache` はdocker公式が提供しているPHP5.5＋Apacheのコンテナイメージです
このコンテナイメージを使ってコンテナ構築するだけでサーバが構築できるので簡単ですね
imageのところはdocker hubから検索するといいです。tagsからバージョン指定もできます

あとは `docker-compose up -d` すれば
docker hubからコンテナイメージをpull→コンテナ構築→コンテナ起動
まで自動でやってくれます
dオプションはバックグラウンド起動オプションです

http://localhost:8000
にアクセスすると「HelloWorld!」と表示されます

`docker ps` と打つとsample_appコンテナが起動してるのが確認できます

おめでとうございます！


```shell
$ docker ps
CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS          PORTS                  NAMES
211a18290243   php:5.5-apache      "apache2-foreground"     54 seconds ago   Up 54 seconds   0.0.0.0:8000->80/tcp   sample_app
```

`docker images`と打つとphp:5.5-apacheのコンテナイメージ一覧が確認できます

```shell
$ docker images
REPOSITORY                   TAG          IMAGE ID       CREATED       SIZE
php                          5.5-apache   ea0a3d41ce6c   4 years ago   390MB
```

ただこんなシステム構築しても面白くないですよね
WEBサーバならDBも用意したいところです
DBコンテナも起動しましょう

# DBにデータを取得するサーバを構築する
まずはmysqlコンテナを追加して
初期データを投入、
index.phpからアクセスまで行います

#### docker-compose.yml
```yaml
services:
  sample_app:
    image: php:5.5-apache
    volumes:
      - ./html:/var/www/html
    ports:
      - 8000:80
    container_name: sample_app
  sample_db:
    image: mysql:5.6
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    volumes:
      - ./sample_db/initdb:/docker-entrypoint-initdb.d # ここに配置するとコンテナ構築時に実行してくれる
    container_name: sample_db
```

#### sample_db/initdb/init.sql
```sql
-- DB作成時に実行されるファイル
create table test.test (text text);
insert into test.test values ('first'),('second'),('third');
```

#### html/index.php
```php5
<?php
$dbh = new PDO('mysql:host=sample_db;dbname=test', 'root', 'root');
foreach ($dbh->query('select * from test') as $row) {
  echo $row['text'] . '<br/>';
}
```

これで設定変更完了。コンテナイメージ・コンテナを再構築します

```shell
# コンテナを停止・削除
docker-compose down --remove-orphans
# コンテナを構築・起動
docker-compose up -d
```

mysql5.6コンテナイメージをpullしてきてdbコンテナを構築・起動してくれます
初期データも構築時に投入してくれます

http://localhost:8000 にアクセスしてみましょう

```
Fatal error: Uncaught exception 'PDOException' with message 'could not find driver' in /var/www/html/index.php:2 Stack trace: #0 /var/www/html/index.php(2): PDO->__construct('mysql:host=samp...', 'root', 'root') #1 {main} thrown in /var/www/html/index.php on line 2
```

PDOエラーがでます
実はphpからmysqlにアクセスするにはpdo_mysqlが必要です

しかしphpはphp:5.5-apacheコンテナイメージから提供されているので
docker-compose.ymlでは手を入れれません

sample_appコンテナにpdo_mysqlを入れるには2通りの方法があります

１つ目はpdo_mysql込みのコンテナイメージからコンテナを作る
２つ目は既存コンテナイメージにpdo_mysqlをインストールする

2つ目のほうが融通が効くので、2つ目にお世話になることが多いと思います
今回は2つ目の方法を記載します

#### sample_app_image/Dockerfile
```dockerfile
FROM php:5.5-apache

RUN apt-get -y update && apt-get -y upgrade \
  && docker-php-ext-install pdo_mysql
```

Dockerfileにインストール手順を記載し、

#### docker-compose.yml
```yaml
services:
  sample_app:
    build:
      context: ./sample_app_image
      dockerfile: Dockerfile
    image: sample_app
    volumes:
      - ./html:/var/www/html
    ports:
      - 8000:80
    container_name: sample_app
  sample_db:
    image: mysql:5.6
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    volumes:
      - ./sample_db/initdb:/docker-entrypoint-initdb.d # ここに配置するとコンテナ構築時に実行してくれる
    container_name: sample_db
```

docker-compose.ymlにビルド先を記述します
あとはコンテナを再起動

```shell
# コンテナを停止・削除
docker-compose down --remove-orphans
# コンテナを構築・起動
docker-compose up -d
```

ビルドに成功すると以下のページで「First Second Thrid」と表示され
DBからデータを取得できているのが確認できます

http://localhost:8000

おつかれさまでした


# Q&A
Q. Dockerfileのapt-getとか作るのめんどい。環境削除と再構築に時間かかる
A. コンテナ内にログインして実際に打ってみて成功したらDockerfileに書くのが効率いいです

```shell
$ docker exec -it sample_app bash
```

Q. コンテナ内のログを見たい
A. logs使えば簡単に見れるよ

```shell
$ docker logs sample_app
```

Q. PHP5.5とか糞雑魚ｗｗｗセキュリティサポート終了してんぞｗｗｗ
A. 仕事で使ってんだくそｇ