DockerでLaravelの環境を立ち上げる on Mac【6.x LTS対応】

Web開発Docker,nginx,Mac,PHP,Laravel,docker-compose

これからPHPのフレームワークを勉強したいという方におすすめのフレームワーク、Laravel

  • フルスタックフレームワークとして、PHPのWebシステム開発に必要な機能がほぼすべて含まれている
  • 機能豊富ながら、学習コストが低く、コードが書きやすい
  • 日本語ドキュメントが豊富
  • 現在のPHPフレームワークのトレンド
    以前はCakePHPがよく使われていましたが、2017年あたりから新規開発ならLaravelがトレンドです

この記事では、LaravelをDockerで立ち上げ+ユーザー登録やログイン・ログアウトができるまでをご紹介していきたいと思います。

こんな人におすすめ
  • これからLaravelを勉強するために、環境を立ち上げたい
  • Dockerで立ち上げてみたいが、Dockerを使ったことがない

Githubリポジトリ

Dockerコンテナを立ち上げる手前までの状態のものをGithubリポジトリに置いてあります。

準備

ターミナルの使用について

この記事では基本的にターミナルでの操作を記載していきますが、必要に応じてFinderやエディターを利用していただいて問題ありません。

ただ、ターミナルはWebエンジニアとしてやっていくためには必須です。
適宜コメントアウトを記載していますので、少しずつでもターミナルに慣れていくようにしましょう!

Dockerをインストールする

以下の記事の 1. Docker for Macをインストールする をやっていただければOKです。

Laravelをインストールするためのディレクトリを作成する

次にLaravelをインストールするためのディレクトリ(フォルダ)を作成していきます。

# ホームディレクトリへ移動
$ cd ~

# wwwディレクトリを作成し、wwwへ移動
$ mkdir www
$ cd www

# sampleディレクトリを作成し、wwwへ移動
$ mkdir sample
$ cd sample

# 現在いるディレクトリを確認
$ pwd
/Users/{ユーザー名}/www/sample

# dockerディレクトリとsrcディレクトリを作成
$ mkdir src
$ mkdir docker
$ mkdir docker/mysql
$ mkdir docker/mysql/conf.d
$ mkdir docker/mysql/data
$ mkdir docker/nginx
$ mkdir docker/php

ホームディレクトリ ~ は、/Users/{ユーザー名}ディレクトリのことを指しています。
つまり、最初にホームディレクトリである/Users/{ユーザー名}ディレクトリに移動し、そこから wwwsample と移動してきたので、現在いるディレクトリを確認した時には/Users/{ユーザー名}/www/sampleにいることになります。

ですので、現在のディレクトリ構成は以下の通りになっています。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/ ←今ここにいる
      ├ src/
      └ docker/
         ├ nginx/
         ├ php/
         └ mysql/
           ├ conf.d/
           └ data/

Dockerの設定

次にDockerでLaravelを立ち上げるために必要なファイルを作成していきます。

docker-compose.yml

今いるディレクトリ ~/www/sampledocker-compose.yml ファイルを作成します。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml  ←新しく作成
      ├ src/
      └ docker/
         ├ nginx/
         ├ php/
         └ mysql/
           ├ conf.d/
           └ data/

これはDockerの機能一つのである Docker Compose機能 を利用するための設定ファイルです。

Dockerは、コンテナと呼ばれる実行環境を起動することで、コンテナごとのアプリケーションを利用できます。
通常、コンテナはアプリケーションごとに独立しており、それをコンテナごとに起動したり設定したりするのですが、コンテナの数が増えてくると管理が煩雑になります。
また、それをチームメンバーで同じような環境を作ろうと思うともっと大変です。

そういったことを解決するため、コンテナをまとめて一括管理できる機能が Docker compose機能 です。
以下が、Docker compose機能を利用するための docker-compose.yml ファイルです。
今回は、nginx(Webサーバー)・PHP・MySQL(データベース)のコンテナを一括管理します。

docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx:1.17-alpine
    container_name: "sample_nginx"
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php-fpm
  php-fpm:
    build: ./docker/php
    image: "php-fpm:latest"
    container_name: "sample_php-fpm"
    volumes:
      - ./src:/var/www
    links:
      - db
    depends_on:
      - db
  db:
    image: mysql:8.0.18
    container_name: "sample_db"
    volumes:
      - ./docker/mysql/conf.d:/etc/mysql/conf.d
      - ./docker/mysql/data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: sample
      MYSQL_USER: sample
      MYSQL_PASSWORD: sample
      MYSQL_ROOT_PASSWORD: root
      TZ: "Asia/Tokyo"
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

PHP : Dockerfile

続いて、~/www/sample/docker/php ディレクトリにPHPのDockerfileを作成します。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml
      ├ src/
      └ docker/
         ├ nginx/
         ├ php/
         │ └ Dockerfile  ←新しく作成
         └ mysql/
           ├ conf.d/
           └ data/

Dockerfile は、Dockerイメージを作成するための設計図のようなものです。
今回、nginx(Webサーバー)やMySQL(データベース)は既存の各イメージを使ってコンテナを作成しますが、PHPについてはLaravelのインストールなども必要なので、Dockerfile からイメージを作成→コンテナを作成する流れになります。

Dockerfile

FROM php:7.3-fpm
COPY php.ini /usr/local/etc/php/

RUN apt-get update \
  && apt-get install -y zlib1g-dev libzip-dev mariadb-client vim \
  && docker-php-ext-install zip pdo_mysql

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1

ENV COMPOSER_HOME /composer

ENV PATH $PATH:/composer/vendor/bin

RUN composer global require "laravel/installer"

RUN curl -SL https://deb.nodesource.com/setup_14.x | bash
RUN apt-get install -y nodejs && \
  npm install -g npm@latest && \
  npm install -g @vue/cli

WORKDIR /var/www

PHP : php.ini

次に、先程とおなじ ~/www/sample/docker/php ディレクトリに php.ini ファイルを作成します。
php.ini は、PHPプログラムの全体的な動作や環境を設定するファイルです。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml
      ├ src/
      └ docker/
         ├ nginx/
         ├ php/
         │ ├ Dockerfile
         │ └ php.ini  ←新しく作成
         └ mysql/
           ├ conf.d/
           └ data/

この設定ファイルでは、タイムゾーン(使用する時間帯の地域)や使用する言語といった最低限の設定を行います。

php.ini

date.timezone = Asia/Tokyo

log_errors = On
error_log = /dev/stderr
display_errors = Off

mbstring.language = "Japanese"

nginx : default.conf

次はWebサーバーとなるnginxの設定ファイルである default.conf を作成します。
作成場所は ~/www/sample/docker/nginx です。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml
      ├ src/
      └ docker/
         ├ nginx/
         │ ├ default.conf  ←新しく作成
         ├ php/
         │ ├ Dockerfile
         │ └ php.ini
         └ mysql/
           ├ conf.d/
           └ data/

default.conf

server {
  listen 80;

  root  /var/www/public;
  index index.php;

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

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass   php-fpm:9000;
    fastcgi_index  index.php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
  }
}

ここではWebサーバーのドキュメントルートの指定やPHPを使用するための設定をしています。

MySQL : default_authentication.cnf

次にMySQLの設定ファイルを作成します。
8.0でデフォルトで設定されている認証プラグインから、以前の認証プラグインを使用するように設定します。
ファイルは ~/www/sample/docker/mysql へ作成します。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml
      ├ src/
      └ docker/
         ├ nginx/
         │ ├ default.conf
         ├ php/
         │ ├ Dockerfile
         │ └ php.ini
         └ mysql/
           ├ conf.d/
           │ └ default_authentication.cnf  ←新しく作成
           └ data/

default_authentication.cnf

[mysqld]
default_authentication_plugin = mysql_native_password

Dockerイメージをビルドする

ここまで作成できたら、今まで作ってきた docker-compose.yml をもとに、その他のファイルを利用してDokerイメージをビルドします。
Dockerイメージをビルドするコマンドは docker-compose build です。

# 現在いるディレクトリを確認
$ pwd
~/www/sample  # もし~/www/sample/にいない場合は cd ~/www/sample で移動する

# Dockerイメージをビルドする
$ docker-compose build
...

# 10分ほどかかりますが、最終的に以下のようなメッセージが出ればOKです
Successfully built facf845a1eb5
Successfully tagged php-fpm:latest

# ビルドされたDockerイメージを確認
$ docker image list
REPOSITORY       TAG              IMAGE ID          CREATED             SIZE
php-fpm          latest           facf845a1eb5      3 minutes ago       948MB
<none>           <none>           9def889c7d75      25 minutes ago      508MB
nginx            1.17-alpine      377c0837328f      5 days ago          19.7MB
php              7.3-fpm          c7bd03ed1e4c      13 days ago         398MB
mysql            8.0.18           ed1ffcb5eff3      2 months ago        456MB

もし Could not open input file: composer-setup.php というエラーがでた場合は、ファイルを開くために必要なハッシュ値(英数字の羅列)を変更する必要があります。


$ docker-compose build
...

# こんなエラーが出たら
 => ERROR [ 6/12] RUN php composer-setup.php                                                                                                             0.6s
------
 > [ 6/12] RUN php composer-setup.php:
#10 0.536 Could not open input file: composer-setup.php
------
executor failed running [/bin/sh -c php composer-setup.php]: exit code: 1
ERROR: Service 'php-fpm' failed to build : Build failed

ハッシュ値(英数字の羅列)を新しいものに書き換えて保存する

https://composer.github.io/pubkeys.html
php/Dockerfileにあるハッシュ値を、上記ページに記載されているハッシュ値に書き換える

# ~/www/sample/docker/php/Dockerfile

# 以下の 75689〜1c7d3 はハッシュ値
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

これでDockerイメージのビルドが完了しました。
この時点でPHPのイメージにLaravelがインストールされた状態になっています。

Dockerコンテナを起動する

続いて、先程ビルドしたDockerイメージを使ってDockerコンテナを一括で起動します。
Dockerコンテナを起動するコマンドは docker-compose up -d です。

$ docker-compose up -d
...

# 最終的に以下のようなメッセージが出ればOKです
Creating sample_db ... done
Creating sample_php-fpm ... done
Creating sample_nginx   ... done

# 起動したDockerコンテナを確認
$ docker-compose ps
     Name                   Command               State                 Ports              
-------------------------------------------------------------------------------------------
sample_db        docker-entrypoint.sh mysql ...   Up      0.0.0.0:3306->3306/tcp, 33060/tcp
sample_nginx     nginx -g daemon off;             Up      0.0.0.0:8080->80/tcp             
sample_php-fpm   docker-php-entrypoint php-fpm    Up      9000/tcp

上記のStateが全てUpになっていれば、無事nginx, php, mysqlが起動できています。

Laravelの設定

プロジェクトを作成する

次に起動できたPHPのコンテナでLaravelのプロジェクトを作成していきます。
そのためにコンテナ上でコマンド操作をしていく必要があります。
コンテナ上でコマンド操作をするためのコマンドは docker exec ... bash です。

# PHPのコンテナ上で操作できるようにする
$ docker exec -it sample_php-fpm bash

# Composerを使って、Laravelプロジェクトを作成する
root@4d34914f97c9:/var/www# composer create-project --prefer-dist "laravel/laravel=6.5.2" .
...

# 最終的に以下のようなメッセージが出ればOKです
Application key set successfully.

もし Project directory "/var/www/." is not empty. というエラーがでた場合は、今いるディレクトリに隠しファイルがある可能性があるので、それを確認して削除しましょう。


root@4d34914f97c9:/var/www# composer create-project --prefer-dist "laravel/laravel=6.5.2" .
Creating a "laravel/laravel=6.5.2" project at "./"

# こんなエラーが出たら
 [InvalidArgumentException]
  Project directory "/var/www/." is not empty.

# 現在のディレクトリ内の隠しファイルを含めた全てのファイルを表示する
root@4d34914f97c9:/var/www# ls -la
total 12
drwxr-xr-x 3 root root   96 Mar 10 15:47 .
drwxr-xr-x 1 root root 4096 Feb 26 11:59 ..
-rw-r--r-- 1 root root 6148 Mar  5 17:59 .DS_Store  # ← .(ドット)から始まるファイルが隠しファイル

# 隠しファイルを削除
root@4d34914f97c9:/var/www# rm -f .DS_Store

# 再度ディレクトリ内のファイルを表示し、隠しファイルがないことを確認
root@4d34914f97c9:/var/www# ls -la 
total 4
drwxr-xr-x 2 root root   64 Mar 10 15:48 .
drwxr-xr-x 1 root root 4096 Feb 26 11:59 ..

# 再度プロジェクト作成コマンドを実行
root@4d34914f97c9:/var/www# composer create-project --prefer-dist "laravel/laravel=6.5.2" .
...

Application key set successfully.

# Dockerコンテナ上での操作を終了する
root@4d34914f97c9:/var/www# exit
exit
$ 

プロジェクト作成が完了すると、~/www/sample/src の中にLaravelのプロジェクトファイルが作成されます。

Users/
└ {ユーザー名}/
  └ www/
    └ sample/
      ├ docker-compose.yml
      ├ src/  ↓新しく作成されている
      │ ├ app/
      │ ├ bootstrap/
      │ ├ ...
      │
      └ docker/
         ├ nginx/
         │ ├ default.conf
         ├ php/
         │ ├ Dockerfile
         │ └ php.ini
         └ mysql/
           ├ conf.d/
           │ └ default_authentication.cnf
           └ data/

最後にGoogle ChromeやSafariなどのブラウザで http://localhost:8080/ へアクセスし、Laravelの初期画面が表示されればLaravelのインストールは完了です。

Laravel 初期画面

.env

次にデータベースに関する設定が書かれている .env ファイルを変更します。
変更する内容は、docker-compose.yml で設定した内容です。

...

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=sample
DB_USERNAME=sample
DB_PASSWORD=sample

...

package.json

javascriptライブラリを管理するnpmでインストールする sass-loder のバージョンを7系に指定します。
(2020.03.13時点で、8だとトランスパイルができない)

{
    ...
        "sass-loader": "^7.0.0"
    ...
}

認証機能を作る

変更が完了できたら認証機能を作っていきます。
といっても、コマンドをポチポチしていくだけで作ってくれます、便利!

# 再度、PHPのDockerコンテナを操作します
$ docker exec -it sample_php-fpm bash

# Composerでlaravel/uiをインストール。2020.03.13時点でver2.0が対応していない
root@4d34914f97c9:/var/www# composer require laravel/ui "^1.0"
...
  - Installing laravel/ui (v1.2.0): Downloading (100%) 
...

Package manifest generated successfully.
14 packages you are using are looking for funding.
Use the composer fund command to find out more!

# 認証機能をインストール
root@4d34914f97c9:/var/www# php artisan ui vue --auth
Vue scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
Authentication scaffolding generated successfully.

# javascriptパッケージのインストールとコンパイル
root@4d34914f97c9:/var/www# npm install && npm run dev
...

DONE  Compiled successfully in 9512ms                                                                                                                                              7:39:09 AM

       Asset     Size   Chunks             Chunk Names
/css/app.css  0 bytes  /js/app  [emitted]  /js/app
  /js/app.js  592 KiB  /js/app  [emitted]  /js/app

# データベースのテーブルを作成
root@4d34914f97c9:/var/www# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.08 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

# Dockerコンテナ上での操作を終了する
root@4d34914f97c9:/var/www# exit
exit

動作確認

ここまでやって http://localhost:8080/ のページを更新すると、右上にLOGINとREGISTERが増えています。

REGISTERをクリックして、ユーザー登録をしてみましょう。

Regiterボタンを押して、以下のように You are logged in! を表示されれば、無事ユーザー登録が完了し、ログインされた状態となります。

右上の名前のところからログアウトできます。
ログアウト後、右上のLOGINページから先程登録したユーザーでログインできるかも試してみましょう。


以上になります。

昔に比べると随分とかんたんに開発環境が構築できるようになりました。
もし不明点があればTwitterにてご連絡ください。