DockerとVirtualBoxでLAMP環境をサクッと構築する

#はじめに
Dockerに興味あるけど結局何ができるの？…という初心者向けに、備忘録も兼ねて投稿します。
30分でLAMP環境を構築することを目標に進めていきます。
Windows向けですが、基本的にMacでも同じようにできると思います。

##え、XAMPPとかMAMPはダメなの…？
↑みたいなことを自分でも思っていましたが、結局デプロイするときDocker使っていた方が楽なのに気づきました。
開発環境からDockerでやっていればサクッと本番環境を構築できるのがありがたいです。
Docker Composeを使えば、起動設定まで自動化できるのでありがたい。
なので共有します。
※本記事ではやりませんが、SSL化もコンテナを使えば簡単に済みます。
というわけで、いずれプロダクトを公開するんだという予定のある方におすすめします。

##環境
**使用OS** Win10 64bit

##使用するもの

**1.Docker Toolbox**
これをインストールするだけで
```Docker-machine```
```Docker```
```VirtualBox```
```ターミナル```
これらが手に入り、サクッと導入できるので今回はこれでいきます。

**2.Docker-machine**
これはDockerがインストールされたDockerホスト（本記事ではVirtualBoxが提供する仮想マシーン）を作成してくれます。

**3.VirtualBox**
これは仮想環境を提供してくれるもの。Dockerホストの実体はここにあります。ですがDockerホストは基本的にdocker-machineコマンドによって接続するので今回では共有フォルダの設定くらいでしか触りません。

**4.Docker Quickstart Terminal**
いわゆるターミナルです。ここからDocker-machineやDockerなどのコマンド操作していきます。

**5.テストアプリ**
環境だけ構築しても寂しいので、LAMPで動かすテストアプリを用意しておきました。
これはGitHubからクローンしてご利用ください。

##前提知識
**ホストマシーン**
今回の場合はWinマシーンです。ここからdocker-machineコマンドを使用して、DockerホストへとSSH接続します。

**Dockerホスト**
今回はVirtualBoxが提供する仮想マシーンです。Docker-machineによって、ここにDockerがインストールされてDockerコマンドはここで使用していくことになります。
今回はテスト環境なのでVirtualBox内の仮想マシーンですが、本番環境時ではあなたが用意したサーバになったりするでしょう。

**Dockerイメージ**
ざっくり言うとコンテナの元になるもの。
基本的なものはDocker Hubがだいたい用意してくれている。
カスタマイズしたい場合はDockerfileでビルド。

**Dockerコンテナ**
Dockerイメージから起動する軽量な仮想マシーン。
Docker Hubから公式イメージをダウンロードしてきて、Dockerfileで好みのイメージをビルド→目当ての機能をDockerコンテナで実現を自分はよくやります。

**Dockerfile**
Dockerイメージを自分好みに改造するもの。

**Docker Compose**
サービスの稼働には、Dockerイメージのビルドに加え、コンテナの起動設定もしなくてはなりません。
イメージのビルドはDockerfileがしてくれるのに対して、コンテナの起動設定はこれが担ってくれます。手動でターミナルからコマンドを打つ方法もありますが毎回やるのは手間なので便利です。

##構築の手順
**1.Docker Toolboxをインストールする**
[こちら](https://docs.docker.com/toolbox/toolbox_install_windows/)からダウンロードしてください。自分がWindowsなのでWin版でやります。
<img width="949" alt="スクリーンショット 2019-09-03 23.03.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491142/edb83a53-9124-3028-e9cc-11b8d4c9222c.png">
↑画像の青文字になってる ```Toolbox Releases``` からゲットできます。

**2.Docker Quickstart Terminalを起動する**
無事にインストールできたらDocker Quick Terminalというものがデスクトップにあると思います。起動してください。

**3.GitHubからテストアプリをクローン**
[ こちら ](https://github.com/ke-hamamoto/build_machine_vbox)からクローンしてきたものは適当なところに置いておいてください。

**4.VirtualBoxの共有フォルダを設定する**
↓画像のようになってDocker Quickstart Terminalが立ち上がっていることが確認できたら、VirtualBoxを起動してください。
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491142/785a51ce-e268-2744-e952-f3e53ade59a4.jpeg)
VirtualBoxを起動するとDockerホストであるdefaultというマシーンが起動しているので、そのマシーンの共有フォルダを設定してください。
↓例
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491142/5b007487-599a-ce1e-dcd5-24aeaef7cccc.jpeg)

**5.defaultマシーンを再起動する**
共有フォルダの設定を有効にするため、Docker Quickstart Terminalに戻ってdefaultマシーンを再起動してください。

```terminal:Docker_Quickstart_Terminal
$ docker-machine restart default
```

**6.DockerホストのIPアドレスを確認する**
Dockerホストdefaultの再起動が完了したら、ホストのIPアドレスを確認します。
MAMPのようにlocalhostでは繋がりませんのでここで確認してください。

```terminal:Docker_Quickstart_Terminal
$ docker-machine ip default
```

**7.configファイルの編集**
万が一IPアドレスが ```192.168.99.100``` ではないものが出てしまった場合は残念ながら、configファイルの設定をする必要があります。
**※通常なら ```192.168.99.100``` が割り振られるはずなので、当てはまらなかった人は飛ばしてください。**

configファイルはGitHubからクローンしてきた中の

```
app_test/project/app_server/test_app/js/config.js
```
```
app_test/project/app_server/test_app/config.php
```
以上が該当します。
DockerホストのIPが記述されているので、そこをあなたが確認したIPへと編集してください。

```js:config.js
var FQDN='http://192.168.99.100';//<-ここを変える
var TIMEOUT=30000;
```
```php:config.php
<?php
define('FQDN','http://192.168.99.100');//<-ここを変える
define('DBHOST','mysql');
define('DBPASS','00000');
```

**8.Dockerホストに接続**
ここまでの作業が完了したら、DockerホストへとSSH接続します。

```terminal:Docker_Quickstart_Terminal
$ docker-machine ssh default
```

**9.フォルダが共有されているか確認する**

```terminal:Docker_Quickstart_Terminal
$ ls 自分が設定したパス
```

クローンしたapp_testなりディレクトリが存在していれば大丈夫です。

**10.Docker Composeの存在を確認する**
Dockerホストに入ったことを確認したら、まず ```docker-compose.yml``` があるところへ移動しましょう。
共有先のフォルダを

```
/home/docker/app_test
```
と設定している場合は

```terminal:Docker_Quickstart_Terminal
$ cd /home/docker/app_test/project
```
でいけます。この辺のパスは自分の設定したものにしたがってください。
該当ディレクトリのprojectへ移動したら↓

```terminal:Docker_Quickstart_Terminal
$ docker-compose -v
```
上記でDocker Composeがインストールされているか確認してください。
おそらく「そんなもの何もない」と言われると思います。
どうやらWin版のDocker ToolboxではDocker Composeまでは用意してくれないようです。Mac版なら用意されていると思います。

**11.Docker Composeをインストールする**
projectディレクトリに移動できているなら ```compose-install.sh``` があるはずです。これを実行すればDocker Composeを手に入れることができます。
**※Docker Composeが入っていた方は飛ばしてください。**

```terminal:Docker_Quickstart_Terminal
$ sudo ./compose-install.sh
```

正常に終了したら再び↓

```terminal:Docker_Quickstart_Terminal
$ docker-compose -v
```
バージョンが表示されたらオッケーです。

**12.環境をビルドする**

下準備が終わったので、Docker Composeでいよいよビルドします。

```terminal:Docker_Quickstart_Terminal
$ sudo docker-compose up -d
```

結構時間かかるのでしばらくお待ちください。
ちなみに今回のdocker-compose.ymlはこんな感じです。

```yml:docker-compose.yml
version: '3.7'
services:

  app_server:
    build: ./app_server
    image: app_server
    container_name: app_server
    init: true
    volumes:
      - ./app_server/test_app:/var/www/html/test_app
      - ./app_server/favicon/favicon.ico:/var/www/html/favicon.ico
      - ./https_portal/ssl_certs:/var/ssl_certs
      - ./app_server/phpconf/php.ini:/usr/local/etc/php/php.ini
    tty: true
    stdin_open: true
    command: bash -c 'forever start /var/www/html/test_app/mod/app.js && apache2-foreground'
    ports:
      - '80:80'
      - '8080:8080'

  mysql:
    build: ./mysql
    image: mysql:5.7
    container_name: mysql
    init: true
    volumes:
      - ./mysql/app_data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d
    command: '--innodb_use_native_aio=0'
    environment:
      - MYSQL_ROOT_PASSWORD=00000

  myadmin:
    image: phpmyadmin/phpmyadmin
    container_name: myadmin
    init: true
    environment:
      - PMA_HOST=mysql
    ports:
      - '8000:80'
```

ミソは

```yml:docker-compose.yml
    command: bash -c 'forever start /var/www/html/test_app/mod/app.js && apache2-foreground'
```
app_serverのcommandの記述です。nodeとapacheの同時起動…ここちょっとはまりました。

↓WEBサーバー用のdockerfile

```dockerfile:app_server/dockerfile
FROM php:7.2-apache
RUN curl -L git.io/nodebrew | perl - setup && \
export PATH=$HOME/.nodebrew/current/bin:$PATH && \
nodebrew install v8.9.4 && nodebrew use v8.9.4 && \
npm install -g forever && \
ln -s /root/.nodebrew/node/v8.9.4/lib/node_modules/forever/bin/forever /usr/local/bin/forever && \
cd /root/.nodebrew/current/bin && \
ln -s $PWD/nodebrew /usr/local/bin/nodebrew && \
ln -s $PWD/node /usr/local/bin/node && \
ln -s $PWD/npm /usr/local/bin/npm && \
ln -s $PWD/npx /usr/local/bin/npx
RUN docker-php-ext-install pdo_mysql mysqli mbstring exif fileinfo
```

↓DB用のdockerfile

```dockerfile:mysql/dockerfile
FROM mysql:5.7
ADD ./sqlconf/_my.cnf /etc/mysql/my.cnf
RUN chmod 644 /etc/mysql/my.cnf
```

**13.ブラウザで確認する**
configファイルに設定したIPアドレスを参照してブラウザで確認してください。
正常にビルドが完了して特にconfigをいじらなかった場合は以下のアドレスで確認できるはずです。

```
http://192.168.99.100/test_app/
```
ログイン画面が表示されたら完了です！
おつかれさまでした。

##補足
**コンテナの停止と削除**

```terminal:停止コマンド
$ docker-compose stop
または
$ docker stop コンテナ名
コンテナ名は
$ docker ps -a
または
docker-compose.ymlのcontainer_name
で確認できます
```
```terminal:削除コマンド
$ docker-compose rm
または
$ docker rm コンテナ名
```

**phpMyAdminに接続**

```
http://192.168.99.100:8000
```
```
ID:root
Pass:00000
```
これで入れます。

**テストアプリの構成**
![Test_App.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491142/00da0237-3180-3149-f391-42218062500a.png)

#まとめ
今回と同じような流れで本番環境にもデプロイできます。
以上、ありがとうございました。