テックブログ

  1. Docker
  2. 498 view

Laravelの環境(Nginx+MySQL+PHP)をdocker-composeでイチから作るチュートリアル

はじめに

Laravelのローカル環境構築方法には、Laravel HomesteadLaradockを使った方法などがありますが、本記事ではdocker-composeを使った方法を一から解説します。Dockerの仕組みにも触れながら、Laravel5.7をLEMP環境(Nginx+MySQL+PHP-FPM)で動かす方法を紹介します。
Docker Composeで環境構築をできるようになるとLaravelに限らず様々なWebフレームワークをモダンな環境で瞬時に立ち上げられるようになるので、ぜひマスターしてください!

構築の流れ

まずは、大まかな方針をまとめておきます。以下の手順で進めていきます。

1. Nginxで静的コンテンツ配信サーバを立ち上げる

2. 1で立てたNginxでPHPが動作するようにする

3. MySQLを立ち上げる

4. Laravelをインストールする

5. インストールしたLaravelを3で立ち上げたMySQLと接続する

全手順を省略せずに書いたつもりですが、全体のソースコードをgithubに用意したのでわからないところがあったら、ぜひ参考にしてください。

ソースコードはこちら

Nginxの構築

まずは本プロジェクトの起点となるフォルダを作成します。本記事では laravel-docker-workspace とします。

mkdir laravel-docker-workspace

cd laravel-docker-workspace

以下のような構成でNginxによるWebサーバを立ち上げます。

.
├── docker/
│   └── web/
│       └── default.conf # Nginxの設定ファイル
│
├── docker-compose.yml
└── index.html # 配信する静的コンテンツ

まず最初に docker-compose.yml という名前のファイルを作成し、立ち上げるDockerコンテナの情報を記述します。

version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:
      - "8000:80"
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html

まず、Nginxのコンテナのサービス名はwebとします。一つの下の階層では、コンテナのオプションを指定していきます。
以下、各オプションの説明を簡単にしていきます。

image には、公式で配布されているnginxを指定します。(Docker Hubというところでレポジトリとして配布されています。興味のある方はこちらから)後ろに続く:1.15.6というのはdockerイメージのタグで、バージョンを表しています。

ports にはホスト側からDockerコンテナ側へのポートフォワーディングを指定します。 ホスト側のポート:コンテナ側のポートという形式で記述します。httpのデフォルトポートが80番なのでDockerコンテナ側の80番に対して任意のポート(今回の場合は8000)を指定してあげると、ホスト側からコンテナ側にそのポートでアクセスできるようになります。

volumes では、Dockerコンテナに共有(マウントと言います)したいファイル群を指定します。この仕組みを使うことにより、ホスト側で編集したソースコードや設定ファイルがdockerコンテナに反映され実行されます。ホスト側のパス:コンテナ側のパス という形式で記述します。

次にNginxの設定ファイルを記述します。(docker/web/default.conf)

server {
    listen 80;

    root  /var/www/html;
    index index.html;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;
}

ここでは、必要最低限のNginxの設定をしていますが、細かい設定をしたい場合は、Nginx設定のまとめをご覧ください。

この設定内では、Nginxが待ち受けるポートをhttpデフォルトの80番に設定し、サーバのルートディレクトリを var/www/htmlに設定しました。

次にindex.htmlを作成します。とりあえず、動作ができていることが確認できればいいので以下のようにします。

<h1>Hello Docker Compose!</h1>

<p>I love Laravel and Docker!</p>

この状態で、以下のコマンドを起動します。

docker-compose up -d

以下のように表示されるはずです。

Creating network "laravel-docker-workspace_default" with the default driver
Creating laravel-docker-workspace_web_1 ... done

http://localhost:8000にアクセスしましょう。以下のように表示されるはずです。

先ほどdocker-composeを記述した時にも説明しましたが、dockerコンテナ内のnginxをdefault.confで設定したように80番で待ち受けて、docker-compose内のportsにてホストマシンの8000番とマッピングしたので、http://localhost:8000でアクセス可能となったわけです。
これにて静的HTMLを配信するNginxサーバを立ち上げることができました!

PHPを動作させる

Nginxの構築の章 では、静的なhtmlを配信するNginxサーバを立ち上げました。本記事では、Laravelを動作させることが目標なので、PHPを入れます。

Nginx上でPHPを動作させるためにはPHP-FPM(FastCGI Process Manager)を使います。

詳しくは以下の記事を参考にしてください。
nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する

docker-compose.ymlファイルに以下の記述を追加します。

  app:
    image: php:7.2.12-fpm
    volumes:
      - .:/var/www/html

サービス名はappとします。また、Nginxの構築の章で作成したwebサービスを編集して、以下のようにします。

web:
    image: nginx:1.15.6
    ports:
      - "8000:80"
    depends_on: # 追加
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html

depends_onは依存関係を定義するオプションです。今回の場合、NginxがPHPを実行するため、NginxがPHPに依存していることを定義したわけです。依存関係を定義すると、docker-composeがそれに従ってDockerコンテナを起動するようになります。

次にNginxの設定ファイル(docker/web/default.conf)を編集して、PHPを実行できるようにします。

server {
    listen 80;

    root  /var/www/html;
    index index.php index.html index.htm;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass   app:9000;
          fastcgi_index  index.php;

          include        fastcgi_params;
          fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_param  PATH_INFO $fastcgi_path_info;
      }
}

PHP-FPMはデフォルトでポート9000番で起動するのでfastcgi_passではapp:9000と指定すれば、docker内で名前解決してくれます。

index.phpを先ほど作成したindex.htmlと同じ階層に作成して、例えば以下のようにします。

<h1>Hello Docker Compose!</h1>

<p>I love Laravel and Docker!</p>

<?php phpinfo();?>

この状態で再び以下のコマンドを実行します。

docker-compose up -d

以下のようなメッセージが出ると思います。

Pulling app (php:7.2.12-fpm)...
7.2.12-fpm: Pulling from library/php
a5a6f2f73cd8: Pulling fs layer
a5a6f2f73cd8: Downloading [>                                                  ]  228.5kB/22.49MBwnload complete
a5a6f2f73cd8: Pull complete
633e0d1cd2a3: Pull complete
fcdfdf7118ba: Pull complete
4e7dc76b1769: Pull complete
64114f4b77d1: Pull complete
8808058334c4: Pull complete
b3b498385302: Pull complete
42083dd7d95b: Pull complete
f7d76dec7f98: Pull complete
0160ecfb865a: Pull complete
6372b5a2a037: Pull complete
Digest: sha256:2eae146993b58a61fbe40b36547d644222cf9db5dd04b3fe9c01f10820459b80
Status: Downloaded newer image for php:7.2.12-fpm
Creating laravel-docker-workspace_app_1 ... done
Recreating laravel-docker-workspace_web_1 ... done

以下のように表示されれば成功です!

これでPHPを動作させることができました!

MySQLを立ち上げる

PHPを動作させる の章にてPHPを無事動作させられたので、お次はMySQLです。

docker-compose.yml のサービスに以下を追加しましょう。

services:
# 省略
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: sample
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:

大まかなオプションの構成は、NginxやPHPのDockerコンテナの記述と同じなのですが、environmentによって、MySQLの情報を定義している点と、volumesによって、mysqlのデータの永続化を行なっている点が今までと異なります。

次に PHPを動作させる の章にて定義したappサービスに以下を追加しましょう。

depends_on:
      - mysql

現在のdocker-compose.yml の構成は以下の通りです。

version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  app:
    image: php:7.2.12-fpm
    depends_on:
    - mysql
    volumes:
      - .:/var/www/html
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: sample
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:

一度以下のコマンドで立ち上げてみましょう。

docker-compose up -d
Recreating laravel-docker-workspace_mysql_1 ... done
Recreating laravel-docker-workspace_app_1   ... done
Recreating laravel-docker-workspace_web_1   ... done

PHPからMySQLにはまだ接続していませんが、Laravelをインストールした後設定します。とりあえずMySQLの設定は以上です。

Laravelをインストールする

それでは、いよいよLaravelのインストールです。Laravelのインストールには色々な方法がありますが、Composerを使ってインストールします。

PHPを動作させる の章にて作成したappサービスにはComposer等Laravelに必要なパッケージが入っていないので、Dockerイメージを自分で定義することにします。

まずは、docker/phpというディレクトリを作り、そこにDockerfileをおきます。内容は以下のようにします。

FROM php:7.2.12-fpm

# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim

RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql

WORKDIR /var/www/html

次にdocker-compose.yml内のappサービスを以下のように書き換えます。

app:
    build: ./docker/php #定義したDockerfileを元にイメージを作るように変更
    depends_on:
      - mysql
    volumes:
      - .:/var/www/html

この状態で以下のコマンドを実行しましょう。

docker-compose up -d

少し起動に時間がかかりますが、うまく立ち上がったら、以下のコマンドでDockerコンテナに入ります。

docker-compose exec app bash

この中ではComposerが使えるようになっているので、以下のコマンドを入力しましょう。my-laravel-appの部分はお好きなプロジェクト名を指定します。

composer create-project --prefer-dist laravel/laravel my-laravel-app

かなり待たされるので、コーヒーでもどうぞ☕

しばらくすると、ComposerによるLaravelプロジェクトの作成が終わり以下のようにLaravelプロジェクトのディレクトリが作成されているはずです。

リクエストのライフサイクル

こちらの記事に書いてあるように、Laravelのアプリケーションに対するリクエストは、全てpublic/index.phpファイルが入り口になります。Nginxの設定(docker/default.conf)のrootを書き換えて以下のようにします。

root  /var/www/html/my-laravel-app/public;

Nginxの設定を反映させるために以下のコマンドを実行しましょう。

docker-compose restart

お疲れ様でした!と言いたいところですが、MySQLの接続まで終わらせちゃいましょう!後もう少しです!

LaravelをMySQLと接続する

Laravel内のプロジェクトの .envファイルを編集してMySQLと接続します。

Laravel5.7では初期状態で以下のようになっています。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

これをMySQLを立ち上げる の章で設定したenvironmentの設定にあわせて変更します。

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=sample
DB_USERNAME=user
DB_PASSWORD=password

DB_HOSTは定義してないじゃないか!と思われるかもしれませんが、 docker-compose で定義したサービス名を指定すると接続できます。

docker-compose restart

して、コンテナ内に入りましょう。

docker-compose exec app bash

Laravelプロジェクトディレクトリに移動します。

cd my-laravel-app

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

php 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

マイグレーションに限らず、artisanコマンドを実行するときは、appコンテナに入って実行することができます。
以上でMySQLの接続は終わりです。

最後に

今度こそ、お疲れ様です。これにてDocker ComposeでLaravelを立ち上げることができました。慣れないと手順は多く感じられると思いますが、慣れるとモダンでアプリケーション要件にあった環境を瞬時に立ち上げられるようになるはずです。本記事が読者様のDockerの理解の助けになれば幸いです。またね~~♪(*^-^)ノ~~

Dockerの最近記事

  1. LaravelでMailHogを導入して快適にメール開発をしよう!【Docker】

  2. Laravel HorizonでQueue/Jobを眺める

  3. LaravelでRedisとSupervisorを導入してQueue/Jobを扱う【doc…

  4. Laravelの環境(Nginx+MySQL+PHP)をdocker-composeでイチ…

  5. Laravel開発環境をLaradockで構築【Docker入門】

関連記事

コメント

  1. この記事へのコメントはありません。

  1. 2019年 1月 15日