DockerでLaravel+PHP5.6+MySQL5.6+Apacheの環境構築

# 環境情報

## ホスト

* macOS Sierra
* Docker for Mac

## 目指す構成

* Apache
* MySQL(Ver.5.6)
* PHP(Ver.5.6)

ホスト側には、phpがなくても動作させられるようにする。

## コンテナの構成

|種類 |docker hub                     |コンテナ、タグ|
|:--  |:--                            |:--           |
|PHP  |https://hub.docker.com/_/php/  |php:5.6-apache|
|MySQL|https://hub.docker.com/_/mysql/|mysql:5.6     |

※MySQL用のデータコンテナは、MySQLと同じものをベースに利用する。

# 最終的なファイル構成

```
project
├── Dockerfile
│     config
│     └── apache2
│         └── sites-available
│             ├── 000-default.conf
│             └── default-ssl.conf
├── docker-compose.yml
└── laravel-app
     └── laravelのアプリを配置
```

※MySQLコンテナのように、起動時に、Apacheの設定を変更する方法は調査できず。

# Apache設定ファイルを取得・変更

``` shell
% mkdir -p config/apache2/sites-available
% cd config/apache2/sites-available
% docker run --name php-apache-tmp php:5.6-apache true
% docker cp php-apache-tmp:/etc/apache2/sites-available/000-default.conf .
% vi 000-default.conf
差分は以下。
-  DocumentRoot /var/www/html
+  DocumentRoot /var/www/html/public

% docker cp php-apache-tmp:/etc/apache2/sites-available/default-ssl.conf .
% vi default-ssl.conf
差分は以下。
-    DocumentRoot /var/www/html
+    DocumentRoot /var/www/html/public

% docker rm php-apache-tmp
```

# Dockerfileの作成

``` :Dockerfile
FROM php:5.6-apache

# PHPのインストール
RUN apt-get update \
    && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
        openssl libssl-dev \
        libxml2-dev \
    && docker-php-ext-install -j$(nproc) iconv mcrypt pdo_mysql mbstring xml tokenizer zip \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd

# apacheのrewriteを有効にする
RUN cd /etc/apache2/mods-enabled \
    && ln -s ../mods-available/rewrite.load

# composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get install -y git && composer global require "laravel/installer=~1.1"

WORKDIR /var/www/html
```

# docker-compose.ymlの作成

``` :docker-compose.yml
laravel:
  container_name: laravel
  build: .
  ports:
   - "80:80"
  environment:
    # bargeでは、/usr/local/binも追加しておかないと起動できない。
    PATH: ${PATH}:/usr/local/bin:/root/.composer/vendor/bin
  volumes:
    - ./laravel-app:/var/www/html
    - ./config/apache2/sites-available:/etc/apache2/sites-available
  links:
    - laravel-db

laravel-db:
  image: mysql:5.6
  container_name: laravel-mysql5.6
  command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --init-connect="SET NAMES utf8" --innodb_file_per_table=1 --innodb_file_format=BARRACUDA
  environment:
    MYSQL_ROOT_PASSWORD: rootpassword
    MYSQL_DATABASE: laravel
    MYSQL_USER: local
    MYSQL_PASSWORD: password
  ports:
    - "13306:3306"
  volumes_from:
    - laravel-dbdata

laravel-dbdata:
  image: mysql:5.6
  container_name: laravel-mysql5.6-dbdata
  command: echo "Data-only container for laravel MySQL5.6"
```

### 参考

上記`docker-compose.yml`をdockerコマンドにすると下記になる。

``` shell
# MySQL用データボリュームコンテナの起動
% docker run --name laravel-mysql5.6-dbdata mysql:5.6 echo "Data-only container for mysql5.6"

# MySQLの起動
% docker run -d --name laravel-mysql5.6 -e "MYSQL_ROOT_PASSWORD=rootpassword" -e "MYSQL_DATABASE=laravel" -e "MYSQL_USER=local" -e "MYSQL_PASSWORD=password" -p 13306:3306 --volumes-from laravel-mysql5.6-dbdata mysql:5.6 --character-set-server=utf8 --collation-server=utf8_general_ci --init-connect="SET NAMES utf8" --innodb_file_per_table=1 --innodb_file_format=BARRACUDA

# LaravelAppサーバの起動
% docker run -d --name laravel -e "PATH=${PATH}:/root/.composer/vendor/bin" -p 80:80 --link laravel-mysql5.6:laravel-mysql5.6 -v "$(pwd)"/laravel-app:/var/www/html -v "$(pwd)"/config/apache2/sites-available:/etc/apache2/sites-available laravel_laravel
# もしくは下記
% docker run -d --name laravel -e "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.composer/vendor/bin" -p 80:80 --link laravel-mysql5.6:laravel-mysql5.6 -v "$(pwd)"/laravel-app:/var/www/html -v "$(pwd)"/config/apache2/sites-available:/etc/apache2/sites-available laravel_laravel
```

## buildして起動

``` shell
% docker-compose build
% docker-compose up
```

# Laravelプロジェクトの生成

``` shell
% docker-compose run laravel laravel new sample-app
% mv sample-app laravel-app
```

下記URLにアクセスしてlaravelの画面が表示されるか確認する。

  * http://127.0.0.1:80/

## 開発時によく使いそうなコマンド(メモ)

``` shell
% docker-compose run laravel composer install
% docker-compose run laravel php artisan key:generate
% docker-compose run laravel php artisan migrate
```

## MySQLの設定

``` shell
% docker exec -it laravel env | grep MYSQL
<省略>
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_ENV_MYSQL_PASSWORD=password
MYSQL_ENV_MYSQL_USER=local
MYSQL_ENV_MYSQL_DATABASE=laravel
<省略>

% cp .env.sample .env
% vi .env
上記確認したMySQLの値を設定
```

# その他メモ

コンテナのターミナルに入る。

  * 実行中のコンテナに入るには、execを使用する。
  * 未実行のコンテナに入るには、runを使用する。

``` shell
% docker run --rm -it php:5.6-apache /bin/bash
% docker run --rm -it mysql:5.6 /bin/bash
% docker exec -it laravel /bin/bash
% docker exec -it laravel-mysql5.6 /bin/bash
```

どのコンテナにも紐付いていないvolumeの一覧を見る、又は削除する。

``` shell
% docker volume ls -qf "dangling=true"
% docker volume ls -qf "dangling=true" | xargs docker volume rm
```