LaravelプロジェクトをLaradockに乗せた話

LaravelプロジェクトをDockerを使って動かすために必要となる機能をひとまとめにしてくれた[Laradock](https://github.com/laradock/laradock)というツールがあります。各サービス毎にコンテナを立ち上げる土台が用意されていて、環境変数を設定すれば欲しいものだけ立ち上げてくれる便利なものです。

会社の業務に直接的には関係ないですが、既存のLaravelプロジェクトをLaradockに乗せる機会があったので使い方を紹介します。Laravelプロジェクトの作り方については触れてません。

Dockerに関する基本的な知識があることを前提に書いています。

# 環境
自分が動かしている環境です。

| サービス | バージョン | 確認コマンド |
|:-------|:--------|:---------|
| Laravel | 5.5.34 | php artisan --verison |
| php, php-fpm | 7.2系 | php -v, php-fpm -v |
| mysql | 5.7.23 | mysql --version |
| nginx | 1.15.2 | nginx -V |

# 概要
本記事では下記について触れます。

- 基本的な使い方
- Laradockをgit submoduleを使って管理
- 他の人が使いやすくするために

# 基本的な使い方
Laradockは様々なツールをDockerコンテナで立ち上げるために必要な機能を用意しており、利用者が欲しいものだけ選択してコンテナを立ち上げる仕組みになっています。

参考までに代表的な対応サービスを挙げると
- Apache
- nginx
- MySQL
- Redis
- MariaDB
- Postgres
- MongoDB
- ElasticSearch
- HAProxy
- Selenium

などがあります。

これによりLaravelを使ったアプリケーションに必要な周辺環境を概ね実現することが可能です。

Laradockはそれらの豊富な機能をDocker Composeによって提供します。我々利用者はdocker-compose upする際に必要なコンテナを選ぶだけです。詳しく知りたい人は[ドキュメント](https://laradock.io/documentation/)を見てください。

非常に多くのツールに対応してるため、

```
docker-compose build
```
等と実行してしまうととても時間がかかります。一度作ってしまえばそれまでなのですが、必要なものだけ選択的にビルドするのが良いと思います。

## setup
まずはソースコードを持ってきます。Laravelプロジェクトのルートディレクトリでcloneして、laradockというディレクトリにいれておきます。

```
git clone https://github.com/laradock/laradock.git laradock
```

この中に様々なサービスのコンテナを立ち上げるための`Dockerfile`及び、`docker-compose.yml`等必要なファイルが格納されています。基本的には`docker-compose.yml`とその環境変数が定義されている`.env`が重要になります。

`docker-compose.yml`は`.env`というファイルに定義された環境変数を使うことができるため、Laradockではユーザ毎の設定を`.env`に持たせて、`docker-compose.yml`は変更しないで済む設計になっています。

レポジトリの中に`env-example`というサンプルファイルがあるため、

```
cp env-example .env
```
を実行することで利用可能になります。基本的な設定は入力済みなので、カスタマイズしたい項目を変更すればOKです。ちなみに`.env`は`.gitignore`で無視するように設定されているため、修正してもレポジトリに影響を与えません。

いくつか`.env`の設定項目を見てみます。

まずはLaradockに対するアプリケーションコードのルートディレクトリの場所です。

```text:.env
# Point to the path of your applications code on your host
APP_CODE_PATH_HOST=../
```

デフォルトでは相対パスで一つ上の階層に指定されています。ここは自由に変更できますが、意味するところとしては恐らく下記のようなディレクトリ構成を想定しているのではないかと思います。

```
laravel-project
├── laradock
│   ├── .env
│   ├── docker-compose.yml
├── app
...
```
個人的にもレポジトリを完全に別の場所に置くよりは、アプリケーションのプロジェクト内に配置した方がユーザ毎の環境に違いが生じないため良いと思います。(Laradockレポジトリのgit管理については後述します。)

次にPHPのバージョンを選択します。ここは各自必要なバージョンを指定しましょう。

```text:.env
# Select a PHP version of the Workspace and PHP-FPM containers (Does not apply to HHVM). Accepted values: 7.2 - 7.1 - 7.0 - 5.6
PHP_VERSION=7.2
```

最後にMySQLの設定を入れます。これはLaravelプロジェクトのルートにある.envに合わせて設定します。

```
MYSQL_VERSION=your_version
MYSQL_DATABASE=your_database
MYSQL_USER=your_user
MYSQL_PASSWORD=your_password
```

これで基本的な設定は完了です。

# コンテナを立ち上げる
大体設定できたはずなので、コンテナを立ち上げます。

今回のケースでは

- アプリケーションコードを配置するコンテナ
- php-fpmの動作コンテナ
- nginxの動作コンテナ
- mysqlの動作コンテナ

が必要です。

素直に考えると、

```
docker-compose up -d mysql nginx php-fpm workspace
```
を実行する必要があります。もちろんこれでも動きますが、コマンドを短くしたいなら下記でも大丈夫です。

```
docker-compose up -d mysql nginx
```
何故かと言うと、`docker-compose.yml`のnginxの項目で依存関係があるコンテナが指定されているため結果的に一緒に立ち上がることになるからです。

```
nginx:
  depends_on:
    - php-fpm

php-fpm:
  depends_on:
    - workspace
  links:
    - docker-in-docker
```

最終的にこうなります。（docker-in-dockerの役割は調べてない）
<img width="793" alt="スクリーンショット 2019-03-24 23.51.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/13766/972debdc-b5e1-74b9-d3f6-b9110d386226.png">

これで動かせる環境ができました。アプリケーションが正常であれば動くはずです。

# Laradockのレポジトリを管理する
動作はできましたが、一つ問題があります。
Laravelプロジェクトをgitで管理していた場合、別レポジトリから持ってきたLaradockが混入することになります。
うまいこと同じプロジェクトの階層の中で別で管理したいです。

そこでgit submoduleを使います。独立したgitレポジトリで管理されているものを、既存のgitレポジトリにいれる際に有効です。下記のコマンドを実行することで、laradockというディレクトリを 
https://github.com/laradock/laradock.git のレポジトリを管理するための場所として定義することができます。

```
git submodule add https://github.com/laradock/laradock.git laradock
```
コマンドが成功すると.gitmodulesというファイルができて、下記のような内容が入ってるはずです。

```text:.gitmodules
[submodule "laradock"]
        path = laradock
        url = https://github.com/laradock/laradock.git
```

この内容をcommitして、pushすれば他の人もsubmoduleの利用が可能になります。

# 他の人が使いやすくするために
## プロジェクト用の.envのサンプルを用意する
Laradockはそのプロジェクトの中で.envを管理しないため、人によってローカルに置いている.envの中身が異なる可能性があります。そこで、Laravelプロジェクトの中に設定ファイルのサンプルを作成してそれを使ってもらうことにしました。特に意識せずに設定が完了するので楽です。

```bash
cp my-env-example laradock/.env
```
## Makefileを用意する
Dockerで管理するとサービス毎にコンテナを建てられるので構築は楽ですが、Dockerコマンドを経由するため、何をすれば何がおきるのかを把握することが難しいです。

そこでコンテナの操作に関しては頻繁に使うものはMakefileにまとめています。そうするとコマンドにコメントを残せますし、Readmeにも「このコマンド打ってね」と書くだけで良いので便利です。

参考までにMakefileの一部を載せておきます。

```makefile:Makefile
setup: ## submoduleの更新とlaradock内に.envファイルを作成してbuild
	git submodule update -i
	cp my-env-example laradock/.env
	make build

restart: ## コンテナの再起動
	make stop
	make start

stop: ## コンテナの停止
	cd laradock; docker-compose down

start: ## コンテナの起動
	cd laradock; docker-compose up -d mysql nginx

build: ## コンテナのビルド
	cd laradock; docker-compose build mysql nginx workspace php-fpm
```

# 最後に
Laravelの開発環境を整える手間を簡略化できる素敵ツールを紹介しました。多機能故に全体像はつかみにくいですが、仕組みが分かればかなり利便性が高いと感じました。コンテナの使い方としても参考になる部分があるため、勉強のためにもう少し詳しく中を見てみるのも面白そうです。