docker - ローカル開発環境の構築 / Laravel on [ [Vagrant + VirtualBox] with Docker ]

# はじめに

Webアプリケーションの開発は、ローカル開発環境の構築手段の選択肢が増えたことによって、ここ10年ほどでかなり効率的に開発を行うことができるようになりました。

2000年代までは、オンプレサーバやレンタルサーバ上に共有の開発サーバを手配し、開発者がリモートからアクセスして開発・テストし、SVNでソースコードを管理することが多かったのではないかと思います。

しかし近年では、 **Infrastructure as Code** の流れから、インフラの設定をコードで定義し、かつそれらを本番や開発に関係なく持ち回れるようにすることで、各環境の構築に関する膨大なサポート作業を効率化し、アプリケーションを開発するまでの手間が大きく削減されました。（自動化する為の技術を覚える手間は増えました。）

私の所属するチームでは **Vagrant + VirtualBox** が基本構成なのですが、近頃はその上に Docker を乗せることで、構築＆再構築の手間を省いたり、Docker を直接、ホストOSに乗せることによる課題（Windows 10 Pro じゃないと駄目だとか、Windows と Mac の Dockerの構築手順の違いだとか）を解決したりするのが流行りのようです。

この記事は、Docker初心者の私が Vagrant + VirtualBox の上に Laravel と MySQL を稼働させる為の Dockerコンテナ をイイ感じに構築する為の備忘録です。

# 想定環境

今回は ホストOS に関係なく利用できることを目標にしているため、 **Vagrant + VirtualBox** をインストールする OS は、 Windows でも Mac でも、どちらでも構いません。

- OS : Windows / macOS
- 仮想環境 : [VirtualBox](https://www.virtualbox.org/) + [Vagrant](https://www.vagrantup.com/)

なお、本文中では、 **Vagrant + VirtualBox** は既にインストールされている状態を想定しています。

# 構築手順

## 概要

今回構築する環境は、 CentOS/7 の上に、 Docker をインストールし、その上で各種アプリケーションを実行させます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79222/d37dd002-14b4-4a3e-cce4-bec849f9753f.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79222/0de80a3b-71e4-7d15-aa96-291834489795.png)


## 手順

### 1. CentOS7 の起動

ホストOS 上で以下のコマンドを実行することで、 Docker と docker-compose が入った CentOS 7 を構築します。

```bash:@HostOS
// Vagrant のプラグインをインストールする
$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-proxyconf

// GitHub から Vagrantfile と provision.sh を取得する
$ git clone https://github.com/anfangd/docker-on-vagrant-script.git
$ cd docker-on-vagrant-script

// Vagrant の起動する
$ vagrant up

// 仮想環境へ ssh でアクセスする
$ vagrant ssh
```

起動した仮想環境内で、 Docker と docker-compose をコマンド操作できるか確認します。

```bash:@VirtualOS
// docker の動作確認をする
$ docker run hello-world

// docker のバージョン確認をする
$ docker --version
Docker version 18.06.1-ce, build e68fc7a

// docker-compose のバージョン確認をする
$ docker-compose --version
docker-compose version 1.17.1, build 6d101fb
```

- [centos/7 Vagrant box](https://app.vagrantup.com/centos/boxes/7)
- [Vagrant: vagrant-vbguest プラグインで仮想マシンの Guest Additions を最新に保つ - https://blog.amedama.jp/entry/2015/08/19/204044](https://blog.amedama.jp/entry/2015/08/19/204044)
- [dotless-de/vagrant-vbguest - GitHub](https://github.com/dotless-de/vagrant-vbguest)
- [vagrant-proxyconf で行う ゲストOSへのかんたんProxy設定 - WEB ARCH LABO](https://weblabo.oscasierra.net/vagrant-proxyconf/)
- [tmatilai/vagrant-proxyconf - GitHub](https://github.com/tmatilai/vagrant-proxyconf)

### 2. Laravel の導入

仮想環境内で、 Laravel + MySQL + nginx を dockerコンテナ にインストールする為のスクリプトを取得し、ビルド、実行することで、 Laravel を導入します。

```bash:@VirtualOS
// HostOS とファイル同期が取れるよう、 /vagrant へ移動
cd /vagrant

// GitHub から docker-compose 用の スクリプトを取得する
git clone https://github.com/anfangd/docker-compose-php-laravel.git dc-laravel && cd $(basename $_ .git)

// 取得したスクリプトをビルドして、docker-compose で コンテナを起動する
$ docker-compose build
$ docker-compose up -d

// laravel でプロジェクトを作成する
$ docker-compose exec php laravel new laravel-src

// 作成したプロジェクトの storage に書き込み権限をつける
$ docker-compose exec php chmod -R 777 ./laravel-src/storage

// MySQL への接続情報を変更する
$ vim src/laravel-src/.env
```

Laravel から MySQL へ接続する為に、 .env を更新します。

```bash:src/laravel-src/.env
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=root
DB_USERNAME=root
DB_PASSWORD=root
```

マイグレーションを行います。

```bash:
// マイグレーションを行う
$ docker-compose exec php php ./laravel-src/artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

```

### 3. 接続確認

以下の URL から接続を確認します。

- http://192.168.33.10:8080/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79222/0d6ad442-032c-d2d2-b28a-8d386e72ef50.png)

この画面を確認することが出来たら、初期構築は完了です。

### 4. AdminLTE の導入（追記）

ついでなので、 AdminLTE を入れてみます。
以下の要領で簡単に、AdminLTE を組み込む事ができます。

```bash:@php/DockerContainer
$ pwd
/src/laravel-src/

$ composer require jeroennoten/laravel-adminlte
// 以下と同じ
// docker-compose exec php composer require jeroennoten/laravel-adminlte
```

ただし、上記の手順で終わりではなく、これからいくつか設定を追加してゆきます。

まずは、アプリの設定ファイルに AdminLTE の設定を追加します。

```php:config/app.php
    'providers' => [
    // 中略
    JeroenNoten\LaravelAdminLte\ServiceProvider::class,
```

次に、Laravel　が提供する artisan コマンドでいくつかのファイルを作成します。

```bash:@php/DockerContainer
// assets のコピー
$ php artisan vendor:publish --provider="JeroenNoten\LaravelAdminLte\ServiceProvider" --tag=assets

// AdminLTE 用の設定ファイルを作成
$ php artisan vendor:publish --provider="JeroenNoten\LaravelAdminLte\ServiceProvider" --tag=config

// AdminLTE のテンプレートをカスタムするビューを作成
$ php artisan vendor:publish --provider="JeroenNoten\LaravelAdminLte\ServiceProvider" --tag=views
```

最後に、以下のファイルを記載の通り修正します。

```php:resources/views/welcom.blade.php
<!-- adminlte::page Inheritance -->
@extends('adminlte::page')

<!-- read page title -->
@section('title', 'Dashboard')

<!-- read page header -->
@section('content_header')
  <h1>Dashboard</h1>
@stop

<!-- read main content -->
@section('content')
  <p>Welcome to this beautiful admin panel.</p>
@stop

<!-- read css -->
@section('css')
  <link rel="stylesheet" href="/css/admin_custom.css">
@stop

<!-- read js -->
@section('js')
  <script> console.log('Custom javascript'); </script>
@stop
```

以上の操作が終わったら、以下にアクセスしてみてください。

- http://192.168.33.10:8080/

AdminLTE のUI を確認できるはずです。

Laravel 初心者の方は、今回作った環境をベースに以下の記事を真似て操作してみると、 Laravel の基本的なお作法を感じることが出来ますのでお試しください。

- [はじめてのLaravelアプリケーションガイド - Qiita](https://qiita.com/Fendo181/items/dece727ea402552fee19)

ここ最近は、 **Laravel on Docker on Vagrant** の構成が流行っているのか、文献が多くありました。
ただし、いくつか試してみましたが、 Laradock などはインストール時に非常に重かったので、今回はミニマム構成で構築出来るであろう記事をベースに、少しカスタムして作ってみました。

また、 AdminLTE については、コマンドで導入する以外の記事が多かったですが、 artisan コマンドで いい感じに組み込む手順を公開されていた方がいたので、参考（というか、引用）をさせて頂きました。

# 課題

1. http アクセスが遅い<br>　→　Vagrant の sync_folder 設定が悪さをしてresponse が遅いです<br>　→　rsync設定などを試してますが、せっかくの開発環境なのに、ソースの変更がリアルタイム同期されず残念なことになります。

Vagrant で **HostOS <--> VirtualOS** で **フォルダ／ファイル同期** する仕組みは非常に便利ですが、VHost 上だと npm がうまく行かなかったり、アクセスが遅くなったりと、見つけづらいところで影響してくるので要注意です。

# 終わりに

Vagrant の sync_folder まわりにかなり泣かされました。
このあたりの文献はあまり数が無いようなんですが、皆さんどうしているんでしょう。

Docker/docker-compose については、参考に記載した「さくらのナレッジ」の記事が非常に分かりやすく、コマンドでトレース出来るあたりも大変助かりました。

Laravel は久しぶりに触りましたが、以前より盛り上がりを見せて記事も充実してきているので、エントリレベル越えたくらいの人なら、 Laravel は良い選択かもしれません。

# 参考

## 単語

- Docker
- docker-compose
- vagrant
- VirtualBox
- Laravel
- Laradock

## 環境を構築する

本記事の作成にあたっては、以下の記事を参考にさせて頂きました。

- [centos7を起動してすぐDockerできるVagrantfile - Qiita](https://qiita.com/suzu2469/items/00afb144a03cb3a0d262)
- [VirtualBox+Vagrantで楽々Docker環境構築（Windows） -Qiita](https://qiita.com/mikoski01/items/7ed36ac9e402658bb93e)
- [LaravelをLaradockを使わずにDocker環境で開発 - Qiita](https://qiita.com/acro5piano/items/e834f44259c607d93086)
- [Vagrant・CoreOS・Dockerでインフラ素人が自宅サーバを立てた話 - Qiita](https://qiita.com/y_hokkey/items/3dd0d8f20f9daadbbf0b)
- [dockerとvagrantの違い言える？新人エンジニアでも分かった気になれる俺流まとめ - This is a pen](http://acchi-muite-hoi.hatenablog.com/entry/2016/05/30/041618)
- [Dockerでlaravel環境構築(php-fpm,nginx,mysql,redis) - Qiita](https://qiita.com/meidaimae/items/1b5902e2e520ece34b9a)
- [Laravel+MySQL+NginxでさくっとDocker開発立ち上げる - Qiita](https://qiita.com/bboobbaa/items/67bd9e74d7805516e68d)
- [Dockerでいい感じにPHP(Laravel)のローカル開発環境を作る - Qiita](https://qiita.com/IganinTea/items/aec8f2b15b203946a2c4)
- [Docker で MySQL 8.0.4 を使う - Qiita](https://qiita.com/yensaki/items/9e453b7320ca2d0461c7)
- [docker-cmpose buildでnode.jsのインストール時にエラー - Qiita](https://qiita.com/hrkbyc/items/48fb6ee6055d60367d7c)

## Laravel に AdminLTE を導入する

- 引用：[【Laravel × AdminLTE】AdminLTE をインストールして使ってみる - ブロックチェーンエンジニアのブログ](https://daiki-sekiguchi.com/2018/08/18/laravel-adminlte-install/)

## Docker について学ぶ

Docker から学びたい人は以下のサイトを手を動かしながら読むと良いと思います。

- [Docker入門（第一回）～Dockerとは何か、何が良いのか～ - さくらのナレッジ](https://knowledge.sakura.ad.jp/13265/)
- [Docker入門（第二回）～Dockerセットアップ、コンテナ起動～ - さくらのナレッジ](https://knowledge.sakura.ad.jp/13795/)
- [Docker入門（第三回）～各種dockerコマンドとDockerイメージ作成について～ - さくらのナレッジ](https://knowledge.sakura.ad.jp/14427/)
- [Docker入門（第四回）～Dockerfileについて～ - さくらのナレッジ](https://knowledge.sakura.ad.jp/15253/)
- [Docker入門（第五回）〜コンテナ間通信〜 - さくらのナレッジ](https://knowledge.sakura.ad.jp/16082/)
- [Docker入門（第六回）〜Docker Compose〜 - さくらのナレッジ](https://knowledge.sakura.ad.jp/16862/)

## Vagrant について

Vagrant の役割については以下を参照ください。

- [「Vagrant」と「Virtual Box」の違い - Qiita](https://qiita.com/andrew954/items/1d9f460558da7b84768f)
- [Vagrantって流行ってるらしいけど何が便利なの？ - Developers.IO](https://dev.classmethod.jp/server-side/virtual-box-vagrant/)

## php-fpm について

Apache 使い には聞き慣れない（かもしれない） php-fpm についてはこちらを参照ください。

- [nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する - Qiita](https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)
- [調べなきゃ寝れない！と調べたら余計に寝れなくなったソケットの話 - Qiita](https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)